]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Add missing KERN_* prefix to printk
[mirror_ubuntu-bionic-kernel.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,
7cf51e48
JW
81#ifdef CONFIG_SND_DEBUG
82 ALC260_TEST,
83#endif
df694daa 84 ALC260_AUTO,
16ded525 85 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
86};
87
df694daa
KY
88/* ALC262 models */
89enum {
90 ALC262_BASIC,
ccc656ce
KY
91 ALC262_HIPPO,
92 ALC262_HIPPO_1,
834be88d 93 ALC262_FUJITSU,
9c7f852e 94 ALC262_HP_BPC,
cd7509a4
KY
95 ALC262_HP_BPC_D7000_WL,
96 ALC262_HP_BPC_D7000_WF,
66d2a9d6 97 ALC262_HP_TC_T5735,
8c427226 98 ALC262_HP_RP5700,
304dcaac 99 ALC262_BENQ_ED8,
272a527c 100 ALC262_SONY_ASSAMD,
83c34218 101 ALC262_BENQ_T31,
f651b50b 102 ALC262_ULTRA,
0e31daf7 103 ALC262_LENOVO_3000,
e8f9ae2a 104 ALC262_NEC,
4e555fe5 105 ALC262_TOSHIBA_S06,
9f99a638 106 ALC262_TOSHIBA_RX1,
ba340e82 107 ALC262_TYAN,
df694daa
KY
108 ALC262_AUTO,
109 ALC262_MODEL_LAST /* last tag */
110};
111
a361d84b
KY
112/* ALC268 models */
113enum {
eb5a6621 114 ALC267_QUANTA_IL1,
a361d84b 115 ALC268_3ST,
d1a991a6 116 ALC268_TOSHIBA,
d273809e 117 ALC268_ACER,
c238b4f4 118 ALC268_ACER_DMIC,
8ef355da 119 ALC268_ACER_ASPIRE_ONE,
3866f0b0 120 ALC268_DELL,
f12462c5 121 ALC268_ZEPTO,
86c53bd2
JW
122#ifdef CONFIG_SND_DEBUG
123 ALC268_TEST,
124#endif
a361d84b
KY
125 ALC268_AUTO,
126 ALC268_MODEL_LAST /* last tag */
127};
128
f6a92248
KY
129/* ALC269 models */
130enum {
131 ALC269_BASIC,
60db6b53 132 ALC269_QUANTA_FL1,
f53281e6
KY
133 ALC269_ASUS_EEEPC_P703,
134 ALC269_ASUS_EEEPC_P901,
26f5df26 135 ALC269_FUJITSU,
64154835 136 ALC269_LIFEBOOK,
f6a92248
KY
137 ALC269_AUTO,
138 ALC269_MODEL_LAST /* last tag */
139};
140
df694daa
KY
141/* ALC861 models */
142enum {
143 ALC861_3ST,
9c7f852e 144 ALC660_3ST,
df694daa
KY
145 ALC861_3ST_DIG,
146 ALC861_6ST_DIG,
22309c3e 147 ALC861_UNIWILL_M31,
a53d1aec 148 ALC861_TOSHIBA,
7cdbff94 149 ALC861_ASUS,
56bb0cab 150 ALC861_ASUS_LAPTOP,
df694daa
KY
151 ALC861_AUTO,
152 ALC861_MODEL_LAST,
153};
154
f32610ed
JS
155/* ALC861-VD models */
156enum {
157 ALC660VD_3ST,
6963f84c 158 ALC660VD_3ST_DIG,
13c94744 159 ALC660VD_ASUS_V1S,
f32610ed
JS
160 ALC861VD_3ST,
161 ALC861VD_3ST_DIG,
162 ALC861VD_6ST_DIG,
bdd148a3 163 ALC861VD_LENOVO,
272a527c 164 ALC861VD_DALLAS,
d1a991a6 165 ALC861VD_HP,
f32610ed
JS
166 ALC861VD_AUTO,
167 ALC861VD_MODEL_LAST,
168};
169
bc9f98a9
KY
170/* ALC662 models */
171enum {
172 ALC662_3ST_2ch_DIG,
173 ALC662_3ST_6ch_DIG,
174 ALC662_3ST_6ch,
175 ALC662_5ST_DIG,
176 ALC662_LENOVO_101E,
291702f0 177 ALC662_ASUS_EEEPC_P701,
8c427226 178 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
179 ALC663_ASUS_M51VA,
180 ALC663_ASUS_G71V,
181 ALC663_ASUS_H13,
182 ALC663_ASUS_G50V,
f1d4e28b
KY
183 ALC662_ECS,
184 ALC663_ASUS_MODE1,
185 ALC662_ASUS_MODE2,
186 ALC663_ASUS_MODE3,
187 ALC663_ASUS_MODE4,
188 ALC663_ASUS_MODE5,
189 ALC663_ASUS_MODE6,
bc9f98a9
KY
190 ALC662_AUTO,
191 ALC662_MODEL_LAST,
192};
193
df694daa
KY
194/* ALC882 models */
195enum {
196 ALC882_3ST_DIG,
197 ALC882_6ST_DIG,
4b146cb0 198 ALC882_ARIMA,
bdd148a3 199 ALC882_W2JC,
272a527c
KY
200 ALC882_TARGA,
201 ALC882_ASUS_A7J,
914759b7 202 ALC882_ASUS_A7M,
9102cd1c 203 ALC885_MACPRO,
87350ad0 204 ALC885_MBP3,
c54728d8 205 ALC885_IMAC24,
272a527c 206 ALC882_AUTO,
df694daa
KY
207 ALC882_MODEL_LAST,
208};
209
9c7f852e
TI
210/* ALC883 models */
211enum {
212 ALC883_3ST_2ch_DIG,
213 ALC883_3ST_6ch_DIG,
214 ALC883_3ST_6ch,
215 ALC883_6ST_DIG,
ccc656ce
KY
216 ALC883_TARGA_DIG,
217 ALC883_TARGA_2ch_DIG,
bab282b9 218 ALC883_ACER,
2880a867 219 ALC883_ACER_ASPIRE,
5b2d1eca 220 ALC888_ACER_ASPIRE_4930G,
c07584c8 221 ALC883_MEDION,
ea1fb29a 222 ALC883_MEDION_MD2,
b373bdeb 223 ALC883_LAPTOP_EAPD,
bc9f98a9 224 ALC883_LENOVO_101E_2ch,
272a527c 225 ALC883_LENOVO_NB0763,
189609ae 226 ALC888_LENOVO_MS7195_DIG,
e2757d5e 227 ALC888_LENOVO_SKY,
ea1fb29a 228 ALC883_HAIER_W66,
4723c022 229 ALC888_3ST_HP,
5795b9e6 230 ALC888_6ST_DELL,
a8848bd6 231 ALC883_MITAC,
0c4cc443 232 ALC883_CLEVO_M720,
fb97dc67 233 ALC883_FUJITSU_PI2515,
ef8ef5fb 234 ALC888_FUJITSU_XA3530,
17bba1b7 235 ALC883_3ST_6ch_INTEL,
e2757d5e
KY
236 ALC888_ASUS_M90V,
237 ALC888_ASUS_EEE1601,
3ab90935 238 ALC1200_ASUS_P5Q,
9c7f852e
TI
239 ALC883_AUTO,
240 ALC883_MODEL_LAST,
241};
242
61b9b9b1
HRK
243/* styles of capture selection */
244enum {
245 CAPT_MUX = 0, /* only mux based */
246 CAPT_MIX, /* only mixer based */
247 CAPT_1MUX_MIX, /* first mux and other mixers */
248};
249
df694daa
KY
250/* for GPIO Poll */
251#define GPIO_MASK 0x03
252
1da177e4
LT
253struct alc_spec {
254 /* codec parameterization */
df694daa 255 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 256 unsigned int num_mixers;
f9e336f6 257 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
1da177e4 258
df694daa 259 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
260 * don't forget NULL
261 * termination!
e9edcee0
TI
262 */
263 unsigned int num_init_verbs;
1da177e4 264
16ded525 265 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
266 struct hda_pcm_stream *stream_analog_playback;
267 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
268 struct hda_pcm_stream *stream_analog_alt_playback;
269 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 270
f12ab1e0 271 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
272 struct hda_pcm_stream *stream_digital_playback;
273 struct hda_pcm_stream *stream_digital_capture;
274
275 /* playback */
16ded525
TI
276 struct hda_multi_out multiout; /* playback set-up
277 * max_channels, dacs must be set
278 * dig_out_nid and hp_nid are optional
279 */
6330079f 280 hda_nid_t alt_dac_nid;
8c441982 281 int dig_out_type;
1da177e4
LT
282
283 /* capture */
284 unsigned int num_adc_nids;
285 hda_nid_t *adc_nids;
e1406348 286 hda_nid_t *capsrc_nids;
16ded525 287 hda_nid_t dig_in_nid; /* digital-in NID; optional */
61b9b9b1 288 int capture_style; /* capture style (CAPT_*) */
1da177e4
LT
289
290 /* capture source */
a1e8d2da 291 unsigned int num_mux_defs;
1da177e4
LT
292 const struct hda_input_mux *input_mux;
293 unsigned int cur_mux[3];
294
295 /* channel model */
d2a6d7dc 296 const struct hda_channel_mode *channel_mode;
1da177e4 297 int num_channel_mode;
4e195a7b 298 int need_dac_fix;
1da177e4
LT
299
300 /* PCM information */
4c5186ed 301 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 302
e9edcee0
TI
303 /* dynamic controls, init_verbs and input_mux */
304 struct auto_pin_cfg autocfg;
603c4019 305 struct snd_array kctls;
61b9b9b1 306 struct hda_input_mux private_imux[3];
41923e44 307 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 308
ae6b813a
TI
309 /* hooks */
310 void (*init_hook)(struct hda_codec *codec);
311 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
312
834be88d
TI
313 /* for pin sensing */
314 unsigned int sense_updated: 1;
315 unsigned int jack_present: 1;
bec15c3a 316 unsigned int master_sw: 1;
cb53c626 317
e64f14f4
TI
318 /* other flags */
319 unsigned int no_analog :1; /* digital I/O only */
320
2134ea4f
TI
321 /* for virtual master */
322 hda_nid_t vmaster_nid;
cb53c626
TI
323#ifdef CONFIG_SND_HDA_POWER_SAVE
324 struct hda_loopback_check loopback;
325#endif
2c3bf9ab
TI
326
327 /* for PLL fix */
328 hda_nid_t pll_nid;
329 unsigned int pll_coef_idx, pll_coef_bit;
e044c39a
TI
330
331#ifdef SND_HDA_NEEDS_RESUME
332#define ALC_MAX_PINS 16
333 unsigned int num_pins;
334 hda_nid_t pin_nids[ALC_MAX_PINS];
335 unsigned int pin_cfgs[ALC_MAX_PINS];
336#endif
df694daa
KY
337};
338
339/*
340 * configuration template - to be copied to the spec instance
341 */
342struct alc_config_preset {
9c7f852e
TI
343 struct snd_kcontrol_new *mixers[5]; /* should be identical size
344 * with spec
345 */
f9e336f6 346 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
347 const struct hda_verb *init_verbs[5];
348 unsigned int num_dacs;
349 hda_nid_t *dac_nids;
350 hda_nid_t dig_out_nid; /* optional */
351 hda_nid_t hp_nid; /* optional */
352 unsigned int num_adc_nids;
353 hda_nid_t *adc_nids;
e1406348 354 hda_nid_t *capsrc_nids;
df694daa
KY
355 hda_nid_t dig_in_nid;
356 unsigned int num_channel_mode;
357 const struct hda_channel_mode *channel_mode;
4e195a7b 358 int need_dac_fix;
a1e8d2da 359 unsigned int num_mux_defs;
df694daa 360 const struct hda_input_mux *input_mux;
ae6b813a
TI
361 void (*unsol_event)(struct hda_codec *, unsigned int);
362 void (*init_hook)(struct hda_codec *);
cb53c626
TI
363#ifdef CONFIG_SND_HDA_POWER_SAVE
364 struct hda_amp_list *loopbacks;
365#endif
1da177e4
LT
366};
367
1da177e4
LT
368
369/*
370 * input MUX handling
371 */
9c7f852e
TI
372static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
374{
375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
376 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
377 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
378 if (mux_idx >= spec->num_mux_defs)
379 mux_idx = 0;
380 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
381}
382
9c7f852e
TI
383static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
384 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
385{
386 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
387 struct alc_spec *spec = codec->spec;
388 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
389
390 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
391 return 0;
392}
393
9c7f852e
TI
394static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
396{
397 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
398 struct alc_spec *spec = codec->spec;
cd896c33 399 const struct hda_input_mux *imux;
1da177e4 400 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 401 unsigned int mux_idx;
e1406348
TI
402 hda_nid_t nid = spec->capsrc_nids ?
403 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4 404
cd896c33
TI
405 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
406 imux = &spec->input_mux[mux_idx];
407
61b9b9b1
HRK
408 if (spec->capture_style &&
409 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
54cbc9ab
TI
410 /* Matrix-mixer style (e.g. ALC882) */
411 unsigned int *cur_val = &spec->cur_mux[adc_idx];
412 unsigned int i, idx;
413
414 idx = ucontrol->value.enumerated.item[0];
415 if (idx >= imux->num_items)
416 idx = imux->num_items - 1;
417 if (*cur_val == idx)
418 return 0;
419 for (i = 0; i < imux->num_items; i++) {
420 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
421 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
422 imux->items[i].index,
423 HDA_AMP_MUTE, v);
424 }
425 *cur_val = idx;
426 return 1;
427 } else {
428 /* MUX style (e.g. ALC880) */
cd896c33 429 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
430 &spec->cur_mux[adc_idx]);
431 }
432}
e9edcee0 433
1da177e4
LT
434/*
435 * channel mode setting
436 */
9c7f852e
TI
437static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
439{
440 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
441 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
442 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
443 spec->num_channel_mode);
1da177e4
LT
444}
445
9c7f852e
TI
446static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
447 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
448{
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 struct alc_spec *spec = codec->spec;
d2a6d7dc 451 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
452 spec->num_channel_mode,
453 spec->multiout.max_channels);
1da177e4
LT
454}
455
9c7f852e
TI
456static int alc_ch_mode_put(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;
4e195a7b
TI
461 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
462 spec->num_channel_mode,
463 &spec->multiout.max_channels);
bd2033f2 464 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
465 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
466 return err;
1da177e4
LT
467}
468
a9430dd8 469/*
4c5186ed 470 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 471 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
472 * being part of a format specifier. Maximum allowed length of a value is
473 * 63 characters plus NULL terminator.
7cf51e48
JW
474 *
475 * Note: some retasking pin complexes seem to ignore requests for input
476 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
477 * are requested. Therefore order this list so that this behaviour will not
478 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
479 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
480 * March 2006.
4c5186ed
JW
481 */
482static char *alc_pin_mode_names[] = {
7cf51e48
JW
483 "Mic 50pc bias", "Mic 80pc bias",
484 "Line in", "Line out", "Headphone out",
4c5186ed
JW
485};
486static unsigned char alc_pin_mode_values[] = {
7cf51e48 487 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
488};
489/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
490 * in the pin being assumed to be exclusively an input or an output pin. In
491 * addition, "input" pins may or may not process the mic bias option
492 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
493 * accept requests for bias as of chip versions up to March 2006) and/or
494 * wiring in the computer.
a9430dd8 495 */
a1e8d2da
JW
496#define ALC_PIN_DIR_IN 0x00
497#define ALC_PIN_DIR_OUT 0x01
498#define ALC_PIN_DIR_INOUT 0x02
499#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
500#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 501
ea1fb29a 502/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
503 * For each direction the minimum and maximum values are given.
504 */
a1e8d2da 505static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
506 { 0, 2 }, /* ALC_PIN_DIR_IN */
507 { 3, 4 }, /* ALC_PIN_DIR_OUT */
508 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
509 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
510 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
511};
512#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
513#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
514#define alc_pin_mode_n_items(_dir) \
515 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
516
9c7f852e
TI
517static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
518 struct snd_ctl_elem_info *uinfo)
a9430dd8 519{
4c5186ed
JW
520 unsigned int item_num = uinfo->value.enumerated.item;
521 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
522
523 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 524 uinfo->count = 1;
4c5186ed
JW
525 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
526
527 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
528 item_num = alc_pin_mode_min(dir);
529 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
530 return 0;
531}
532
9c7f852e
TI
533static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
534 struct snd_ctl_elem_value *ucontrol)
a9430dd8 535{
4c5186ed 536 unsigned int i;
a9430dd8
JW
537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
538 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 539 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 540 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
541 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
542 AC_VERB_GET_PIN_WIDGET_CONTROL,
543 0x00);
a9430dd8 544
4c5186ed
JW
545 /* Find enumerated value for current pinctl setting */
546 i = alc_pin_mode_min(dir);
9c7f852e 547 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 548 i++;
9c7f852e 549 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
550 return 0;
551}
552
9c7f852e
TI
553static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
554 struct snd_ctl_elem_value *ucontrol)
a9430dd8 555{
4c5186ed 556 signed int change;
a9430dd8
JW
557 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
558 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
559 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
560 long val = *ucontrol->value.integer.value;
9c7f852e
TI
561 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
562 AC_VERB_GET_PIN_WIDGET_CONTROL,
563 0x00);
a9430dd8 564
f12ab1e0 565 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
566 val = alc_pin_mode_min(dir);
567
568 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
569 if (change) {
570 /* Set pin mode to that requested */
82beb8fd
TI
571 snd_hda_codec_write_cache(codec, nid, 0,
572 AC_VERB_SET_PIN_WIDGET_CONTROL,
573 alc_pin_mode_values[val]);
cdcd9268 574
ea1fb29a 575 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
576 * for the requested pin mode. Enum values of 2 or less are
577 * input modes.
578 *
579 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
580 * reduces noise slightly (particularly on input) so we'll
581 * do it. However, having both input and output buffers
582 * enabled simultaneously doesn't seem to be problematic if
583 * this turns out to be necessary in the future.
cdcd9268
JW
584 */
585 if (val <= 2) {
47fd830a
TI
586 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
587 HDA_AMP_MUTE, HDA_AMP_MUTE);
588 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
589 HDA_AMP_MUTE, 0);
cdcd9268 590 } else {
47fd830a
TI
591 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
592 HDA_AMP_MUTE, HDA_AMP_MUTE);
593 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
594 HDA_AMP_MUTE, 0);
cdcd9268
JW
595 }
596 }
a9430dd8
JW
597 return change;
598}
599
4c5186ed 600#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 601 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
602 .info = alc_pin_mode_info, \
603 .get = alc_pin_mode_get, \
604 .put = alc_pin_mode_put, \
605 .private_value = nid | (dir<<16) }
df694daa 606
5c8f858d
JW
607/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
608 * together using a mask with more than one bit set. This control is
609 * currently used only by the ALC260 test model. At this stage they are not
610 * needed for any "production" models.
611 */
612#ifdef CONFIG_SND_DEBUG
a5ce8890 613#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 614
9c7f852e
TI
615static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
616 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
617{
618 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
619 hda_nid_t nid = kcontrol->private_value & 0xffff;
620 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
621 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
622 unsigned int val = snd_hda_codec_read(codec, nid, 0,
623 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
624
625 *valp = (val & mask) != 0;
626 return 0;
627}
9c7f852e
TI
628static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
629 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
630{
631 signed int change;
632 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
633 hda_nid_t nid = kcontrol->private_value & 0xffff;
634 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
635 long val = *ucontrol->value.integer.value;
9c7f852e
TI
636 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
637 AC_VERB_GET_GPIO_DATA,
638 0x00);
5c8f858d
JW
639
640 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
641 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
642 if (val == 0)
5c8f858d
JW
643 gpio_data &= ~mask;
644 else
645 gpio_data |= mask;
82beb8fd
TI
646 snd_hda_codec_write_cache(codec, nid, 0,
647 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
648
649 return change;
650}
651#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
652 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
653 .info = alc_gpio_data_info, \
654 .get = alc_gpio_data_get, \
655 .put = alc_gpio_data_put, \
656 .private_value = nid | (mask<<16) }
657#endif /* CONFIG_SND_DEBUG */
658
92621f13
JW
659/* A switch control to allow the enabling of the digital IO pins on the
660 * ALC260. This is incredibly simplistic; the intention of this control is
661 * to provide something in the test model allowing digital outputs to be
662 * identified if present. If models are found which can utilise these
663 * outputs a more complete mixer control can be devised for those models if
664 * necessary.
665 */
666#ifdef CONFIG_SND_DEBUG
a5ce8890 667#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 668
9c7f852e
TI
669static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
670 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
671{
672 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
673 hda_nid_t nid = kcontrol->private_value & 0xffff;
674 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
675 long *valp = ucontrol->value.integer.value;
9c7f852e 676 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 677 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
678
679 *valp = (val & mask) != 0;
680 return 0;
681}
9c7f852e
TI
682static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
683 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
684{
685 signed int change;
686 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
687 hda_nid_t nid = kcontrol->private_value & 0xffff;
688 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
689 long val = *ucontrol->value.integer.value;
9c7f852e 690 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 691 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 692 0x00);
92621f13
JW
693
694 /* Set/unset the masked control bit(s) as needed */
9c7f852e 695 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
696 if (val==0)
697 ctrl_data &= ~mask;
698 else
699 ctrl_data |= mask;
82beb8fd
TI
700 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
701 ctrl_data);
92621f13
JW
702
703 return change;
704}
705#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
706 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
707 .info = alc_spdif_ctrl_info, \
708 .get = alc_spdif_ctrl_get, \
709 .put = alc_spdif_ctrl_put, \
710 .private_value = nid | (mask<<16) }
711#endif /* CONFIG_SND_DEBUG */
712
f8225f6d
JW
713/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
714 * Again, this is only used in the ALC26x test models to help identify when
715 * the EAPD line must be asserted for features to work.
716 */
717#ifdef CONFIG_SND_DEBUG
718#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
719
720static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
721 struct snd_ctl_elem_value *ucontrol)
722{
723 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
724 hda_nid_t nid = kcontrol->private_value & 0xffff;
725 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
726 long *valp = ucontrol->value.integer.value;
727 unsigned int val = snd_hda_codec_read(codec, nid, 0,
728 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
729
730 *valp = (val & mask) != 0;
731 return 0;
732}
733
734static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
735 struct snd_ctl_elem_value *ucontrol)
736{
737 int change;
738 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
739 hda_nid_t nid = kcontrol->private_value & 0xffff;
740 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
741 long val = *ucontrol->value.integer.value;
742 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
743 AC_VERB_GET_EAPD_BTLENABLE,
744 0x00);
745
746 /* Set/unset the masked control bit(s) as needed */
747 change = (!val ? 0 : mask) != (ctrl_data & mask);
748 if (!val)
749 ctrl_data &= ~mask;
750 else
751 ctrl_data |= mask;
752 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
753 ctrl_data);
754
755 return change;
756}
757
758#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
759 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
760 .info = alc_eapd_ctrl_info, \
761 .get = alc_eapd_ctrl_get, \
762 .put = alc_eapd_ctrl_put, \
763 .private_value = nid | (mask<<16) }
764#endif /* CONFIG_SND_DEBUG */
765
d88897ea
TI
766/*
767 */
768static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
769{
770 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
771 return;
772 spec->mixers[spec->num_mixers++] = mix;
773}
774
775static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
776{
777 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
778 return;
779 spec->init_verbs[spec->num_init_verbs++] = verb;
780}
781
daead538
TI
782#ifdef CONFIG_PROC_FS
783/*
784 * hook for proc
785 */
786static void print_realtek_coef(struct snd_info_buffer *buffer,
787 struct hda_codec *codec, hda_nid_t nid)
788{
789 int coeff;
790
791 if (nid != 0x20)
792 return;
793 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
794 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
795 coeff = snd_hda_codec_read(codec, nid, 0,
796 AC_VERB_GET_COEF_INDEX, 0);
797 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
798}
799#else
800#define print_realtek_coef NULL
801#endif
802
df694daa
KY
803/*
804 * set up from the preset table
805 */
9c7f852e
TI
806static void setup_preset(struct alc_spec *spec,
807 const struct alc_config_preset *preset)
df694daa
KY
808{
809 int i;
810
811 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 812 add_mixer(spec, preset->mixers[i]);
f9e336f6 813 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
814 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
815 i++)
d88897ea 816 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 817
df694daa
KY
818 spec->channel_mode = preset->channel_mode;
819 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 820 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
821
822 spec->multiout.max_channels = spec->channel_mode[0].channels;
823
824 spec->multiout.num_dacs = preset->num_dacs;
825 spec->multiout.dac_nids = preset->dac_nids;
826 spec->multiout.dig_out_nid = preset->dig_out_nid;
827 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 828
a1e8d2da 829 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 830 if (!spec->num_mux_defs)
a1e8d2da 831 spec->num_mux_defs = 1;
df694daa
KY
832 spec->input_mux = preset->input_mux;
833
834 spec->num_adc_nids = preset->num_adc_nids;
835 spec->adc_nids = preset->adc_nids;
e1406348 836 spec->capsrc_nids = preset->capsrc_nids;
df694daa 837 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
838
839 spec->unsol_event = preset->unsol_event;
840 spec->init_hook = preset->init_hook;
cb53c626
TI
841#ifdef CONFIG_SND_HDA_POWER_SAVE
842 spec->loopback.amplist = preset->loopbacks;
843#endif
df694daa
KY
844}
845
bc9f98a9
KY
846/* Enable GPIO mask and set output */
847static struct hda_verb alc_gpio1_init_verbs[] = {
848 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
849 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
850 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
851 { }
852};
853
854static struct hda_verb alc_gpio2_init_verbs[] = {
855 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
856 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
857 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
858 { }
859};
860
bdd148a3
KY
861static struct hda_verb alc_gpio3_init_verbs[] = {
862 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
863 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
864 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
865 { }
866};
867
2c3bf9ab
TI
868/*
869 * Fix hardware PLL issue
870 * On some codecs, the analog PLL gating control must be off while
871 * the default value is 1.
872 */
873static void alc_fix_pll(struct hda_codec *codec)
874{
875 struct alc_spec *spec = codec->spec;
876 unsigned int val;
877
878 if (!spec->pll_nid)
879 return;
880 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
881 spec->pll_coef_idx);
882 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
883 AC_VERB_GET_PROC_COEF, 0);
884 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
885 spec->pll_coef_idx);
886 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
887 val & ~(1 << spec->pll_coef_bit));
888}
889
890static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
891 unsigned int coef_idx, unsigned int coef_bit)
892{
893 struct alc_spec *spec = codec->spec;
894 spec->pll_nid = nid;
895 spec->pll_coef_idx = coef_idx;
896 spec->pll_coef_bit = coef_bit;
897 alc_fix_pll(codec);
898}
899
c9b58006
KY
900static void alc_sku_automute(struct hda_codec *codec)
901{
902 struct alc_spec *spec = codec->spec;
c9b58006
KY
903 unsigned int present;
904 unsigned int hp_nid = spec->autocfg.hp_pins[0];
905 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
906
907 /* need to execute and sync at first */
908 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
909 present = snd_hda_codec_read(codec, hp_nid, 0,
910 AC_VERB_GET_PIN_SENSE, 0);
911 spec->jack_present = (present & 0x80000000) != 0;
f6c7e546
TI
912 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
913 spec->jack_present ? 0 : PIN_OUT);
c9b58006
KY
914}
915
4605b718 916#if 0 /* it's broken in some acses -- temporarily disabled */
7fb0d78f
KY
917static void alc_mic_automute(struct hda_codec *codec)
918{
919 struct alc_spec *spec = codec->spec;
920 unsigned int present;
921 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
922 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
923 unsigned int mix_nid = spec->capsrc_nids[0];
924 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
925
926 capsrc_idx_mic = mic_nid - 0x18;
927 capsrc_idx_fmic = fmic_nid - 0x18;
928 present = snd_hda_codec_read(codec, mic_nid, 0,
929 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
930 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
931 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
932 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
933 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
934 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
935 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
936}
4605b718
TI
937#else
938#define alc_mic_automute(codec) /* NOP */
939#endif /* disabled */
7fb0d78f 940
c9b58006
KY
941/* unsolicited event for HP jack sensing */
942static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
943{
944 if (codec->vendor_id == 0x10ec0880)
945 res >>= 28;
946 else
947 res >>= 26;
7fb0d78f
KY
948 if (res == ALC880_HP_EVENT)
949 alc_sku_automute(codec);
c9b58006 950
7fb0d78f
KY
951 if (res == ALC880_MIC_EVENT)
952 alc_mic_automute(codec);
953}
954
955static void alc_inithook(struct hda_codec *codec)
956{
c9b58006 957 alc_sku_automute(codec);
7fb0d78f 958 alc_mic_automute(codec);
c9b58006
KY
959}
960
f9423e7a
KY
961/* additional initialization for ALC888 variants */
962static void alc888_coef_init(struct hda_codec *codec)
963{
964 unsigned int tmp;
965
966 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
967 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
968 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
969 if ((tmp & 0xf0) == 2)
970 /* alc888S-VC */
971 snd_hda_codec_read(codec, 0x20, 0,
972 AC_VERB_SET_PROC_COEF, 0x830);
973 else
974 /* alc888-VB */
975 snd_hda_codec_read(codec, 0x20, 0,
976 AC_VERB_SET_PROC_COEF, 0x3030);
977}
978
bc9f98a9
KY
979/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
980 * 31 ~ 16 : Manufacture ID
981 * 15 ~ 8 : SKU ID
982 * 7 ~ 0 : Assembly ID
983 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
984 */
985static void alc_subsystem_id(struct hda_codec *codec,
986 unsigned int porta, unsigned int porte,
987 unsigned int portd)
988{
c9b58006
KY
989 unsigned int ass, tmp, i;
990 unsigned nid;
991 struct alc_spec *spec = codec->spec;
bc9f98a9 992
c9b58006
KY
993 ass = codec->subsystem_id & 0xffff;
994 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
995 goto do_sku;
996
ea1fb29a 997 /*
c9b58006
KY
998 * 31~30 : port conetcivity
999 * 29~21 : reserve
1000 * 20 : PCBEEP input
1001 * 19~16 : Check sum (15:1)
1002 * 15~1 : Custom
1003 * 0 : override
1004 */
1005 nid = 0x1d;
1006 if (codec->vendor_id == 0x10ec0260)
1007 nid = 0x17;
1008 ass = snd_hda_codec_read(codec, nid, 0,
1009 AC_VERB_GET_CONFIG_DEFAULT, 0);
1010 if (!(ass & 1) && !(ass & 0x100000))
1011 return;
1012 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
1013 return;
1014
c9b58006
KY
1015 /* check sum */
1016 tmp = 0;
1017 for (i = 1; i < 16; i++) {
8c427226 1018 if ((ass >> i) & 1)
c9b58006
KY
1019 tmp++;
1020 }
1021 if (((ass >> 16) & 0xf) != tmp)
1022 return;
1023do_sku:
1024 /*
1025 * 0 : override
1026 * 1 : Swap Jack
1027 * 2 : 0 --> Desktop, 1 --> Laptop
1028 * 3~5 : External Amplifier control
1029 * 7~6 : Reserved
1030 */
bc9f98a9
KY
1031 tmp = (ass & 0x38) >> 3; /* external Amp control */
1032 switch (tmp) {
1033 case 1:
1034 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1035 break;
1036 case 3:
1037 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1038 break;
bdd148a3
KY
1039 case 7:
1040 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1041 break;
c9b58006 1042 case 5: /* set EAPD output high */
bdd148a3 1043 switch (codec->vendor_id) {
c9b58006
KY
1044 case 0x10ec0260:
1045 snd_hda_codec_write(codec, 0x0f, 0,
1046 AC_VERB_SET_EAPD_BTLENABLE, 2);
1047 snd_hda_codec_write(codec, 0x10, 0,
1048 AC_VERB_SET_EAPD_BTLENABLE, 2);
1049 break;
1050 case 0x10ec0262:
bdd148a3
KY
1051 case 0x10ec0267:
1052 case 0x10ec0268:
c9b58006 1053 case 0x10ec0269:
f9423e7a
KY
1054 case 0x10ec0660:
1055 case 0x10ec0662:
1056 case 0x10ec0663:
c9b58006 1057 case 0x10ec0862:
20a3a05d 1058 case 0x10ec0889:
bdd148a3
KY
1059 snd_hda_codec_write(codec, 0x14, 0,
1060 AC_VERB_SET_EAPD_BTLENABLE, 2);
1061 snd_hda_codec_write(codec, 0x15, 0,
1062 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 1063 break;
bdd148a3 1064 }
c9b58006
KY
1065 switch (codec->vendor_id) {
1066 case 0x10ec0260:
1067 snd_hda_codec_write(codec, 0x1a, 0,
1068 AC_VERB_SET_COEF_INDEX, 7);
1069 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1070 AC_VERB_GET_PROC_COEF, 0);
1071 snd_hda_codec_write(codec, 0x1a, 0,
1072 AC_VERB_SET_COEF_INDEX, 7);
1073 snd_hda_codec_write(codec, 0x1a, 0,
1074 AC_VERB_SET_PROC_COEF,
1075 tmp | 0x2010);
1076 break;
1077 case 0x10ec0262:
1078 case 0x10ec0880:
1079 case 0x10ec0882:
1080 case 0x10ec0883:
1081 case 0x10ec0885:
20a3a05d 1082 case 0x10ec0889:
c9b58006
KY
1083 snd_hda_codec_write(codec, 0x20, 0,
1084 AC_VERB_SET_COEF_INDEX, 7);
1085 tmp = snd_hda_codec_read(codec, 0x20, 0,
1086 AC_VERB_GET_PROC_COEF, 0);
1087 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1088 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1089 snd_hda_codec_write(codec, 0x20, 0,
1090 AC_VERB_SET_PROC_COEF,
1091 tmp | 0x2010);
1092 break;
f9423e7a 1093 case 0x10ec0888:
1082c748 1094 /*alc888_coef_init(codec);*/ /* called in alc_init() */
f9423e7a 1095 break;
c9b58006
KY
1096 case 0x10ec0267:
1097 case 0x10ec0268:
1098 snd_hda_codec_write(codec, 0x20, 0,
1099 AC_VERB_SET_COEF_INDEX, 7);
1100 tmp = snd_hda_codec_read(codec, 0x20, 0,
1101 AC_VERB_GET_PROC_COEF, 0);
1102 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1103 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1104 snd_hda_codec_write(codec, 0x20, 0,
1105 AC_VERB_SET_PROC_COEF,
1106 tmp | 0x3000);
1107 break;
bc9f98a9 1108 }
c9b58006 1109 default:
bc9f98a9
KY
1110 break;
1111 }
ea1fb29a 1112
8c427226 1113 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1114 * when the external headphone out jack is plugged"
1115 */
8c427226 1116 if (!(ass & 0x8000))
c9b58006
KY
1117 return;
1118 /*
1119 * 10~8 : Jack location
1120 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1121 * 14~13: Resvered
1122 * 15 : 1 --> enable the function "Mute internal speaker
1123 * when the external headphone out jack is plugged"
1124 */
1125 if (!spec->autocfg.speaker_pins[0]) {
8c427226 1126 if (spec->autocfg.line_out_pins[0])
c9b58006 1127 spec->autocfg.speaker_pins[0] =
8c427226 1128 spec->autocfg.line_out_pins[0];
c9b58006
KY
1129 else
1130 return;
1131 }
1132
1133 if (!spec->autocfg.hp_pins[0]) {
1134 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1135 if (tmp == 0)
1136 spec->autocfg.hp_pins[0] = porta;
1137 else if (tmp == 1)
1138 spec->autocfg.hp_pins[0] = porte;
1139 else if (tmp == 2)
1140 spec->autocfg.hp_pins[0] = portd;
1141 else
1142 return;
1143 }
7fb0d78f
KY
1144 if (spec->autocfg.hp_pins[0])
1145 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1146 AC_VERB_SET_UNSOLICITED_ENABLE,
1147 AC_USRSP_EN | ALC880_HP_EVENT);
c9b58006 1148
4605b718 1149#if 0 /* it's broken in some acses -- temporarily disabled */
7fb0d78f
KY
1150 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1151 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1152 snd_hda_codec_write(codec,
1153 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1154 AC_VERB_SET_UNSOLICITED_ENABLE,
1155 AC_USRSP_EN | ALC880_MIC_EVENT);
4605b718 1156#endif /* disabled */
ea1fb29a 1157
c9b58006 1158 spec->unsol_event = alc_sku_unsol_event;
bc9f98a9
KY
1159}
1160
f95474ec
TI
1161/*
1162 * Fix-up pin default configurations
1163 */
1164
1165struct alc_pincfg {
1166 hda_nid_t nid;
1167 u32 val;
1168};
1169
1170static void alc_fix_pincfg(struct hda_codec *codec,
1171 const struct snd_pci_quirk *quirk,
1172 const struct alc_pincfg **pinfix)
1173{
1174 const struct alc_pincfg *cfg;
1175
1176 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1177 if (!quirk)
1178 return;
1179
1180 cfg = pinfix[quirk->value];
1181 for (; cfg->nid; cfg++) {
1182 int i;
1183 u32 val = cfg->val;
1184 for (i = 0; i < 4; i++) {
1185 snd_hda_codec_write(codec, cfg->nid, 0,
1186 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1187 val & 0xff);
1188 val >>= 8;
1189 }
1190 }
1191}
1192
ef8ef5fb
VP
1193/*
1194 * ALC888
1195 */
1196
1197/*
1198 * 2ch mode
1199 */
1200static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1201/* Mic-in jack as mic in */
1202 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1203 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1204/* Line-in jack as Line in */
1205 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1206 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1207/* Line-Out as Front */
1208 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1209 { } /* end */
1210};
1211
1212/*
1213 * 4ch mode
1214 */
1215static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1216/* Mic-in jack as mic in */
1217 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1218 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1219/* Line-in jack as Surround */
1220 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1221 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1222/* Line-Out as Front */
1223 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1224 { } /* end */
1225};
1226
1227/*
1228 * 6ch mode
1229 */
1230static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1231/* Mic-in jack as CLFE */
1232 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1233 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1234/* Line-in jack as Surround */
1235 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1236 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1237/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1238 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1239 { } /* end */
1240};
1241
1242/*
1243 * 8ch mode
1244 */
1245static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1246/* Mic-in jack as CLFE */
1247 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1248 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1249/* Line-in jack as Surround */
1250 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1251 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1252/* Line-Out as Side */
1253 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1254 { } /* end */
1255};
1256
1257static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1258 { 2, alc888_4ST_ch2_intel_init },
1259 { 4, alc888_4ST_ch4_intel_init },
1260 { 6, alc888_4ST_ch6_intel_init },
1261 { 8, alc888_4ST_ch8_intel_init },
1262};
1263
1264/*
1265 * ALC888 Fujitsu Siemens Amillo xa3530
1266 */
1267
1268static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1269/* Front Mic: set to PIN_IN (empty by default) */
1270 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1271/* Connect Internal HP to Front */
1272 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1273 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1274 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1275/* Connect Bass HP to Front */
1276 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1277 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1278 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1279/* Connect Line-Out side jack (SPDIF) to Side */
1280 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1281 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1282 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1283/* Connect Mic jack to CLFE */
1284 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1285 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1286 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1287/* Connect Line-in jack to Surround */
1288 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1289 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1290 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1291/* Connect HP out jack to Front */
1292 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1293 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1294 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1295/* Enable unsolicited event for HP jack and Line-out jack */
1296 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1297 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1298 {}
1299};
1300
1301static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1302{
1303 unsigned int present;
1304 unsigned int bits;
1305 /* Line out presence */
1306 present = snd_hda_codec_read(codec, 0x17, 0,
1307 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1308 /* HP out presence */
1309 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1310 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1311 bits = present ? HDA_AMP_MUTE : 0;
1312 /* Toggle internal speakers muting */
1313 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1314 HDA_AMP_MUTE, bits);
1315 /* Toggle internal bass muting */
1316 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1317 HDA_AMP_MUTE, bits);
1318}
1319
1320static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1321 unsigned int res)
1322{
1323 if (res >> 26 == ALC880_HP_EVENT)
1324 alc888_fujitsu_xa3530_automute(codec);
1325}
1326
1327
5b2d1eca
VP
1328/*
1329 * ALC888 Acer Aspire 4930G model
1330 */
1331
1332static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1333/* Front Mic: set to PIN_IN (empty by default) */
1334 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1335/* Unselect Front Mic by default in input mixer 3 */
1336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1337/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1339/* Connect Internal HP to front */
1340 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1342 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1343/* Connect HP out to front */
1344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1347 { }
1348};
1349
ef8ef5fb 1350static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1351 /* Front mic only available on one ADC */
1352 {
1353 .num_items = 4,
1354 .items = {
1355 { "Mic", 0x0 },
1356 { "Line", 0x2 },
1357 { "CD", 0x4 },
1358 { "Front Mic", 0xb },
1359 },
1360 },
1361 {
1362 .num_items = 3,
1363 .items = {
1364 { "Mic", 0x0 },
1365 { "Line", 0x2 },
1366 { "CD", 0x4 },
1367 },
1368 }
1369};
1370
ef8ef5fb 1371static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1372 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1373 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1374 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1375 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1376 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1377 HDA_OUTPUT),
1378 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1379 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1380 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1381 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1382 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1388 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1389 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1390 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1391 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1392 { } /* end */
1393};
1394
1395static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1396{
1397 unsigned int present;
ef8ef5fb 1398 unsigned int bits;
5b2d1eca
VP
1399 present = snd_hda_codec_read(codec, 0x15, 0,
1400 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
ef8ef5fb
VP
1401 bits = present ? HDA_AMP_MUTE : 0;
1402 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1403 HDA_AMP_MUTE, bits);
5b2d1eca
VP
1404}
1405
1406static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1407 unsigned int res)
1408{
1409 if (res >> 26 == ALC880_HP_EVENT)
1410 alc888_acer_aspire_4930g_automute(codec);
1411}
1412
1da177e4 1413/*
e9edcee0
TI
1414 * ALC880 3-stack model
1415 *
1416 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1417 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1418 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1419 */
1420
e9edcee0
TI
1421static hda_nid_t alc880_dac_nids[4] = {
1422 /* front, rear, clfe, rear_surr */
1423 0x02, 0x05, 0x04, 0x03
1424};
1425
1426static hda_nid_t alc880_adc_nids[3] = {
1427 /* ADC0-2 */
1428 0x07, 0x08, 0x09,
1429};
1430
1431/* The datasheet says the node 0x07 is connected from inputs,
1432 * but it shows zero connection in the real implementation on some devices.
df694daa 1433 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1434 */
e9edcee0
TI
1435static hda_nid_t alc880_adc_nids_alt[2] = {
1436 /* ADC1-2 */
1437 0x08, 0x09,
1438};
1439
1440#define ALC880_DIGOUT_NID 0x06
1441#define ALC880_DIGIN_NID 0x0a
1442
1443static struct hda_input_mux alc880_capture_source = {
1444 .num_items = 4,
1445 .items = {
1446 { "Mic", 0x0 },
1447 { "Front Mic", 0x3 },
1448 { "Line", 0x2 },
1449 { "CD", 0x4 },
1450 },
1451};
1452
1453/* channel source setting (2/6 channel selection for 3-stack) */
1454/* 2ch mode */
1455static struct hda_verb alc880_threestack_ch2_init[] = {
1456 /* set line-in to input, mute it */
1457 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1458 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1459 /* set mic-in to input vref 80%, mute it */
1460 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1461 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1462 { } /* end */
1463};
1464
1465/* 6ch mode */
1466static struct hda_verb alc880_threestack_ch6_init[] = {
1467 /* set line-in to output, unmute it */
1468 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1469 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1470 /* set mic-in to output, unmute it */
1471 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1472 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1473 { } /* end */
1474};
1475
d2a6d7dc 1476static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1477 { 2, alc880_threestack_ch2_init },
1478 { 6, alc880_threestack_ch6_init },
1479};
1480
c8b6bf9b 1481static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1482 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1483 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1484 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1485 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1486 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1487 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1488 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1489 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1490 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1491 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1492 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1493 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1495 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1496 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1497 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1498 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1499 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
1500 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1501 {
1502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1503 .name = "Channel Mode",
df694daa
KY
1504 .info = alc_ch_mode_info,
1505 .get = alc_ch_mode_get,
1506 .put = alc_ch_mode_put,
e9edcee0
TI
1507 },
1508 { } /* end */
1509};
1510
1511/* capture mixer elements */
f9e336f6
TI
1512static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1513 struct snd_ctl_elem_info *uinfo)
1514{
1515 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1516 struct alc_spec *spec = codec->spec;
1517 int err;
1da177e4 1518
5a9e02e9 1519 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1520 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1521 HDA_INPUT);
1522 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 1523 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1524 return err;
1525}
1526
1527static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1528 unsigned int size, unsigned int __user *tlv)
1529{
1530 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1531 struct alc_spec *spec = codec->spec;
1532 int err;
1da177e4 1533
5a9e02e9 1534 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1535 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1536 HDA_INPUT);
1537 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 1538 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1539 return err;
1540}
1541
1542typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1543 struct snd_ctl_elem_value *ucontrol);
1544
1545static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1546 struct snd_ctl_elem_value *ucontrol,
1547 getput_call_t func)
1548{
1549 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1550 struct alc_spec *spec = codec->spec;
1551 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1552 int err;
1553
5a9e02e9 1554 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1555 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1556 3, 0, HDA_INPUT);
1557 err = func(kcontrol, ucontrol);
5a9e02e9 1558 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1559 return err;
1560}
1561
1562static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1563 struct snd_ctl_elem_value *ucontrol)
1564{
1565 return alc_cap_getput_caller(kcontrol, ucontrol,
1566 snd_hda_mixer_amp_volume_get);
1567}
1568
1569static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1570 struct snd_ctl_elem_value *ucontrol)
1571{
1572 return alc_cap_getput_caller(kcontrol, ucontrol,
1573 snd_hda_mixer_amp_volume_put);
1574}
1575
1576/* capture mixer elements */
1577#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1578
1579static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1580 struct snd_ctl_elem_value *ucontrol)
1581{
1582 return alc_cap_getput_caller(kcontrol, ucontrol,
1583 snd_hda_mixer_amp_switch_get);
1584}
1585
1586static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1587 struct snd_ctl_elem_value *ucontrol)
1588{
1589 return alc_cap_getput_caller(kcontrol, ucontrol,
1590 snd_hda_mixer_amp_switch_put);
1591}
1592
1593#define DEFINE_CAPMIX(num) \
1594static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1595 { \
1596 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1597 .name = "Capture Switch", \
1598 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1599 .count = num, \
1600 .info = alc_cap_sw_info, \
1601 .get = alc_cap_sw_get, \
1602 .put = alc_cap_sw_put, \
1603 }, \
1604 { \
1605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1606 .name = "Capture Volume", \
1607 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1608 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1609 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1610 .count = num, \
1611 .info = alc_cap_vol_info, \
1612 .get = alc_cap_vol_get, \
1613 .put = alc_cap_vol_put, \
1614 .tlv = { .c = alc_cap_vol_tlv }, \
1615 }, \
3c3e9892
TI
1616 { \
1617 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1618 /* .name = "Capture Source", */ \
1619 .name = "Input Source", \
1620 .count = num, \
1621 .info = alc_mux_enum_info, \
1622 .get = alc_mux_enum_get, \
1623 .put = alc_mux_enum_put, \
1624 }, \
f9e336f6
TI
1625 { } /* end */ \
1626}
1627
1628/* up to three ADCs */
1629DEFINE_CAPMIX(1);
1630DEFINE_CAPMIX(2);
1631DEFINE_CAPMIX(3);
e9edcee0
TI
1632
1633
1634/*
1635 * ALC880 5-stack model
1636 *
9c7f852e
TI
1637 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1638 * Side = 0x02 (0xd)
e9edcee0
TI
1639 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1640 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1641 */
1642
1643/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1644static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1645 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1646 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1647 { } /* end */
1648};
1649
e9edcee0
TI
1650/* channel source setting (6/8 channel selection for 5-stack) */
1651/* 6ch mode */
1652static struct hda_verb alc880_fivestack_ch6_init[] = {
1653 /* set line-in to input, mute it */
1654 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1655 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1656 { } /* end */
1657};
1658
e9edcee0
TI
1659/* 8ch mode */
1660static struct hda_verb alc880_fivestack_ch8_init[] = {
1661 /* set line-in to output, unmute it */
1662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1664 { } /* end */
1665};
1666
d2a6d7dc 1667static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1668 { 6, alc880_fivestack_ch6_init },
1669 { 8, alc880_fivestack_ch8_init },
1670};
1671
1672
1673/*
1674 * ALC880 6-stack model
1675 *
9c7f852e
TI
1676 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1677 * Side = 0x05 (0x0f)
e9edcee0
TI
1678 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1679 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1680 */
1681
1682static hda_nid_t alc880_6st_dac_nids[4] = {
1683 /* front, rear, clfe, rear_surr */
1684 0x02, 0x03, 0x04, 0x05
f12ab1e0 1685};
e9edcee0
TI
1686
1687static struct hda_input_mux alc880_6stack_capture_source = {
1688 .num_items = 4,
1689 .items = {
1690 { "Mic", 0x0 },
1691 { "Front Mic", 0x1 },
1692 { "Line", 0x2 },
1693 { "CD", 0x4 },
1694 },
1695};
1696
1697/* fixed 8-channels */
d2a6d7dc 1698static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1699 { 8, NULL },
1700};
1701
c8b6bf9b 1702static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1703 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1704 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1705 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1706 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1707 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1708 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1709 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1710 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1711 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1712 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1713 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1714 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1715 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1716 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1717 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1718 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1719 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1720 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1721 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1722 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
1723 {
1724 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1725 .name = "Channel Mode",
df694daa
KY
1726 .info = alc_ch_mode_info,
1727 .get = alc_ch_mode_get,
1728 .put = alc_ch_mode_put,
16ded525
TI
1729 },
1730 { } /* end */
1731};
1732
e9edcee0
TI
1733
1734/*
1735 * ALC880 W810 model
1736 *
1737 * W810 has rear IO for:
1738 * Front (DAC 02)
1739 * Surround (DAC 03)
1740 * Center/LFE (DAC 04)
1741 * Digital out (06)
1742 *
1743 * The system also has a pair of internal speakers, and a headphone jack.
1744 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 1745 *
e9edcee0
TI
1746 * There is a variable resistor to control the speaker or headphone
1747 * volume. This is a hardware-only device without a software API.
1748 *
1749 * Plugging headphones in will disable the internal speakers. This is
1750 * implemented in hardware, not via the driver using jack sense. In
1751 * a similar fashion, plugging into the rear socket marked "front" will
1752 * disable both the speakers and headphones.
1753 *
1754 * For input, there's a microphone jack, and an "audio in" jack.
1755 * These may not do anything useful with this driver yet, because I
1756 * haven't setup any initialization verbs for these yet...
1757 */
1758
1759static hda_nid_t alc880_w810_dac_nids[3] = {
1760 /* front, rear/surround, clfe */
1761 0x02, 0x03, 0x04
16ded525
TI
1762};
1763
e9edcee0 1764/* fixed 6 channels */
d2a6d7dc 1765static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1766 { 6, NULL }
1767};
1768
1769/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1770static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1771 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1772 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1773 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1774 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1775 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1776 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1777 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1778 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1780 { } /* end */
1781};
1782
1783
1784/*
1785 * Z710V model
1786 *
1787 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1788 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1789 * Line = 0x1a
e9edcee0
TI
1790 */
1791
1792static hda_nid_t alc880_z71v_dac_nids[1] = {
1793 0x02
1794};
1795#define ALC880_Z71V_HP_DAC 0x03
1796
1797/* fixed 2 channels */
d2a6d7dc 1798static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1799 { 2, NULL }
1800};
1801
c8b6bf9b 1802static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1803 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1804 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1805 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1806 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1807 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1808 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1811 { } /* end */
1812};
1813
e9edcee0 1814
e9edcee0
TI
1815/*
1816 * ALC880 F1734 model
1817 *
1818 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1819 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1820 */
1821
1822static hda_nid_t alc880_f1734_dac_nids[1] = {
1823 0x03
1824};
1825#define ALC880_F1734_HP_DAC 0x02
1826
c8b6bf9b 1827static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1828 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1829 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
1830 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1831 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1832 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1833 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
1834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1835 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
1836 { } /* end */
1837};
1838
937b4160
TI
1839static struct hda_input_mux alc880_f1734_capture_source = {
1840 .num_items = 2,
1841 .items = {
1842 { "Mic", 0x1 },
1843 { "CD", 0x4 },
1844 },
1845};
1846
e9edcee0 1847
e9edcee0
TI
1848/*
1849 * ALC880 ASUS model
1850 *
1851 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1852 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1853 * Mic = 0x18, Line = 0x1a
1854 */
1855
1856#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1857#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1858
c8b6bf9b 1859static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1860 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1861 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1862 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1863 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1864 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1865 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1866 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1867 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1868 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1869 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1870 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1871 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1872 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1873 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1874 {
1875 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1876 .name = "Channel Mode",
df694daa
KY
1877 .info = alc_ch_mode_info,
1878 .get = alc_ch_mode_get,
1879 .put = alc_ch_mode_put,
16ded525
TI
1880 },
1881 { } /* end */
1882};
e9edcee0 1883
e9edcee0
TI
1884/*
1885 * ALC880 ASUS W1V model
1886 *
1887 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1888 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1889 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1890 */
1891
1892/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1893static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1894 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1895 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1896 { } /* end */
1897};
1898
3c10a9d9 1899/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1900static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
1901 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1902 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1903 { } /* end */
1904};
e9edcee0 1905
df694daa
KY
1906/* TCL S700 */
1907static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1908 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1909 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1910 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1911 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1912 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1913 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1914 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1915 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1916 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
1917 { } /* end */
1918};
1919
ccc656ce
KY
1920/* Uniwill */
1921static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
1922 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1923 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1924 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1925 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1926 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1927 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1928 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1929 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1930 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1931 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1932 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1933 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1936 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1937 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1938 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1939 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1940 {
1941 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1942 .name = "Channel Mode",
1943 .info = alc_ch_mode_info,
1944 .get = alc_ch_mode_get,
1945 .put = alc_ch_mode_put,
1946 },
1947 { } /* end */
1948};
1949
2cf9f0fc
TD
1950static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1951 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1952 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1953 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1954 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1955 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1956 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1957 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1958 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1959 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1960 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1961 { } /* end */
1962};
1963
ccc656ce 1964static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
1965 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1966 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1967 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1968 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1970 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1971 { } /* end */
1972};
1973
2134ea4f
TI
1974/*
1975 * virtual master controls
1976 */
1977
1978/*
1979 * slave controls for virtual master
1980 */
1981static const char *alc_slave_vols[] = {
1982 "Front Playback Volume",
1983 "Surround Playback Volume",
1984 "Center Playback Volume",
1985 "LFE Playback Volume",
1986 "Side Playback Volume",
1987 "Headphone Playback Volume",
1988 "Speaker Playback Volume",
1989 "Mono Playback Volume",
2134ea4f 1990 "Line-Out Playback Volume",
26f5df26 1991 "PCM Playback Volume",
2134ea4f
TI
1992 NULL,
1993};
1994
1995static const char *alc_slave_sws[] = {
1996 "Front Playback Switch",
1997 "Surround Playback Switch",
1998 "Center Playback Switch",
1999 "LFE Playback Switch",
2000 "Side Playback Switch",
2001 "Headphone Playback Switch",
2002 "Speaker Playback Switch",
2003 "Mono Playback Switch",
edb54a55 2004 "IEC958 Playback Switch",
2134ea4f
TI
2005 NULL,
2006};
2007
1da177e4 2008/*
e9edcee0 2009 * build control elements
1da177e4 2010 */
603c4019
TI
2011
2012static void alc_free_kctls(struct hda_codec *codec);
2013
1da177e4
LT
2014static int alc_build_controls(struct hda_codec *codec)
2015{
2016 struct alc_spec *spec = codec->spec;
2017 int err;
2018 int i;
2019
2020 for (i = 0; i < spec->num_mixers; i++) {
2021 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2022 if (err < 0)
2023 return err;
2024 }
f9e336f6
TI
2025 if (spec->cap_mixer) {
2026 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2027 if (err < 0)
2028 return err;
2029 }
1da177e4 2030 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2031 err = snd_hda_create_spdif_out_ctls(codec,
2032 spec->multiout.dig_out_nid);
1da177e4
LT
2033 if (err < 0)
2034 return err;
e64f14f4
TI
2035 if (!spec->no_analog) {
2036 err = snd_hda_create_spdif_share_sw(codec,
2037 &spec->multiout);
2038 if (err < 0)
2039 return err;
2040 spec->multiout.share_spdif = 1;
2041 }
1da177e4
LT
2042 }
2043 if (spec->dig_in_nid) {
2044 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2045 if (err < 0)
2046 return err;
2047 }
2134ea4f
TI
2048
2049 /* if we have no master control, let's create it */
e64f14f4
TI
2050 if (!spec->no_analog &&
2051 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2052 unsigned int vmaster_tlv[4];
2134ea4f 2053 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2054 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2055 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2056 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2057 if (err < 0)
2058 return err;
2059 }
e64f14f4
TI
2060 if (!spec->no_analog &&
2061 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2062 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2063 NULL, alc_slave_sws);
2064 if (err < 0)
2065 return err;
2066 }
2067
603c4019 2068 alc_free_kctls(codec); /* no longer needed */
1da177e4
LT
2069 return 0;
2070}
2071
e9edcee0 2072
1da177e4
LT
2073/*
2074 * initialize the codec volumes, etc
2075 */
2076
e9edcee0
TI
2077/*
2078 * generic initialization of ADC, input mixers and output mixers
2079 */
2080static struct hda_verb alc880_volume_init_verbs[] = {
2081 /*
2082 * Unmute ADC0-2 and set the default input to mic-in
2083 */
71fe7b82 2084 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2086 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2088 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2090
e9edcee0
TI
2091 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2092 * mixer widget
9c7f852e
TI
2093 * Note: PASD motherboards uses the Line In 2 as the input for front
2094 * panel mic (mic 2)
1da177e4 2095 */
e9edcee0 2096 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2104
e9edcee0
TI
2105 /*
2106 * Set up output mixers (0x0c - 0x0f)
1da177e4 2107 */
e9edcee0
TI
2108 /* set vol=0 to output mixers */
2109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2112 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2113 /* set up input amps for analog loopback */
2114 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2118 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2119 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2122 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2123
2124 { }
2125};
2126
e9edcee0
TI
2127/*
2128 * 3-stack pin configuration:
2129 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2130 */
2131static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2132 /*
2133 * preset connection lists of input pins
2134 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2135 */
2136 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2137 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2138 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2139
2140 /*
2141 * Set pin mode and muting
2142 */
2143 /* set front pin widgets 0x14 for output */
05acb863 2144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2145 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2146 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2147 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2148 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2149 /* Mic2 (as headphone out) for HP output */
2150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2151 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2152 /* Line In pin widget for input */
05acb863 2153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2155 /* Line2 (as front mic) pin widget for input and vref at 80% */
2156 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2157 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2158 /* CD pin widget for input */
05acb863 2159 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2160
e9edcee0
TI
2161 { }
2162};
1da177e4 2163
e9edcee0
TI
2164/*
2165 * 5-stack pin configuration:
2166 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2167 * line-in/side = 0x1a, f-mic = 0x1b
2168 */
2169static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2170 /*
2171 * preset connection lists of input pins
2172 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2173 */
e9edcee0
TI
2174 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2175 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2176
e9edcee0
TI
2177 /*
2178 * Set pin mode and muting
1da177e4 2179 */
e9edcee0
TI
2180 /* set pin widgets 0x14-0x17 for output */
2181 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2184 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2185 /* unmute pins for output (no gain on this amp) */
2186 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2188 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2189 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2190
2191 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2193 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2194 /* Mic2 (as headphone out) for HP output */
2195 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2196 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2197 /* Line In pin widget for input */
2198 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2199 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2200 /* Line2 (as front mic) pin widget for input and vref at 80% */
2201 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2203 /* CD pin widget for input */
2204 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2205
2206 { }
2207};
2208
e9edcee0
TI
2209/*
2210 * W810 pin configuration:
2211 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2212 */
2213static struct hda_verb alc880_pin_w810_init_verbs[] = {
2214 /* hphone/speaker input selector: front DAC */
2215 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2216
05acb863 2217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2220 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2222 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2223
e9edcee0 2224 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2225 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2226
1da177e4
LT
2227 { }
2228};
2229
e9edcee0
TI
2230/*
2231 * Z71V pin configuration:
2232 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2233 */
2234static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2236 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2237 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2238 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2239
16ded525 2240 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2241 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2242 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2243 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2244
2245 { }
2246};
2247
e9edcee0
TI
2248/*
2249 * 6-stack pin configuration:
9c7f852e
TI
2250 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2251 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2252 */
2253static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2254 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2255
16ded525 2256 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2258 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2261 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2262 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2263 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2264
16ded525 2265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2266 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2269 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2272 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2273 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2274
e9edcee0
TI
2275 { }
2276};
2277
ccc656ce
KY
2278/*
2279 * Uniwill pin configuration:
2280 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2281 * line = 0x1a
2282 */
2283static struct hda_verb alc880_uniwill_init_verbs[] = {
2284 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2285
2286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2287 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2290 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2291 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2292 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2293 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2296 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2297 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2298 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2300
2301 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2302 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2303 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2304 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2307 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2308 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2309 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2310
2311 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2312 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2313
2314 { }
2315};
2316
2317/*
2318* Uniwill P53
ea1fb29a 2319* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2320 */
2321static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2322 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2323
2324 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2325 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2327 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2336
2337 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2339 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2343
2344 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2345 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2346
2347 { }
2348};
2349
2cf9f0fc
TD
2350static struct hda_verb alc880_beep_init_verbs[] = {
2351 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2352 { }
2353};
2354
ccc656ce 2355/* toggle speaker-output according to the hp-jack state */
458a4fab 2356static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
2357{
2358 unsigned int present;
f12ab1e0 2359 unsigned char bits;
ccc656ce
KY
2360
2361 present = snd_hda_codec_read(codec, 0x14, 0,
2362 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2363 bits = present ? HDA_AMP_MUTE : 0;
2364 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2365 HDA_AMP_MUTE, bits);
2366 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2367 HDA_AMP_MUTE, bits);
458a4fab
TI
2368}
2369
2370/* auto-toggle front mic */
2371static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2372{
2373 unsigned int present;
2374 unsigned char bits;
ccc656ce
KY
2375
2376 present = snd_hda_codec_read(codec, 0x18, 0,
2377 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2378 bits = present ? HDA_AMP_MUTE : 0;
2379 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2380}
2381
2382static void alc880_uniwill_automute(struct hda_codec *codec)
2383{
2384 alc880_uniwill_hp_automute(codec);
2385 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2386}
2387
2388static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2389 unsigned int res)
2390{
2391 /* Looks like the unsol event is incompatible with the standard
2392 * definition. 4bit tag is placed at 28 bit!
2393 */
458a4fab
TI
2394 switch (res >> 28) {
2395 case ALC880_HP_EVENT:
2396 alc880_uniwill_hp_automute(codec);
2397 break;
2398 case ALC880_MIC_EVENT:
2399 alc880_uniwill_mic_automute(codec);
2400 break;
2401 }
ccc656ce
KY
2402}
2403
2404static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2405{
2406 unsigned int present;
f12ab1e0 2407 unsigned char bits;
ccc656ce
KY
2408
2409 present = snd_hda_codec_read(codec, 0x14, 0,
2410 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a 2411 bits = present ? HDA_AMP_MUTE : 0;
64654c2f 2412 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
2413}
2414
2415static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2416{
2417 unsigned int present;
ea1fb29a 2418
ccc656ce 2419 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
2420 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2421 present &= HDA_AMP_VOLMASK;
2422 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2423 HDA_AMP_VOLMASK, present);
2424 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2425 HDA_AMP_VOLMASK, present);
ccc656ce 2426}
47fd830a 2427
ccc656ce
KY
2428static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2429 unsigned int res)
2430{
2431 /* Looks like the unsol event is incompatible with the standard
2432 * definition. 4bit tag is placed at 28 bit!
2433 */
2434 if ((res >> 28) == ALC880_HP_EVENT)
2435 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 2436 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
2437 alc880_uniwill_p53_dcvol_automute(codec);
2438}
2439
e9edcee0
TI
2440/*
2441 * F1734 pin configuration:
2442 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2443 */
2444static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2445 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2446 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2447 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2448 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2449 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2450
e9edcee0 2451 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2452 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2455
e9edcee0
TI
2456 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2457 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2458 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2460 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2462 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2463 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2464 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2465
937b4160
TI
2466 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2467 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2468
dfc0ff62
TI
2469 { }
2470};
2471
e9edcee0
TI
2472/*
2473 * ASUS pin configuration:
2474 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2475 */
2476static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2477 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2478 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2479 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2480 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2481
2482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2483 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2484 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2486 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2488 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2490
2491 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2492 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2493 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2494 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2495 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2497 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2499 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2500
e9edcee0
TI
2501 { }
2502};
16ded525 2503
e9edcee0 2504/* Enable GPIO mask and set output */
bc9f98a9
KY
2505#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2506#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
2507
2508/* Clevo m520g init */
2509static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2510 /* headphone output */
2511 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2512 /* line-out */
2513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2514 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2515 /* Line-in */
2516 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2517 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2518 /* CD */
2519 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2520 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2521 /* Mic1 (rear panel) */
2522 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2523 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2524 /* Mic2 (front panel) */
2525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2526 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2527 /* headphone */
2528 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2530 /* change to EAPD mode */
2531 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2532 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2533
2534 { }
16ded525
TI
2535};
2536
df694daa 2537static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2538 /* change to EAPD mode */
2539 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2540 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2541
df694daa
KY
2542 /* Headphone output */
2543 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2544 /* Front output*/
2545 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2546 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2547
2548 /* Line In pin widget for input */
2549 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2550 /* CD pin widget for input */
2551 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2552 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2553 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2554
2555 /* change to EAPD mode */
2556 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2557 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2558
2559 { }
2560};
16ded525 2561
e9edcee0 2562/*
ae6b813a
TI
2563 * LG m1 express dual
2564 *
2565 * Pin assignment:
2566 * Rear Line-In/Out (blue): 0x14
2567 * Build-in Mic-In: 0x15
2568 * Speaker-out: 0x17
2569 * HP-Out (green): 0x1b
2570 * Mic-In/Out (red): 0x19
2571 * SPDIF-Out: 0x1e
2572 */
2573
2574/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2575static hda_nid_t alc880_lg_dac_nids[3] = {
2576 0x05, 0x02, 0x03
2577};
2578
2579/* seems analog CD is not working */
2580static struct hda_input_mux alc880_lg_capture_source = {
2581 .num_items = 3,
2582 .items = {
2583 { "Mic", 0x1 },
2584 { "Line", 0x5 },
2585 { "Internal Mic", 0x6 },
2586 },
2587};
2588
2589/* 2,4,6 channel modes */
2590static struct hda_verb alc880_lg_ch2_init[] = {
2591 /* set line-in and mic-in to input */
2592 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2593 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2594 { }
2595};
2596
2597static struct hda_verb alc880_lg_ch4_init[] = {
2598 /* set line-in to out and mic-in to input */
2599 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2600 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2601 { }
2602};
2603
2604static struct hda_verb alc880_lg_ch6_init[] = {
2605 /* set line-in and mic-in to output */
2606 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2607 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2608 { }
2609};
2610
2611static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2612 { 2, alc880_lg_ch2_init },
2613 { 4, alc880_lg_ch4_init },
2614 { 6, alc880_lg_ch6_init },
2615};
2616
2617static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2618 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2619 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2620 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2621 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2622 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2623 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2624 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2625 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2627 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2628 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2629 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2630 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2631 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2632 {
2633 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2634 .name = "Channel Mode",
2635 .info = alc_ch_mode_info,
2636 .get = alc_ch_mode_get,
2637 .put = alc_ch_mode_put,
2638 },
2639 { } /* end */
2640};
2641
2642static struct hda_verb alc880_lg_init_verbs[] = {
2643 /* set capture source to mic-in */
2644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2645 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2646 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2647 /* mute all amp mixer inputs */
2648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2651 /* line-in to input */
2652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2653 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2654 /* built-in mic */
2655 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2656 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2657 /* speaker-out */
2658 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2659 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2660 /* mic-in to input */
2661 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2662 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2663 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2664 /* HP-out */
2665 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2666 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2667 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2668 /* jack sense */
2669 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2670 { }
2671};
2672
2673/* toggle speaker-output according to the hp-jack state */
2674static void alc880_lg_automute(struct hda_codec *codec)
2675{
2676 unsigned int present;
f12ab1e0 2677 unsigned char bits;
ae6b813a
TI
2678
2679 present = snd_hda_codec_read(codec, 0x1b, 0,
2680 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2681 bits = present ? HDA_AMP_MUTE : 0;
2682 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2683 HDA_AMP_MUTE, bits);
ae6b813a
TI
2684}
2685
2686static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2687{
2688 /* Looks like the unsol event is incompatible with the standard
2689 * definition. 4bit tag is placed at 28 bit!
2690 */
2691 if ((res >> 28) == 0x01)
2692 alc880_lg_automute(codec);
2693}
2694
d681518a
TI
2695/*
2696 * LG LW20
2697 *
2698 * Pin assignment:
2699 * Speaker-out: 0x14
2700 * Mic-In: 0x18
e4f41da9
CM
2701 * Built-in Mic-In: 0x19
2702 * Line-In: 0x1b
2703 * HP-Out: 0x1a
d681518a
TI
2704 * SPDIF-Out: 0x1e
2705 */
2706
d681518a 2707static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2708 .num_items = 3,
d681518a
TI
2709 .items = {
2710 { "Mic", 0x0 },
2711 { "Internal Mic", 0x1 },
e4f41da9 2712 { "Line In", 0x2 },
d681518a
TI
2713 },
2714};
2715
0a8c5da3
CM
2716#define alc880_lg_lw_modes alc880_threestack_modes
2717
d681518a 2718static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2720 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2721 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2722 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2723 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2724 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2725 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2726 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2727 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2728 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2731 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2732 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
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 },
d681518a
TI
2740 { } /* end */
2741};
2742
2743static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2744 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2745 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2746 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2747
d681518a
TI
2748 /* set capture source to mic-in */
2749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2751 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2753 /* speaker-out */
2754 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2756 /* HP-out */
d681518a
TI
2757 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2758 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2759 /* mic-in to input */
2760 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2761 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2762 /* built-in mic */
2763 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2765 /* jack sense */
2766 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2767 { }
2768};
2769
2770/* toggle speaker-output according to the hp-jack state */
2771static void alc880_lg_lw_automute(struct hda_codec *codec)
2772{
2773 unsigned int present;
f12ab1e0 2774 unsigned char bits;
d681518a
TI
2775
2776 present = snd_hda_codec_read(codec, 0x1b, 0,
2777 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2778 bits = present ? HDA_AMP_MUTE : 0;
2779 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2780 HDA_AMP_MUTE, bits);
d681518a
TI
2781}
2782
2783static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2784{
2785 /* Looks like the unsol event is incompatible with the standard
2786 * definition. 4bit tag is placed at 28 bit!
2787 */
2788 if ((res >> 28) == 0x01)
2789 alc880_lg_lw_automute(codec);
2790}
2791
df99cd33
TI
2792static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2793 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2794 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2797 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2798 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2799 { } /* end */
2800};
2801
2802static struct hda_input_mux alc880_medion_rim_capture_source = {
2803 .num_items = 2,
2804 .items = {
2805 { "Mic", 0x0 },
2806 { "Internal Mic", 0x1 },
2807 },
2808};
2809
2810static struct hda_verb alc880_medion_rim_init_verbs[] = {
2811 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2812
2813 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2815
2816 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2817 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2818 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2819 /* Mic2 (as headphone out) for HP output */
2820 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2821 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2822 /* Internal Speaker */
2823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2824 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2825
2826 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2827 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2828
2829 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2830 { }
2831};
2832
2833/* toggle speaker-output according to the hp-jack state */
2834static void alc880_medion_rim_automute(struct hda_codec *codec)
2835{
2836 unsigned int present;
2837 unsigned char bits;
2838
2839 present = snd_hda_codec_read(codec, 0x14, 0,
2840 AC_VERB_GET_PIN_SENSE, 0)
2841 & AC_PINSENSE_PRESENCE;
2842 bits = present ? HDA_AMP_MUTE : 0;
2843 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2844 HDA_AMP_MUTE, bits);
2845 if (present)
2846 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2847 else
2848 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2849}
2850
2851static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2852 unsigned int res)
2853{
2854 /* Looks like the unsol event is incompatible with the standard
2855 * definition. 4bit tag is placed at 28 bit!
2856 */
2857 if ((res >> 28) == ALC880_HP_EVENT)
2858 alc880_medion_rim_automute(codec);
2859}
2860
cb53c626
TI
2861#ifdef CONFIG_SND_HDA_POWER_SAVE
2862static struct hda_amp_list alc880_loopbacks[] = {
2863 { 0x0b, HDA_INPUT, 0 },
2864 { 0x0b, HDA_INPUT, 1 },
2865 { 0x0b, HDA_INPUT, 2 },
2866 { 0x0b, HDA_INPUT, 3 },
2867 { 0x0b, HDA_INPUT, 4 },
2868 { } /* end */
2869};
2870
2871static struct hda_amp_list alc880_lg_loopbacks[] = {
2872 { 0x0b, HDA_INPUT, 1 },
2873 { 0x0b, HDA_INPUT, 6 },
2874 { 0x0b, HDA_INPUT, 7 },
2875 { } /* end */
2876};
2877#endif
2878
ae6b813a
TI
2879/*
2880 * Common callbacks
e9edcee0
TI
2881 */
2882
1da177e4
LT
2883static int alc_init(struct hda_codec *codec)
2884{
2885 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2886 unsigned int i;
2887
2c3bf9ab 2888 alc_fix_pll(codec);
1082c748
TI
2889 if (codec->vendor_id == 0x10ec0888)
2890 alc888_coef_init(codec);
2c3bf9ab 2891
e9edcee0
TI
2892 for (i = 0; i < spec->num_init_verbs; i++)
2893 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2894
2895 if (spec->init_hook)
2896 spec->init_hook(codec);
2897
1da177e4
LT
2898 return 0;
2899}
2900
ae6b813a
TI
2901static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2902{
2903 struct alc_spec *spec = codec->spec;
2904
2905 if (spec->unsol_event)
2906 spec->unsol_event(codec, res);
2907}
2908
cb53c626
TI
2909#ifdef CONFIG_SND_HDA_POWER_SAVE
2910static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2911{
2912 struct alc_spec *spec = codec->spec;
2913 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2914}
2915#endif
2916
1da177e4
LT
2917/*
2918 * Analog playback callbacks
2919 */
2920static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2921 struct hda_codec *codec,
c8b6bf9b 2922 struct snd_pcm_substream *substream)
1da177e4
LT
2923{
2924 struct alc_spec *spec = codec->spec;
9a08160b
TI
2925 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2926 hinfo);
1da177e4
LT
2927}
2928
2929static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2930 struct hda_codec *codec,
2931 unsigned int stream_tag,
2932 unsigned int format,
c8b6bf9b 2933 struct snd_pcm_substream *substream)
1da177e4
LT
2934{
2935 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2936 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2937 stream_tag, format, substream);
1da177e4
LT
2938}
2939
2940static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2941 struct hda_codec *codec,
c8b6bf9b 2942 struct snd_pcm_substream *substream)
1da177e4
LT
2943{
2944 struct alc_spec *spec = codec->spec;
2945 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2946}
2947
2948/*
2949 * Digital out
2950 */
2951static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2952 struct hda_codec *codec,
c8b6bf9b 2953 struct snd_pcm_substream *substream)
1da177e4
LT
2954{
2955 struct alc_spec *spec = codec->spec;
2956 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2957}
2958
6b97eb45
TI
2959static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2960 struct hda_codec *codec,
2961 unsigned int stream_tag,
2962 unsigned int format,
2963 struct snd_pcm_substream *substream)
2964{
2965 struct alc_spec *spec = codec->spec;
2966 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2967 stream_tag, format, substream);
2968}
2969
1da177e4
LT
2970static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2971 struct hda_codec *codec,
c8b6bf9b 2972 struct snd_pcm_substream *substream)
1da177e4
LT
2973{
2974 struct alc_spec *spec = codec->spec;
2975 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2976}
2977
2978/*
2979 * Analog capture
2980 */
6330079f 2981static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
2982 struct hda_codec *codec,
2983 unsigned int stream_tag,
2984 unsigned int format,
c8b6bf9b 2985 struct snd_pcm_substream *substream)
1da177e4
LT
2986{
2987 struct alc_spec *spec = codec->spec;
2988
6330079f 2989 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
2990 stream_tag, 0, format);
2991 return 0;
2992}
2993
6330079f 2994static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 2995 struct hda_codec *codec,
c8b6bf9b 2996 struct snd_pcm_substream *substream)
1da177e4
LT
2997{
2998 struct alc_spec *spec = codec->spec;
2999
888afa15
TI
3000 snd_hda_codec_cleanup_stream(codec,
3001 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3002 return 0;
3003}
3004
3005
3006/*
3007 */
3008static struct hda_pcm_stream alc880_pcm_analog_playback = {
3009 .substreams = 1,
3010 .channels_min = 2,
3011 .channels_max = 8,
e9edcee0 3012 /* NID is set in alc_build_pcms */
1da177e4
LT
3013 .ops = {
3014 .open = alc880_playback_pcm_open,
3015 .prepare = alc880_playback_pcm_prepare,
3016 .cleanup = alc880_playback_pcm_cleanup
3017 },
3018};
3019
3020static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3021 .substreams = 1,
3022 .channels_min = 2,
3023 .channels_max = 2,
3024 /* NID is set in alc_build_pcms */
3025};
3026
3027static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3028 .substreams = 1,
3029 .channels_min = 2,
3030 .channels_max = 2,
3031 /* NID is set in alc_build_pcms */
3032};
3033
3034static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3035 .substreams = 2, /* can be overridden */
1da177e4
LT
3036 .channels_min = 2,
3037 .channels_max = 2,
e9edcee0 3038 /* NID is set in alc_build_pcms */
1da177e4 3039 .ops = {
6330079f
TI
3040 .prepare = alc880_alt_capture_pcm_prepare,
3041 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3042 },
3043};
3044
3045static struct hda_pcm_stream alc880_pcm_digital_playback = {
3046 .substreams = 1,
3047 .channels_min = 2,
3048 .channels_max = 2,
3049 /* NID is set in alc_build_pcms */
3050 .ops = {
3051 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
3052 .close = alc880_dig_playback_pcm_close,
3053 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
3054 },
3055};
3056
3057static struct hda_pcm_stream alc880_pcm_digital_capture = {
3058 .substreams = 1,
3059 .channels_min = 2,
3060 .channels_max = 2,
3061 /* NID is set in alc_build_pcms */
3062};
3063
4c5186ed 3064/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3065static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3066 .substreams = 0,
3067 .channels_min = 0,
3068 .channels_max = 0,
3069};
3070
1da177e4
LT
3071static int alc_build_pcms(struct hda_codec *codec)
3072{
3073 struct alc_spec *spec = codec->spec;
3074 struct hda_pcm *info = spec->pcm_rec;
3075 int i;
3076
3077 codec->num_pcms = 1;
3078 codec->pcm_info = info;
3079
e64f14f4
TI
3080 if (spec->no_analog)
3081 goto skip_analog;
3082
1da177e4 3083 info->name = spec->stream_name_analog;
4a471b7d 3084 if (spec->stream_analog_playback) {
da3cec35
TI
3085 if (snd_BUG_ON(!spec->multiout.dac_nids))
3086 return -EINVAL;
4a471b7d
TI
3087 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3088 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3089 }
3090 if (spec->stream_analog_capture) {
da3cec35
TI
3091 if (snd_BUG_ON(!spec->adc_nids))
3092 return -EINVAL;
4a471b7d
TI
3093 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3094 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3095 }
3096
3097 if (spec->channel_mode) {
3098 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3099 for (i = 0; i < spec->num_channel_mode; i++) {
3100 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3101 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3102 }
1da177e4
LT
3103 }
3104 }
3105
e64f14f4 3106 skip_analog:
e08a007d 3107 /* SPDIF for stream index #1 */
1da177e4 3108 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 3109 codec->num_pcms = 2;
c06134d7 3110 info = spec->pcm_rec + 1;
1da177e4 3111 info->name = spec->stream_name_digital;
8c441982
TI
3112 if (spec->dig_out_type)
3113 info->pcm_type = spec->dig_out_type;
3114 else
3115 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3116 if (spec->multiout.dig_out_nid &&
3117 spec->stream_digital_playback) {
1da177e4
LT
3118 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3119 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3120 }
4a471b7d
TI
3121 if (spec->dig_in_nid &&
3122 spec->stream_digital_capture) {
1da177e4
LT
3123 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3124 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3125 }
963f803f
TI
3126 /* FIXME: do we need this for all Realtek codec models? */
3127 codec->spdif_status_reset = 1;
1da177e4
LT
3128 }
3129
e64f14f4
TI
3130 if (spec->no_analog)
3131 return 0;
3132
e08a007d
TI
3133 /* If the use of more than one ADC is requested for the current
3134 * model, configure a second analog capture-only PCM.
3135 */
3136 /* Additional Analaog capture for index #2 */
6330079f
TI
3137 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3138 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3139 codec->num_pcms = 3;
c06134d7 3140 info = spec->pcm_rec + 2;
e08a007d 3141 info->name = spec->stream_name_analog;
6330079f
TI
3142 if (spec->alt_dac_nid) {
3143 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3144 *spec->stream_analog_alt_playback;
3145 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3146 spec->alt_dac_nid;
3147 } else {
3148 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3149 alc_pcm_null_stream;
3150 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3151 }
3152 if (spec->num_adc_nids > 1) {
3153 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3154 *spec->stream_analog_alt_capture;
3155 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3156 spec->adc_nids[1];
3157 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3158 spec->num_adc_nids - 1;
3159 } else {
3160 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3161 alc_pcm_null_stream;
3162 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3163 }
3164 }
3165
1da177e4
LT
3166 return 0;
3167}
3168
603c4019
TI
3169static void alc_free_kctls(struct hda_codec *codec)
3170{
3171 struct alc_spec *spec = codec->spec;
3172
3173 if (spec->kctls.list) {
3174 struct snd_kcontrol_new *kctl = spec->kctls.list;
3175 int i;
3176 for (i = 0; i < spec->kctls.used; i++)
3177 kfree(kctl[i].name);
3178 }
3179 snd_array_free(&spec->kctls);
3180}
3181
1da177e4
LT
3182static void alc_free(struct hda_codec *codec)
3183{
e9edcee0 3184 struct alc_spec *spec = codec->spec;
e9edcee0 3185
f12ab1e0 3186 if (!spec)
e9edcee0
TI
3187 return;
3188
603c4019 3189 alc_free_kctls(codec);
e9edcee0 3190 kfree(spec);
680cd536 3191 snd_hda_detach_beep_device(codec);
7943a8ab 3192 codec->spec = NULL; /* to be sure */
1da177e4
LT
3193}
3194
e044c39a
TI
3195#ifdef SND_HDA_NEEDS_RESUME
3196static void store_pin_configs(struct hda_codec *codec)
3197{
3198 struct alc_spec *spec = codec->spec;
3199 hda_nid_t nid, end_nid;
3200
3201 end_nid = codec->start_nid + codec->num_nodes;
3202 for (nid = codec->start_nid; nid < end_nid; nid++) {
3203 unsigned int wid_caps = get_wcaps(codec, nid);
3204 unsigned int wid_type =
3205 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3206 if (wid_type != AC_WID_PIN)
3207 continue;
3208 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
3209 break;
3210 spec->pin_nids[spec->num_pins] = nid;
3211 spec->pin_cfgs[spec->num_pins] =
3212 snd_hda_codec_read(codec, nid, 0,
3213 AC_VERB_GET_CONFIG_DEFAULT, 0);
3214 spec->num_pins++;
3215 }
3216}
3217
3218static void resume_pin_configs(struct hda_codec *codec)
3219{
3220 struct alc_spec *spec = codec->spec;
3221 int i;
3222
3223 for (i = 0; i < spec->num_pins; i++) {
3224 hda_nid_t pin_nid = spec->pin_nids[i];
3225 unsigned int pin_config = spec->pin_cfgs[i];
3226 snd_hda_codec_write(codec, pin_nid, 0,
3227 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
3228 pin_config & 0x000000ff);
3229 snd_hda_codec_write(codec, pin_nid, 0,
3230 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
3231 (pin_config & 0x0000ff00) >> 8);
3232 snd_hda_codec_write(codec, pin_nid, 0,
3233 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
3234 (pin_config & 0x00ff0000) >> 16);
3235 snd_hda_codec_write(codec, pin_nid, 0,
3236 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
3237 pin_config >> 24);
3238 }
3239}
3240
3241static int alc_resume(struct hda_codec *codec)
3242{
3243 resume_pin_configs(codec);
3244 codec->patch_ops.init(codec);
3245 snd_hda_codec_resume_amp(codec);
3246 snd_hda_codec_resume_cache(codec);
3247 return 0;
3248}
3249#else
3250#define store_pin_configs(codec)
3251#endif
3252
1da177e4
LT
3253/*
3254 */
3255static struct hda_codec_ops alc_patch_ops = {
3256 .build_controls = alc_build_controls,
3257 .build_pcms = alc_build_pcms,
3258 .init = alc_init,
3259 .free = alc_free,
ae6b813a 3260 .unsol_event = alc_unsol_event,
e044c39a
TI
3261#ifdef SND_HDA_NEEDS_RESUME
3262 .resume = alc_resume,
3263#endif
cb53c626
TI
3264#ifdef CONFIG_SND_HDA_POWER_SAVE
3265 .check_power_status = alc_check_power_status,
3266#endif
1da177e4
LT
3267};
3268
2fa522be
TI
3269
3270/*
3271 * Test configuration for debugging
3272 *
3273 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3274 * enum controls.
3275 */
3276#ifdef CONFIG_SND_DEBUG
3277static hda_nid_t alc880_test_dac_nids[4] = {
3278 0x02, 0x03, 0x04, 0x05
3279};
3280
3281static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3282 .num_items = 7,
2fa522be
TI
3283 .items = {
3284 { "In-1", 0x0 },
3285 { "In-2", 0x1 },
3286 { "In-3", 0x2 },
3287 { "In-4", 0x3 },
3288 { "CD", 0x4 },
ae6b813a
TI
3289 { "Front", 0x5 },
3290 { "Surround", 0x6 },
2fa522be
TI
3291 },
3292};
3293
d2a6d7dc 3294static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3295 { 2, NULL },
fd2c326d 3296 { 4, NULL },
2fa522be 3297 { 6, NULL },
fd2c326d 3298 { 8, NULL },
2fa522be
TI
3299};
3300
9c7f852e
TI
3301static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3302 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3303{
3304 static char *texts[] = {
3305 "N/A", "Line Out", "HP Out",
3306 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3307 };
3308 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3309 uinfo->count = 1;
3310 uinfo->value.enumerated.items = 8;
3311 if (uinfo->value.enumerated.item >= 8)
3312 uinfo->value.enumerated.item = 7;
3313 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3314 return 0;
3315}
3316
9c7f852e
TI
3317static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3318 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3319{
3320 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3321 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3322 unsigned int pin_ctl, item = 0;
3323
3324 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3325 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3326 if (pin_ctl & AC_PINCTL_OUT_EN) {
3327 if (pin_ctl & AC_PINCTL_HP_EN)
3328 item = 2;
3329 else
3330 item = 1;
3331 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3332 switch (pin_ctl & AC_PINCTL_VREFEN) {
3333 case AC_PINCTL_VREF_HIZ: item = 3; break;
3334 case AC_PINCTL_VREF_50: item = 4; break;
3335 case AC_PINCTL_VREF_GRD: item = 5; break;
3336 case AC_PINCTL_VREF_80: item = 6; break;
3337 case AC_PINCTL_VREF_100: item = 7; break;
3338 }
3339 }
3340 ucontrol->value.enumerated.item[0] = item;
3341 return 0;
3342}
3343
9c7f852e
TI
3344static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3345 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3346{
3347 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3348 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3349 static unsigned int ctls[] = {
3350 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3351 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3352 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3353 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3354 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3355 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3356 };
3357 unsigned int old_ctl, new_ctl;
3358
3359 old_ctl = snd_hda_codec_read(codec, nid, 0,
3360 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3361 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3362 if (old_ctl != new_ctl) {
82beb8fd
TI
3363 int val;
3364 snd_hda_codec_write_cache(codec, nid, 0,
3365 AC_VERB_SET_PIN_WIDGET_CONTROL,
3366 new_ctl);
47fd830a
TI
3367 val = ucontrol->value.enumerated.item[0] >= 3 ?
3368 HDA_AMP_MUTE : 0;
3369 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3370 HDA_AMP_MUTE, val);
2fa522be
TI
3371 return 1;
3372 }
3373 return 0;
3374}
3375
9c7f852e
TI
3376static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3377 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3378{
3379 static char *texts[] = {
3380 "Front", "Surround", "CLFE", "Side"
3381 };
3382 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3383 uinfo->count = 1;
3384 uinfo->value.enumerated.items = 4;
3385 if (uinfo->value.enumerated.item >= 4)
3386 uinfo->value.enumerated.item = 3;
3387 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3388 return 0;
3389}
3390
9c7f852e
TI
3391static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3392 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3393{
3394 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3395 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3396 unsigned int sel;
3397
3398 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3399 ucontrol->value.enumerated.item[0] = sel & 3;
3400 return 0;
3401}
3402
9c7f852e
TI
3403static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3404 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3405{
3406 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3407 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3408 unsigned int sel;
3409
3410 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3411 if (ucontrol->value.enumerated.item[0] != sel) {
3412 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
3413 snd_hda_codec_write_cache(codec, nid, 0,
3414 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
3415 return 1;
3416 }
3417 return 0;
3418}
3419
3420#define PIN_CTL_TEST(xname,nid) { \
3421 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3422 .name = xname, \
3423 .info = alc_test_pin_ctl_info, \
3424 .get = alc_test_pin_ctl_get, \
3425 .put = alc_test_pin_ctl_put, \
3426 .private_value = nid \
3427 }
3428
3429#define PIN_SRC_TEST(xname,nid) { \
3430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3431 .name = xname, \
3432 .info = alc_test_pin_src_info, \
3433 .get = alc_test_pin_src_get, \
3434 .put = alc_test_pin_src_put, \
3435 .private_value = nid \
3436 }
3437
c8b6bf9b 3438static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
3439 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3440 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3441 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3442 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
3443 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3444 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3445 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3446 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
3447 PIN_CTL_TEST("Front Pin Mode", 0x14),
3448 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3449 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3450 PIN_CTL_TEST("Side Pin Mode", 0x17),
3451 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3452 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3453 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3454 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3455 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3456 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3457 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3458 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3459 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3460 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3461 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3462 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3463 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3464 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3465 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3466 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3467 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3468 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
3469 {
3470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3471 .name = "Channel Mode",
df694daa
KY
3472 .info = alc_ch_mode_info,
3473 .get = alc_ch_mode_get,
3474 .put = alc_ch_mode_put,
2fa522be
TI
3475 },
3476 { } /* end */
3477};
3478
3479static struct hda_verb alc880_test_init_verbs[] = {
3480 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
3481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3482 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3484 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3485 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3486 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3487 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3488 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 3489 /* Vol output for 0x0c-0x0f */
05acb863
TI
3490 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3491 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3493 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 3494 /* Set output pins 0x14-0x17 */
05acb863
TI
3495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3497 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3498 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 3499 /* Unmute output pins 0x14-0x17 */
05acb863
TI
3500 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3502 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3503 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 3504 /* Set input pins 0x18-0x1c */
16ded525
TI
3505 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3506 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
3507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3509 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 3510 /* Mute input pins 0x18-0x1b */
05acb863
TI
3511 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3514 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 3515 /* ADC set up */
05acb863 3516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3517 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3518 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3519 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3520 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3521 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3522 /* Analog input/passthru */
3523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
3528 { }
3529};
3530#endif
3531
1da177e4
LT
3532/*
3533 */
3534
f5fcc13c
TI
3535static const char *alc880_models[ALC880_MODEL_LAST] = {
3536 [ALC880_3ST] = "3stack",
3537 [ALC880_TCL_S700] = "tcl",
3538 [ALC880_3ST_DIG] = "3stack-digout",
3539 [ALC880_CLEVO] = "clevo",
3540 [ALC880_5ST] = "5stack",
3541 [ALC880_5ST_DIG] = "5stack-digout",
3542 [ALC880_W810] = "w810",
3543 [ALC880_Z71V] = "z71v",
3544 [ALC880_6ST] = "6stack",
3545 [ALC880_6ST_DIG] = "6stack-digout",
3546 [ALC880_ASUS] = "asus",
3547 [ALC880_ASUS_W1V] = "asus-w1v",
3548 [ALC880_ASUS_DIG] = "asus-dig",
3549 [ALC880_ASUS_DIG2] = "asus-dig2",
3550 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
3551 [ALC880_UNIWILL_P53] = "uniwill-p53",
3552 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
3553 [ALC880_F1734] = "F1734",
3554 [ALC880_LG] = "lg",
3555 [ALC880_LG_LW] = "lg-lw",
df99cd33 3556 [ALC880_MEDION_RIM] = "medion",
2fa522be 3557#ifdef CONFIG_SND_DEBUG
f5fcc13c 3558 [ALC880_TEST] = "test",
2fa522be 3559#endif
f5fcc13c
TI
3560 [ALC880_AUTO] = "auto",
3561};
3562
3563static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 3564 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
3565 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3566 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3567 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3568 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3569 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3570 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3571 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3572 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
3573 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3574 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
3575 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3576 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3577 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3578 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3579 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3580 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3581 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3582 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3583 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3584 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 3585 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
3586 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3587 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3588 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 3589 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 3590 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
3591 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3592 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
3593 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3594 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
3595 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3596 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3597 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3598 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3599 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3600 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3601 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3602 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3603 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3604 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3605 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3606 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3607 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3608 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3609 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3610 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3611 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 3612 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 3613 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3614 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3615 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3616 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3617 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3618 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3619 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3620 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3621 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3622 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3623 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3624 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3625 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3626 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3627 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3628 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3629 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3630 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3631 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3632 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3633 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3634 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3635 {}
3636};
3637
16ded525 3638/*
df694daa 3639 * ALC880 codec presets
16ded525 3640 */
16ded525
TI
3641static struct alc_config_preset alc880_presets[] = {
3642 [ALC880_3ST] = {
e9edcee0 3643 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3644 .init_verbs = { alc880_volume_init_verbs,
3645 alc880_pin_3stack_init_verbs },
16ded525 3646 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3647 .dac_nids = alc880_dac_nids,
16ded525
TI
3648 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3649 .channel_mode = alc880_threestack_modes,
4e195a7b 3650 .need_dac_fix = 1,
16ded525
TI
3651 .input_mux = &alc880_capture_source,
3652 },
3653 [ALC880_3ST_DIG] = {
e9edcee0 3654 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3655 .init_verbs = { alc880_volume_init_verbs,
3656 alc880_pin_3stack_init_verbs },
16ded525 3657 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3658 .dac_nids = alc880_dac_nids,
3659 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3660 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3661 .channel_mode = alc880_threestack_modes,
4e195a7b 3662 .need_dac_fix = 1,
16ded525
TI
3663 .input_mux = &alc880_capture_source,
3664 },
df694daa
KY
3665 [ALC880_TCL_S700] = {
3666 .mixers = { alc880_tcl_s700_mixer },
3667 .init_verbs = { alc880_volume_init_verbs,
3668 alc880_pin_tcl_S700_init_verbs,
3669 alc880_gpio2_init_verbs },
3670 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3671 .dac_nids = alc880_dac_nids,
f9e336f6
TI
3672 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3673 .num_adc_nids = 1, /* single ADC */
df694daa
KY
3674 .hp_nid = 0x03,
3675 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3676 .channel_mode = alc880_2_jack_modes,
3677 .input_mux = &alc880_capture_source,
3678 },
16ded525 3679 [ALC880_5ST] = {
f12ab1e0
TI
3680 .mixers = { alc880_three_stack_mixer,
3681 alc880_five_stack_mixer},
3682 .init_verbs = { alc880_volume_init_verbs,
3683 alc880_pin_5stack_init_verbs },
16ded525
TI
3684 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3685 .dac_nids = alc880_dac_nids,
16ded525
TI
3686 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3687 .channel_mode = alc880_fivestack_modes,
3688 .input_mux = &alc880_capture_source,
3689 },
3690 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3691 .mixers = { alc880_three_stack_mixer,
3692 alc880_five_stack_mixer },
3693 .init_verbs = { alc880_volume_init_verbs,
3694 alc880_pin_5stack_init_verbs },
16ded525
TI
3695 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3696 .dac_nids = alc880_dac_nids,
3697 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3698 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3699 .channel_mode = alc880_fivestack_modes,
3700 .input_mux = &alc880_capture_source,
3701 },
b6482d48
TI
3702 [ALC880_6ST] = {
3703 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3704 .init_verbs = { alc880_volume_init_verbs,
3705 alc880_pin_6stack_init_verbs },
b6482d48
TI
3706 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3707 .dac_nids = alc880_6st_dac_nids,
3708 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3709 .channel_mode = alc880_sixstack_modes,
3710 .input_mux = &alc880_6stack_capture_source,
3711 },
16ded525 3712 [ALC880_6ST_DIG] = {
e9edcee0 3713 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3714 .init_verbs = { alc880_volume_init_verbs,
3715 alc880_pin_6stack_init_verbs },
16ded525
TI
3716 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3717 .dac_nids = alc880_6st_dac_nids,
3718 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3719 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3720 .channel_mode = alc880_sixstack_modes,
3721 .input_mux = &alc880_6stack_capture_source,
3722 },
3723 [ALC880_W810] = {
e9edcee0 3724 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3725 .init_verbs = { alc880_volume_init_verbs,
3726 alc880_pin_w810_init_verbs,
b0af0de5 3727 alc880_gpio2_init_verbs },
16ded525
TI
3728 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3729 .dac_nids = alc880_w810_dac_nids,
3730 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3731 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3732 .channel_mode = alc880_w810_modes,
3733 .input_mux = &alc880_capture_source,
3734 },
3735 [ALC880_Z71V] = {
e9edcee0 3736 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3737 .init_verbs = { alc880_volume_init_verbs,
3738 alc880_pin_z71v_init_verbs },
16ded525
TI
3739 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3740 .dac_nids = alc880_z71v_dac_nids,
3741 .dig_out_nid = ALC880_DIGOUT_NID,
3742 .hp_nid = 0x03,
e9edcee0
TI
3743 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3744 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3745 .input_mux = &alc880_capture_source,
3746 },
3747 [ALC880_F1734] = {
e9edcee0 3748 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3749 .init_verbs = { alc880_volume_init_verbs,
3750 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3751 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3752 .dac_nids = alc880_f1734_dac_nids,
3753 .hp_nid = 0x02,
3754 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3755 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3756 .input_mux = &alc880_f1734_capture_source,
3757 .unsol_event = alc880_uniwill_p53_unsol_event,
3758 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3759 },
3760 [ALC880_ASUS] = {
e9edcee0 3761 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3762 .init_verbs = { alc880_volume_init_verbs,
3763 alc880_pin_asus_init_verbs,
e9edcee0
TI
3764 alc880_gpio1_init_verbs },
3765 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3766 .dac_nids = alc880_asus_dac_nids,
3767 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3768 .channel_mode = alc880_asus_modes,
4e195a7b 3769 .need_dac_fix = 1,
16ded525
TI
3770 .input_mux = &alc880_capture_source,
3771 },
3772 [ALC880_ASUS_DIG] = {
e9edcee0 3773 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3774 .init_verbs = { alc880_volume_init_verbs,
3775 alc880_pin_asus_init_verbs,
e9edcee0
TI
3776 alc880_gpio1_init_verbs },
3777 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3778 .dac_nids = alc880_asus_dac_nids,
16ded525 3779 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3780 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3781 .channel_mode = alc880_asus_modes,
4e195a7b 3782 .need_dac_fix = 1,
16ded525
TI
3783 .input_mux = &alc880_capture_source,
3784 },
df694daa
KY
3785 [ALC880_ASUS_DIG2] = {
3786 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3787 .init_verbs = { alc880_volume_init_verbs,
3788 alc880_pin_asus_init_verbs,
df694daa
KY
3789 alc880_gpio2_init_verbs }, /* use GPIO2 */
3790 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3791 .dac_nids = alc880_asus_dac_nids,
3792 .dig_out_nid = ALC880_DIGOUT_NID,
3793 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3794 .channel_mode = alc880_asus_modes,
4e195a7b 3795 .need_dac_fix = 1,
df694daa
KY
3796 .input_mux = &alc880_capture_source,
3797 },
16ded525 3798 [ALC880_ASUS_W1V] = {
e9edcee0 3799 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3800 .init_verbs = { alc880_volume_init_verbs,
3801 alc880_pin_asus_init_verbs,
e9edcee0
TI
3802 alc880_gpio1_init_verbs },
3803 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3804 .dac_nids = alc880_asus_dac_nids,
16ded525 3805 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3806 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3807 .channel_mode = alc880_asus_modes,
4e195a7b 3808 .need_dac_fix = 1,
16ded525
TI
3809 .input_mux = &alc880_capture_source,
3810 },
3811 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3812 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3813 .init_verbs = { alc880_volume_init_verbs,
3814 alc880_pin_asus_init_verbs },
e9edcee0
TI
3815 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3816 .dac_nids = alc880_asus_dac_nids,
16ded525 3817 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3818 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3819 .channel_mode = alc880_asus_modes,
4e195a7b 3820 .need_dac_fix = 1,
16ded525
TI
3821 .input_mux = &alc880_capture_source,
3822 },
ccc656ce
KY
3823 [ALC880_UNIWILL] = {
3824 .mixers = { alc880_uniwill_mixer },
3825 .init_verbs = { alc880_volume_init_verbs,
3826 alc880_uniwill_init_verbs },
3827 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3828 .dac_nids = alc880_asus_dac_nids,
3829 .dig_out_nid = ALC880_DIGOUT_NID,
3830 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3831 .channel_mode = alc880_threestack_modes,
3832 .need_dac_fix = 1,
3833 .input_mux = &alc880_capture_source,
3834 .unsol_event = alc880_uniwill_unsol_event,
3835 .init_hook = alc880_uniwill_automute,
3836 },
3837 [ALC880_UNIWILL_P53] = {
3838 .mixers = { alc880_uniwill_p53_mixer },
3839 .init_verbs = { alc880_volume_init_verbs,
3840 alc880_uniwill_p53_init_verbs },
3841 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3842 .dac_nids = alc880_asus_dac_nids,
3843 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3844 .channel_mode = alc880_threestack_modes,
3845 .input_mux = &alc880_capture_source,
3846 .unsol_event = alc880_uniwill_p53_unsol_event,
3847 .init_hook = alc880_uniwill_p53_hp_automute,
3848 },
3849 [ALC880_FUJITSU] = {
f12ab1e0 3850 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3851 alc880_pcbeep_mixer, },
3852 .init_verbs = { alc880_volume_init_verbs,
3853 alc880_uniwill_p53_init_verbs,
3854 alc880_beep_init_verbs },
3855 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3856 .dac_nids = alc880_dac_nids,
d53d7d9e 3857 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3858 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3859 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3860 .input_mux = &alc880_capture_source,
3861 .unsol_event = alc880_uniwill_p53_unsol_event,
3862 .init_hook = alc880_uniwill_p53_hp_automute,
3863 },
df694daa
KY
3864 [ALC880_CLEVO] = {
3865 .mixers = { alc880_three_stack_mixer },
3866 .init_verbs = { alc880_volume_init_verbs,
3867 alc880_pin_clevo_init_verbs },
3868 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3869 .dac_nids = alc880_dac_nids,
3870 .hp_nid = 0x03,
3871 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3872 .channel_mode = alc880_threestack_modes,
4e195a7b 3873 .need_dac_fix = 1,
df694daa
KY
3874 .input_mux = &alc880_capture_source,
3875 },
ae6b813a
TI
3876 [ALC880_LG] = {
3877 .mixers = { alc880_lg_mixer },
3878 .init_verbs = { alc880_volume_init_verbs,
3879 alc880_lg_init_verbs },
3880 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3881 .dac_nids = alc880_lg_dac_nids,
3882 .dig_out_nid = ALC880_DIGOUT_NID,
3883 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3884 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3885 .need_dac_fix = 1,
ae6b813a
TI
3886 .input_mux = &alc880_lg_capture_source,
3887 .unsol_event = alc880_lg_unsol_event,
3888 .init_hook = alc880_lg_automute,
cb53c626
TI
3889#ifdef CONFIG_SND_HDA_POWER_SAVE
3890 .loopbacks = alc880_lg_loopbacks,
3891#endif
ae6b813a 3892 },
d681518a
TI
3893 [ALC880_LG_LW] = {
3894 .mixers = { alc880_lg_lw_mixer },
3895 .init_verbs = { alc880_volume_init_verbs,
3896 alc880_lg_lw_init_verbs },
0a8c5da3 3897 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3898 .dac_nids = alc880_dac_nids,
3899 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3900 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3901 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3902 .input_mux = &alc880_lg_lw_capture_source,
3903 .unsol_event = alc880_lg_lw_unsol_event,
3904 .init_hook = alc880_lg_lw_automute,
3905 },
df99cd33
TI
3906 [ALC880_MEDION_RIM] = {
3907 .mixers = { alc880_medion_rim_mixer },
3908 .init_verbs = { alc880_volume_init_verbs,
3909 alc880_medion_rim_init_verbs,
3910 alc_gpio2_init_verbs },
3911 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3912 .dac_nids = alc880_dac_nids,
3913 .dig_out_nid = ALC880_DIGOUT_NID,
3914 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3915 .channel_mode = alc880_2_jack_modes,
3916 .input_mux = &alc880_medion_rim_capture_source,
3917 .unsol_event = alc880_medion_rim_unsol_event,
3918 .init_hook = alc880_medion_rim_automute,
3919 },
16ded525
TI
3920#ifdef CONFIG_SND_DEBUG
3921 [ALC880_TEST] = {
e9edcee0
TI
3922 .mixers = { alc880_test_mixer },
3923 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3924 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3925 .dac_nids = alc880_test_dac_nids,
3926 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3927 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3928 .channel_mode = alc880_test_modes,
3929 .input_mux = &alc880_test_capture_source,
3930 },
3931#endif
3932};
3933
e9edcee0
TI
3934/*
3935 * Automatic parse of I/O pins from the BIOS configuration
3936 */
3937
e9edcee0
TI
3938enum {
3939 ALC_CTL_WIDGET_VOL,
3940 ALC_CTL_WIDGET_MUTE,
3941 ALC_CTL_BIND_MUTE,
3942};
c8b6bf9b 3943static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3944 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3945 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3946 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3947};
3948
3949/* add dynamic controls */
f12ab1e0
TI
3950static int add_control(struct alc_spec *spec, int type, const char *name,
3951 unsigned long val)
e9edcee0 3952{
c8b6bf9b 3953 struct snd_kcontrol_new *knew;
e9edcee0 3954
603c4019
TI
3955 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3956 knew = snd_array_new(&spec->kctls);
3957 if (!knew)
3958 return -ENOMEM;
e9edcee0 3959 *knew = alc880_control_templates[type];
543537bd 3960 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3961 if (!knew->name)
e9edcee0
TI
3962 return -ENOMEM;
3963 knew->private_value = val;
e9edcee0
TI
3964 return 0;
3965}
3966
3967#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3968#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3969#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3970#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3971#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3972#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3973#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3974#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3975#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3976#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3977#define ALC880_PIN_CD_NID 0x1c
3978
3979/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3980static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3981 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3982{
3983 hda_nid_t nid;
3984 int assigned[4];
3985 int i, j;
3986
3987 memset(assigned, 0, sizeof(assigned));
b0af0de5 3988 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3989
3990 /* check the pins hardwired to audio widget */
3991 for (i = 0; i < cfg->line_outs; i++) {
3992 nid = cfg->line_out_pins[i];
3993 if (alc880_is_fixed_pin(nid)) {
3994 int idx = alc880_fixed_pin_idx(nid);
5014f193 3995 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3996 assigned[idx] = 1;
3997 }
3998 }
3999 /* left pins can be connect to any audio widget */
4000 for (i = 0; i < cfg->line_outs; i++) {
4001 nid = cfg->line_out_pins[i];
4002 if (alc880_is_fixed_pin(nid))
4003 continue;
4004 /* search for an empty channel */
4005 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4006 if (!assigned[j]) {
4007 spec->multiout.dac_nids[i] =
4008 alc880_idx_to_dac(j);
e9edcee0
TI
4009 assigned[j] = 1;
4010 break;
4011 }
4012 }
4013 }
4014 spec->multiout.num_dacs = cfg->line_outs;
4015 return 0;
4016}
4017
4018/* add playback controls from the parsed DAC table */
df694daa
KY
4019static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4020 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4021{
4022 char name[32];
f12ab1e0
TI
4023 static const char *chname[4] = {
4024 "Front", "Surround", NULL /*CLFE*/, "Side"
4025 };
e9edcee0
TI
4026 hda_nid_t nid;
4027 int i, err;
4028
4029 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4030 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4031 continue;
4032 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4033 if (i == 2) {
4034 /* Center/LFE */
f12ab1e0
TI
4035 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4036 "Center Playback Volume",
4037 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4038 HDA_OUTPUT));
4039 if (err < 0)
e9edcee0 4040 return err;
f12ab1e0
TI
4041 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4042 "LFE Playback Volume",
4043 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4044 HDA_OUTPUT));
4045 if (err < 0)
e9edcee0 4046 return err;
f12ab1e0
TI
4047 err = add_control(spec, ALC_CTL_BIND_MUTE,
4048 "Center Playback Switch",
4049 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4050 HDA_INPUT));
4051 if (err < 0)
e9edcee0 4052 return err;
f12ab1e0
TI
4053 err = add_control(spec, ALC_CTL_BIND_MUTE,
4054 "LFE Playback Switch",
4055 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4056 HDA_INPUT));
4057 if (err < 0)
e9edcee0
TI
4058 return err;
4059 } else {
4060 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
4061 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4062 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4063 HDA_OUTPUT));
4064 if (err < 0)
e9edcee0
TI
4065 return err;
4066 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
4067 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4068 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4069 HDA_INPUT));
4070 if (err < 0)
e9edcee0
TI
4071 return err;
4072 }
4073 }
e9edcee0
TI
4074 return 0;
4075}
4076
8d88bc3d
TI
4077/* add playback controls for speaker and HP outputs */
4078static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4079 const char *pfx)
e9edcee0
TI
4080{
4081 hda_nid_t nid;
4082 int err;
8d88bc3d 4083 char name[32];
e9edcee0 4084
f12ab1e0 4085 if (!pin)
e9edcee0
TI
4086 return 0;
4087
4088 if (alc880_is_fixed_pin(pin)) {
4089 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4090 /* specify the DAC as the extra output */
f12ab1e0 4091 if (!spec->multiout.hp_nid)
e9edcee0 4092 spec->multiout.hp_nid = nid;
82bc955f
TI
4093 else
4094 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4095 /* control HP volume/switch on the output mixer amp */
4096 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 4097 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
4098 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4099 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4100 if (err < 0)
e9edcee0 4101 return err;
8d88bc3d 4102 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4103 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4104 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4105 if (err < 0)
e9edcee0
TI
4106 return err;
4107 } else if (alc880_is_multi_pin(pin)) {
4108 /* set manual connection */
e9edcee0 4109 /* we have only a switch on HP-out PIN */
8d88bc3d 4110 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4111 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4112 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4113 if (err < 0)
e9edcee0
TI
4114 return err;
4115 }
4116 return 0;
4117}
4118
4119/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4120static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4121 const char *ctlname,
df694daa 4122 int idx, hda_nid_t mix_nid)
e9edcee0
TI
4123{
4124 char name[32];
df694daa 4125 int err;
e9edcee0
TI
4126
4127 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
4128 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4129 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4130 if (err < 0)
e9edcee0
TI
4131 return err;
4132 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
4133 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4134 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4135 if (err < 0)
e9edcee0
TI
4136 return err;
4137 return 0;
4138}
4139
4140/* create playback/capture controls for input pins */
df694daa
KY
4141static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4142 const struct auto_pin_cfg *cfg)
e9edcee0 4143{
61b9b9b1 4144 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4145 int i, err, idx;
e9edcee0
TI
4146
4147 for (i = 0; i < AUTO_PIN_LAST; i++) {
4148 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 4149 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
4150 err = new_analog_input(spec, cfg->input_pins[i],
4151 auto_pin_cfg_labels[i],
df694daa 4152 idx, 0x0b);
e9edcee0
TI
4153 if (err < 0)
4154 return err;
f12ab1e0
TI
4155 imux->items[imux->num_items].label =
4156 auto_pin_cfg_labels[i];
4157 imux->items[imux->num_items].index =
4158 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
4159 imux->num_items++;
4160 }
4161 }
4162 return 0;
4163}
4164
f6c7e546
TI
4165static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4166 unsigned int pin_type)
4167{
4168 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4169 pin_type);
4170 /* unmute pin */
d260cdf6
TI
4171 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4172 AMP_OUT_UNMUTE);
f6c7e546
TI
4173}
4174
df694daa
KY
4175static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4176 hda_nid_t nid, int pin_type,
e9edcee0
TI
4177 int dac_idx)
4178{
f6c7e546 4179 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4180 /* need the manual connection? */
4181 if (alc880_is_multi_pin(nid)) {
4182 struct alc_spec *spec = codec->spec;
4183 int idx = alc880_multi_pin_idx(nid);
4184 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4185 AC_VERB_SET_CONNECT_SEL,
4186 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4187 }
4188}
4189
baba8ee9
TI
4190static int get_pin_type(int line_out_type)
4191{
4192 if (line_out_type == AUTO_PIN_HP_OUT)
4193 return PIN_HP;
4194 else
4195 return PIN_OUT;
4196}
4197
e9edcee0
TI
4198static void alc880_auto_init_multi_out(struct hda_codec *codec)
4199{
4200 struct alc_spec *spec = codec->spec;
4201 int i;
ea1fb29a 4202
bc9f98a9 4203 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
4204 for (i = 0; i < spec->autocfg.line_outs; i++) {
4205 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4206 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4207 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4208 }
4209}
4210
8d88bc3d 4211static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4212{
4213 struct alc_spec *spec = codec->spec;
4214 hda_nid_t pin;
4215
82bc955f 4216 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4217 if (pin) /* connect to front */
4218 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4219 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4220 if (pin) /* connect to front */
4221 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4222}
4223
4224static void alc880_auto_init_analog_input(struct hda_codec *codec)
4225{
4226 struct alc_spec *spec = codec->spec;
4227 int i;
4228
4229 for (i = 0; i < AUTO_PIN_LAST; i++) {
4230 hda_nid_t nid = spec->autocfg.input_pins[i];
4231 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
4232 snd_hda_codec_write(codec, nid, 0,
4233 AC_VERB_SET_PIN_WIDGET_CONTROL,
4234 i <= AUTO_PIN_FRONT_MIC ?
4235 PIN_VREF80 : PIN_IN);
e9edcee0 4236 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
4237 snd_hda_codec_write(codec, nid, 0,
4238 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4239 AMP_OUT_MUTE);
4240 }
4241 }
4242}
4243
4244/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4245/* return 1 if successful, 0 if the proper config is not found,
4246 * or a negative error code
4247 */
e9edcee0
TI
4248static int alc880_parse_auto_config(struct hda_codec *codec)
4249{
4250 struct alc_spec *spec = codec->spec;
4251 int err;
df694daa 4252 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4253
f12ab1e0
TI
4254 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4255 alc880_ignore);
4256 if (err < 0)
e9edcee0 4257 return err;
f12ab1e0 4258 if (!spec->autocfg.line_outs)
e9edcee0 4259 return 0; /* can't find valid BIOS pin config */
df694daa 4260
f12ab1e0
TI
4261 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4262 if (err < 0)
4263 return err;
4264 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4265 if (err < 0)
4266 return err;
4267 err = alc880_auto_create_extra_out(spec,
4268 spec->autocfg.speaker_pins[0],
4269 "Speaker");
4270 if (err < 0)
4271 return err;
4272 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4273 "Headphone");
4274 if (err < 0)
4275 return err;
4276 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4277 if (err < 0)
e9edcee0
TI
4278 return err;
4279
4280 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4281
4282 if (spec->autocfg.dig_out_pin)
4283 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
4284 if (spec->autocfg.dig_in_pin)
4285 spec->dig_in_nid = ALC880_DIGIN_NID;
4286
603c4019 4287 if (spec->kctls.list)
d88897ea 4288 add_mixer(spec, spec->kctls.list);
e9edcee0 4289
d88897ea 4290 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4291
a1e8d2da 4292 spec->num_mux_defs = 1;
61b9b9b1 4293 spec->input_mux = &spec->private_imux[0];
e9edcee0 4294
e044c39a 4295 store_pin_configs(codec);
e9edcee0
TI
4296 return 1;
4297}
4298
ae6b813a
TI
4299/* additional initialization for auto-configuration model */
4300static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4301{
f6c7e546 4302 struct alc_spec *spec = codec->spec;
e9edcee0 4303 alc880_auto_init_multi_out(codec);
8d88bc3d 4304 alc880_auto_init_extra_out(codec);
e9edcee0 4305 alc880_auto_init_analog_input(codec);
f6c7e546 4306 if (spec->unsol_event)
7fb0d78f 4307 alc_inithook(codec);
e9edcee0
TI
4308}
4309
4310/*
4311 * OK, here we have finally the patch for ALC880
4312 */
4313
f9e336f6
TI
4314static void set_capture_mixer(struct alc_spec *spec)
4315{
4316 static struct snd_kcontrol_new *caps[3] = {
4317 alc_capture_mixer1,
4318 alc_capture_mixer2,
4319 alc_capture_mixer3,
4320 };
30d72e9f 4321 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3)
f9e336f6
TI
4322 spec->cap_mixer = caps[spec->num_adc_nids - 1];
4323}
4324
1da177e4
LT
4325static int patch_alc880(struct hda_codec *codec)
4326{
4327 struct alc_spec *spec;
4328 int board_config;
df694daa 4329 int err;
1da177e4 4330
e560d8d8 4331 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
4332 if (spec == NULL)
4333 return -ENOMEM;
4334
4335 codec->spec = spec;
4336
f5fcc13c
TI
4337 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4338 alc880_models,
4339 alc880_cfg_tbl);
4340 if (board_config < 0) {
9c7f852e
TI
4341 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4342 "trying auto-probe from BIOS...\n");
e9edcee0 4343 board_config = ALC880_AUTO;
1da177e4 4344 }
1da177e4 4345
e9edcee0
TI
4346 if (board_config == ALC880_AUTO) {
4347 /* automatic parse from the BIOS config */
4348 err = alc880_parse_auto_config(codec);
4349 if (err < 0) {
4350 alc_free(codec);
4351 return err;
f12ab1e0 4352 } else if (!err) {
9c7f852e
TI
4353 printk(KERN_INFO
4354 "hda_codec: Cannot set up configuration "
4355 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
4356 board_config = ALC880_3ST;
4357 }
1da177e4
LT
4358 }
4359
680cd536
KK
4360 err = snd_hda_attach_beep_device(codec, 0x1);
4361 if (err < 0) {
4362 alc_free(codec);
4363 return err;
4364 }
4365
df694daa
KY
4366 if (board_config != ALC880_AUTO)
4367 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
4368
4369 spec->stream_name_analog = "ALC880 Analog";
4370 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4371 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 4372 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
4373
4374 spec->stream_name_digital = "ALC880 Digital";
4375 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4376 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4377
f12ab1e0 4378 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 4379 /* check whether NID 0x07 is valid */
54d17403 4380 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
4381 /* get type */
4382 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
4383 if (wcap != AC_WID_AUD_IN) {
4384 spec->adc_nids = alc880_adc_nids_alt;
4385 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
4386 } else {
4387 spec->adc_nids = alc880_adc_nids;
4388 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
4389 }
4390 }
f9e336f6 4391 set_capture_mixer(spec);
1da177e4 4392
2134ea4f
TI
4393 spec->vmaster_nid = 0x0c;
4394
1da177e4 4395 codec->patch_ops = alc_patch_ops;
e9edcee0 4396 if (board_config == ALC880_AUTO)
ae6b813a 4397 spec->init_hook = alc880_auto_init;
cb53c626
TI
4398#ifdef CONFIG_SND_HDA_POWER_SAVE
4399 if (!spec->loopback.amplist)
4400 spec->loopback.amplist = alc880_loopbacks;
4401#endif
daead538 4402 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
4403
4404 return 0;
4405}
4406
e9edcee0 4407
1da177e4
LT
4408/*
4409 * ALC260 support
4410 */
4411
e9edcee0
TI
4412static hda_nid_t alc260_dac_nids[1] = {
4413 /* front */
4414 0x02,
4415};
4416
4417static hda_nid_t alc260_adc_nids[1] = {
4418 /* ADC0 */
4419 0x04,
4420};
4421
df694daa 4422static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
4423 /* ADC1 */
4424 0x05,
4425};
4426
d57fdac0
JW
4427/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4428 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4429 */
4430static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
4431 /* ADC0, ADC1 */
4432 0x04, 0x05
4433};
4434
e9edcee0
TI
4435#define ALC260_DIGOUT_NID 0x03
4436#define ALC260_DIGIN_NID 0x06
4437
4438static struct hda_input_mux alc260_capture_source = {
4439 .num_items = 4,
4440 .items = {
4441 { "Mic", 0x0 },
4442 { "Front Mic", 0x1 },
4443 { "Line", 0x2 },
4444 { "CD", 0x4 },
4445 },
4446};
4447
17e7aec6 4448/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
4449 * headphone jack and the internal CD lines since these are the only pins at
4450 * which audio can appear. For flexibility, also allow the option of
4451 * recording the mixer output on the second ADC (ADC0 doesn't have a
4452 * connection to the mixer output).
a9430dd8 4453 */
a1e8d2da
JW
4454static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4455 {
4456 .num_items = 3,
4457 .items = {
4458 { "Mic/Line", 0x0 },
4459 { "CD", 0x4 },
4460 { "Headphone", 0x2 },
4461 },
a9430dd8 4462 },
a1e8d2da
JW
4463 {
4464 .num_items = 4,
4465 .items = {
4466 { "Mic/Line", 0x0 },
4467 { "CD", 0x4 },
4468 { "Headphone", 0x2 },
4469 { "Mixer", 0x5 },
4470 },
4471 },
4472
a9430dd8
JW
4473};
4474
a1e8d2da
JW
4475/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4476 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 4477 */
a1e8d2da
JW
4478static struct hda_input_mux alc260_acer_capture_sources[2] = {
4479 {
4480 .num_items = 4,
4481 .items = {
4482 { "Mic", 0x0 },
4483 { "Line", 0x2 },
4484 { "CD", 0x4 },
4485 { "Headphone", 0x5 },
4486 },
4487 },
4488 {
4489 .num_items = 5,
4490 .items = {
4491 { "Mic", 0x0 },
4492 { "Line", 0x2 },
4493 { "CD", 0x4 },
4494 { "Headphone", 0x6 },
4495 { "Mixer", 0x5 },
4496 },
0bfc90e9
JW
4497 },
4498};
1da177e4
LT
4499/*
4500 * This is just place-holder, so there's something for alc_build_pcms to look
4501 * at when it calculates the maximum number of channels. ALC260 has no mixer
4502 * element which allows changing the channel mode, so the verb list is
4503 * never used.
4504 */
d2a6d7dc 4505static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
4506 { 2, NULL },
4507};
4508
df694daa
KY
4509
4510/* Mixer combinations
4511 *
4512 * basic: base_output + input + pc_beep + capture
4513 * HP: base_output + input + capture_alt
4514 * HP_3013: hp_3013 + input + capture
4515 * fujitsu: fujitsu + capture
0bfc90e9 4516 * acer: acer + capture
df694daa
KY
4517 */
4518
4519static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 4520 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4521 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 4522 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 4523 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 4524 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 4525 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 4526 { } /* end */
f12ab1e0 4527};
1da177e4 4528
df694daa 4529static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
4530 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4531 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4532 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4533 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4535 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4536 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4537 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
4538 { } /* end */
4539};
4540
4541static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4542 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4543 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4544 { } /* end */
4545};
4546
bec15c3a
TI
4547/* update HP, line and mono out pins according to the master switch */
4548static void alc260_hp_master_update(struct hda_codec *codec,
4549 hda_nid_t hp, hda_nid_t line,
4550 hda_nid_t mono)
4551{
4552 struct alc_spec *spec = codec->spec;
4553 unsigned int val = spec->master_sw ? PIN_HP : 0;
4554 /* change HP and line-out pins */
30cde0aa 4555 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 4556 val);
30cde0aa 4557 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4558 val);
4559 /* mono (speaker) depending on the HP jack sense */
4560 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 4561 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4562 val);
4563}
4564
4565static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4566 struct snd_ctl_elem_value *ucontrol)
4567{
4568 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4569 struct alc_spec *spec = codec->spec;
4570 *ucontrol->value.integer.value = spec->master_sw;
4571 return 0;
4572}
4573
4574static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4575 struct snd_ctl_elem_value *ucontrol)
4576{
4577 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4578 struct alc_spec *spec = codec->spec;
4579 int val = !!*ucontrol->value.integer.value;
4580 hda_nid_t hp, line, mono;
4581
4582 if (val == spec->master_sw)
4583 return 0;
4584 spec->master_sw = val;
4585 hp = (kcontrol->private_value >> 16) & 0xff;
4586 line = (kcontrol->private_value >> 8) & 0xff;
4587 mono = kcontrol->private_value & 0xff;
4588 alc260_hp_master_update(codec, hp, line, mono);
4589 return 1;
4590}
4591
4592static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4593 {
4594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4595 .name = "Master Playback Switch",
4596 .info = snd_ctl_boolean_mono_info,
4597 .get = alc260_hp_master_sw_get,
4598 .put = alc260_hp_master_sw_put,
4599 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4600 },
4601 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4602 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4603 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4604 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4605 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4606 HDA_OUTPUT),
4607 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4608 { } /* end */
4609};
4610
4611static struct hda_verb alc260_hp_unsol_verbs[] = {
4612 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4613 {},
4614};
4615
4616static void alc260_hp_automute(struct hda_codec *codec)
4617{
4618 struct alc_spec *spec = codec->spec;
4619 unsigned int present;
4620
4621 present = snd_hda_codec_read(codec, 0x10, 0,
4622 AC_VERB_GET_PIN_SENSE, 0);
4623 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4624 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4625}
4626
4627static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4628{
4629 if ((res >> 26) == ALC880_HP_EVENT)
4630 alc260_hp_automute(codec);
4631}
4632
df694daa 4633static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
4634 {
4635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4636 .name = "Master Playback Switch",
4637 .info = snd_ctl_boolean_mono_info,
4638 .get = alc260_hp_master_sw_get,
4639 .put = alc260_hp_master_sw_put,
30cde0aa 4640 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 4641 },
df694daa
KY
4642 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4643 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4644 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4645 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4646 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4647 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
4648 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4649 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
4650 { } /* end */
4651};
4652
3f878308
KY
4653static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4654 .ops = &snd_hda_bind_vol,
4655 .values = {
4656 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4657 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4658 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4659 0
4660 },
4661};
4662
4663static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4664 .ops = &snd_hda_bind_sw,
4665 .values = {
4666 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4667 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4668 0
4669 },
4670};
4671
4672static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4673 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4674 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4675 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4676 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4677 { } /* end */
4678};
4679
bec15c3a
TI
4680static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4681 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4682 {},
4683};
4684
4685static void alc260_hp_3013_automute(struct hda_codec *codec)
4686{
4687 struct alc_spec *spec = codec->spec;
4688 unsigned int present;
4689
4690 present = snd_hda_codec_read(codec, 0x15, 0,
4691 AC_VERB_GET_PIN_SENSE, 0);
4692 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
30cde0aa 4693 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
4694}
4695
4696static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4697 unsigned int res)
4698{
4699 if ((res >> 26) == ALC880_HP_EVENT)
4700 alc260_hp_3013_automute(codec);
4701}
4702
3f878308
KY
4703static void alc260_hp_3012_automute(struct hda_codec *codec)
4704{
4705 unsigned int present, bits;
4706
4707 present = snd_hda_codec_read(codec, 0x10, 0,
4708 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4709
4710 bits = present ? 0 : PIN_OUT;
4711 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4712 bits);
4713 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4714 bits);
4715 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4716 bits);
4717}
4718
4719static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4720 unsigned int res)
4721{
4722 if ((res >> 26) == ALC880_HP_EVENT)
4723 alc260_hp_3012_automute(codec);
4724}
4725
4726/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
4727 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4728 */
c8b6bf9b 4729static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 4730 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4731 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 4732 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
4733 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4734 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4735 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4736 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4737 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
4738 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4739 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
31bffaa9
TI
4740 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4741 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4742 { } /* end */
4743};
4744
a1e8d2da
JW
4745/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4746 * versions of the ALC260 don't act on requests to enable mic bias from NID
4747 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4748 * datasheet doesn't mention this restriction. At this stage it's not clear
4749 * whether this behaviour is intentional or is a hardware bug in chip
4750 * revisions available in early 2006. Therefore for now allow the
4751 * "Headphone Jack Mode" control to span all choices, but if it turns out
4752 * that the lack of mic bias for this NID is intentional we could change the
4753 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4754 *
4755 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4756 * don't appear to make the mic bias available from the "line" jack, even
4757 * though the NID used for this jack (0x14) can supply it. The theory is
4758 * that perhaps Acer have included blocking capacitors between the ALC260
4759 * and the output jack. If this turns out to be the case for all such
4760 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4761 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4762 *
4763 * The C20x Tablet series have a mono internal speaker which is controlled
4764 * via the chip's Mono sum widget and pin complex, so include the necessary
4765 * controls for such models. On models without a "mono speaker" the control
4766 * won't do anything.
a1e8d2da 4767 */
0bfc90e9
JW
4768static struct snd_kcontrol_new alc260_acer_mixer[] = {
4769 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4770 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4771 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4772 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4773 HDA_OUTPUT),
31bffaa9 4774 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4775 HDA_INPUT),
0bfc90e9
JW
4776 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4777 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4778 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4779 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4780 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4781 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4782 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4783 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4784 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4785 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4786 { } /* end */
4787};
4788
bc9f98a9
KY
4789/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4790 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4791 */
4792static struct snd_kcontrol_new alc260_will_mixer[] = {
4793 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4794 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4796 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4797 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4798 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4799 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4800 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4801 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4802 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4803 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4804 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4805 { } /* end */
4806};
4807
4808/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4809 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4810 */
4811static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4812 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4813 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4815 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4816 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4817 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4818 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4819 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4820 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4821 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4822 { } /* end */
4823};
4824
df694daa
KY
4825/*
4826 * initialization verbs
4827 */
1da177e4
LT
4828static struct hda_verb alc260_init_verbs[] = {
4829 /* Line In pin widget for input */
05acb863 4830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4831 /* CD pin widget for input */
05acb863 4832 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4833 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4834 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4835 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4836 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4837 /* LINE-2 is used for line-out in rear */
05acb863 4838 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4839 /* select line-out */
fd56f2db 4840 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4841 /* LINE-OUT pin */
05acb863 4842 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4843 /* enable HP */
05acb863 4844 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4845 /* enable Mono */
05acb863
TI
4846 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4847 /* mute capture amp left and right */
16ded525 4848 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4849 /* set connection select to line in (default select for this ADC) */
4850 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4851 /* mute capture amp left and right */
4852 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4853 /* set connection select to line in (default select for this ADC) */
4854 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4855 /* set vol=0 Line-Out mixer amp left and right */
4856 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4857 /* unmute pin widget amp left and right (no gain on this amp) */
4858 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4859 /* set vol=0 HP mixer amp left and right */
4860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4861 /* unmute pin widget amp left and right (no gain on this amp) */
4862 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4863 /* set vol=0 Mono mixer amp left and right */
4864 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4865 /* unmute pin widget amp left and right (no gain on this amp) */
4866 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4867 /* unmute LINE-2 out pin */
4868 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4869 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4870 * Line In 2 = 0x03
4871 */
cb53c626
TI
4872 /* mute analog inputs */
4873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4878 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4879 /* mute Front out path */
4880 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4881 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4882 /* mute Headphone out path */
4883 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4884 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4885 /* mute Mono out path */
4886 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4887 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4888 { }
4889};
4890
474167d6 4891#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4892static struct hda_verb alc260_hp_init_verbs[] = {
4893 /* Headphone and output */
4894 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4895 /* mono output */
4896 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4897 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4898 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4899 /* Mic2 (front panel) pin widget for input and vref at 80% */
4900 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4901 /* Line In pin widget for input */
4902 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4903 /* Line-2 pin widget for output */
4904 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4905 /* CD pin widget for input */
4906 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4907 /* unmute amp left and right */
4908 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4909 /* set connection select to line in (default select for this ADC) */
4910 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4911 /* unmute Line-Out mixer amp left and right (volume = 0) */
4912 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4913 /* mute pin widget amp left and right (no gain on this amp) */
4914 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4915 /* unmute HP mixer amp left and right (volume = 0) */
4916 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4917 /* mute pin widget amp left and right (no gain on this amp) */
4918 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4919 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4920 * Line In 2 = 0x03
4921 */
cb53c626
TI
4922 /* mute analog inputs */
4923 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4924 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4925 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4926 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4927 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4928 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4929 /* Unmute Front out path */
4930 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4931 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4932 /* Unmute Headphone out path */
4933 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4934 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4935 /* Unmute Mono out path */
4936 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4937 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4938 { }
4939};
474167d6 4940#endif
df694daa
KY
4941
4942static struct hda_verb alc260_hp_3013_init_verbs[] = {
4943 /* Line out and output */
4944 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4945 /* mono output */
4946 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4947 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4948 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4949 /* Mic2 (front panel) pin widget for input and vref at 80% */
4950 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4951 /* Line In pin widget for input */
4952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4953 /* Headphone pin widget for output */
4954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4955 /* CD pin widget for input */
4956 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4957 /* unmute amp left and right */
4958 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4959 /* set connection select to line in (default select for this ADC) */
4960 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4961 /* unmute Line-Out mixer amp left and right (volume = 0) */
4962 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4963 /* mute pin widget amp left and right (no gain on this amp) */
4964 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4965 /* unmute HP mixer amp left and right (volume = 0) */
4966 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4967 /* mute pin widget amp left and right (no gain on this amp) */
4968 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4969 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4970 * Line In 2 = 0x03
4971 */
cb53c626
TI
4972 /* mute analog inputs */
4973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4976 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4977 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4978 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4979 /* Unmute Front out path */
4980 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4981 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4982 /* Unmute Headphone out path */
4983 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4984 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4985 /* Unmute Mono out path */
4986 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4987 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4988 { }
4989};
4990
a9430dd8 4991/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4992 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4993 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4994 */
4995static struct hda_verb alc260_fujitsu_init_verbs[] = {
4996 /* Disable all GPIOs */
4997 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4998 /* Internal speaker is connected to headphone pin */
4999 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5000 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5002 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5003 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5004 /* Ensure all other unused pins are disabled and muted. */
5005 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5006 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5007 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5008 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5009 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5010 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5011 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5013
5014 /* Disable digital (SPDIF) pins */
5015 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5016 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5017
ea1fb29a 5018 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5019 * when acting as an output.
5020 */
5021 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5022
f7ace40d 5023 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5025 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5026 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5027 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5028 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5029 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5030 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5031 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5032 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5033
f7ace40d
JW
5034 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5035 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5036 /* Unmute Line1 pin widget output buffer since it starts as an output.
5037 * If the pin mode is changed by the user the pin mode control will
5038 * take care of enabling the pin's input/output buffers as needed.
5039 * Therefore there's no need to enable the input buffer at this
5040 * stage.
cdcd9268 5041 */
f7ace40d 5042 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5043 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5044 * mixer ctrl)
5045 */
f7ace40d
JW
5046 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5047
5048 /* Mute capture amp left and right */
5049 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5050 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5051 * in (on mic1 pin)
5052 */
5053 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5054
5055 /* Do the same for the second ADC: mute capture input amp and
5056 * set ADC connection to line in (on mic1 pin)
5057 */
5058 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5059 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5060
5061 /* Mute all inputs to mixer widget (even unconnected ones) */
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5063 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5064 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5070
5071 { }
a9430dd8
JW
5072};
5073
0bfc90e9
JW
5074/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5075 * similar laptops (adapted from Fujitsu init verbs).
5076 */
5077static struct hda_verb alc260_acer_init_verbs[] = {
5078 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5079 * the headphone jack. Turn this on and rely on the standard mute
5080 * methods whenever the user wants to turn these outputs off.
5081 */
5082 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5083 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5084 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5085 /* Internal speaker/Headphone jack is connected to Line-out pin */
5086 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5087 /* Internal microphone/Mic jack is connected to Mic1 pin */
5088 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5089 /* Line In jack is connected to Line1 pin */
5090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5091 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5092 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5093 /* Ensure all other unused pins are disabled and muted. */
5094 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5095 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5096 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5097 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5098 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5100 /* Disable digital (SPDIF) pins */
5101 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5102 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5103
ea1fb29a 5104 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5105 * bus when acting as outputs.
5106 */
5107 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5108 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5109
5110 /* Start with output sum widgets muted and their output gains at min */
5111 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5112 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5113 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5114 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5115 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5116 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5117 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5118 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5119 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5120
f12ab1e0
TI
5121 /* Unmute Line-out pin widget amp left and right
5122 * (no equiv mixer ctrl)
5123 */
0bfc90e9 5124 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5125 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5126 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5127 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5128 * inputs. If the pin mode is changed by the user the pin mode control
5129 * will take care of enabling the pin's input/output buffers as needed.
5130 * Therefore there's no need to enable the input buffer at this
5131 * stage.
5132 */
5133 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5135
5136 /* Mute capture amp left and right */
5137 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5138 /* Set ADC connection select to match default mixer setting - mic
5139 * (on mic1 pin)
5140 */
5141 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5142
5143 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5144 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5145 */
5146 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5147 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5148
5149 /* Mute all inputs to mixer widget (even unconnected ones) */
5150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5156 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5158
5159 { }
5160};
5161
bc9f98a9
KY
5162static struct hda_verb alc260_will_verbs[] = {
5163 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5164 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5165 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5166 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5167 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5168 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5169 {}
5170};
5171
5172static struct hda_verb alc260_replacer_672v_verbs[] = {
5173 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5174 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5175 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5176
5177 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5178 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5179 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5180
5181 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5182 {}
5183};
5184
5185/* toggle speaker-output according to the hp-jack state */
5186static void alc260_replacer_672v_automute(struct hda_codec *codec)
5187{
5188 unsigned int present;
5189
5190 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5191 present = snd_hda_codec_read(codec, 0x0f, 0,
5192 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5193 if (present) {
82beb8fd
TI
5194 snd_hda_codec_write_cache(codec, 0x01, 0,
5195 AC_VERB_SET_GPIO_DATA, 1);
5196 snd_hda_codec_write_cache(codec, 0x0f, 0,
5197 AC_VERB_SET_PIN_WIDGET_CONTROL,
5198 PIN_HP);
bc9f98a9 5199 } else {
82beb8fd
TI
5200 snd_hda_codec_write_cache(codec, 0x01, 0,
5201 AC_VERB_SET_GPIO_DATA, 0);
5202 snd_hda_codec_write_cache(codec, 0x0f, 0,
5203 AC_VERB_SET_PIN_WIDGET_CONTROL,
5204 PIN_OUT);
bc9f98a9
KY
5205 }
5206}
5207
5208static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5209 unsigned int res)
5210{
5211 if ((res >> 26) == ALC880_HP_EVENT)
5212 alc260_replacer_672v_automute(codec);
5213}
5214
3f878308
KY
5215static struct hda_verb alc260_hp_dc7600_verbs[] = {
5216 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5217 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5218 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5219 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5220 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5222 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5223 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5224 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5225 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5226 {}
5227};
5228
7cf51e48
JW
5229/* Test configuration for debugging, modelled after the ALC880 test
5230 * configuration.
5231 */
5232#ifdef CONFIG_SND_DEBUG
5233static hda_nid_t alc260_test_dac_nids[1] = {
5234 0x02,
5235};
5236static hda_nid_t alc260_test_adc_nids[2] = {
5237 0x04, 0x05,
5238};
a1e8d2da 5239/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 5240 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 5241 * is NID 0x04.
17e7aec6 5242 */
a1e8d2da
JW
5243static struct hda_input_mux alc260_test_capture_sources[2] = {
5244 {
5245 .num_items = 7,
5246 .items = {
5247 { "MIC1 pin", 0x0 },
5248 { "MIC2 pin", 0x1 },
5249 { "LINE1 pin", 0x2 },
5250 { "LINE2 pin", 0x3 },
5251 { "CD pin", 0x4 },
5252 { "LINE-OUT pin", 0x5 },
5253 { "HP-OUT pin", 0x6 },
5254 },
5255 },
5256 {
5257 .num_items = 8,
5258 .items = {
5259 { "MIC1 pin", 0x0 },
5260 { "MIC2 pin", 0x1 },
5261 { "LINE1 pin", 0x2 },
5262 { "LINE2 pin", 0x3 },
5263 { "CD pin", 0x4 },
5264 { "Mixer", 0x5 },
5265 { "LINE-OUT pin", 0x6 },
5266 { "HP-OUT pin", 0x7 },
5267 },
7cf51e48
JW
5268 },
5269};
5270static struct snd_kcontrol_new alc260_test_mixer[] = {
5271 /* Output driver widgets */
5272 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5273 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5274 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5275 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5276 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5277 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5278
a1e8d2da
JW
5279 /* Modes for retasking pin widgets
5280 * Note: the ALC260 doesn't seem to act on requests to enable mic
5281 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5282 * mention this restriction. At this stage it's not clear whether
5283 * this behaviour is intentional or is a hardware bug in chip
5284 * revisions available at least up until early 2006. Therefore for
5285 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5286 * choices, but if it turns out that the lack of mic bias for these
5287 * NIDs is intentional we could change their modes from
5288 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5289 */
7cf51e48
JW
5290 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5291 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5292 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5293 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5294 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5295 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5296
5297 /* Loopback mixer controls */
5298 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5299 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5300 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5301 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5302 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5303 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5304 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5305 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5306 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5307 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5308 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
5309 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
5310 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5311 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5312 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5313 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
5314
5315 /* Controls for GPIO pins, assuming they are configured as outputs */
5316 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5317 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5318 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5319 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5320
92621f13
JW
5321 /* Switches to allow the digital IO pins to be enabled. The datasheet
5322 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 5323 * make this output available should provide clarification.
92621f13
JW
5324 */
5325 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5326 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5327
f8225f6d
JW
5328 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5329 * this output to turn on an external amplifier.
5330 */
5331 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5332 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5333
7cf51e48
JW
5334 { } /* end */
5335};
5336static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
5337 /* Enable all GPIOs as outputs with an initial value of 0 */
5338 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5339 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5340 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5341
7cf51e48
JW
5342 /* Enable retasking pins as output, initially without power amp */
5343 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5344 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5345 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5346 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5347 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5348 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5349
92621f13
JW
5350 /* Disable digital (SPDIF) pins initially, but users can enable
5351 * them via a mixer switch. In the case of SPDIF-out, this initverb
5352 * payload also sets the generation to 0, output to be in "consumer"
5353 * PCM format, copyright asserted, no pre-emphasis and no validity
5354 * control.
5355 */
7cf51e48
JW
5356 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5357 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5358
ea1fb29a 5359 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
5360 * OUT1 sum bus when acting as an output.
5361 */
5362 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5363 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5364 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5365 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5366
5367 /* Start with output sum widgets muted and their output gains at min */
5368 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5369 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5370 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5371 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5372 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5373 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5374 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5375 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5376 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5377
cdcd9268
JW
5378 /* Unmute retasking pin widget output buffers since the default
5379 * state appears to be output. As the pin mode is changed by the
5380 * user the pin mode control will take care of enabling the pin's
5381 * input/output buffers as needed.
5382 */
7cf51e48
JW
5383 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5384 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5385 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5386 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5387 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5388 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5389 /* Also unmute the mono-out pin widget */
5390 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5391
7cf51e48
JW
5392 /* Mute capture amp left and right */
5393 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
5394 /* Set ADC connection select to match default mixer setting (mic1
5395 * pin)
7cf51e48
JW
5396 */
5397 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5398
5399 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 5400 * set ADC connection to mic1 pin
7cf51e48
JW
5401 */
5402 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5403 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5404
5405 /* Mute all inputs to mixer widget (even unconnected ones) */
5406 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5408 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5414
5415 { }
5416};
5417#endif
5418
6330079f
TI
5419#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5420#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 5421
a3bcba38
TI
5422#define alc260_pcm_digital_playback alc880_pcm_digital_playback
5423#define alc260_pcm_digital_capture alc880_pcm_digital_capture
5424
df694daa
KY
5425/*
5426 * for BIOS auto-configuration
5427 */
16ded525 5428
df694daa 5429static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 5430 const char *pfx, int *vol_bits)
df694daa
KY
5431{
5432 hda_nid_t nid_vol;
5433 unsigned long vol_val, sw_val;
5434 char name[32];
5435 int err;
5436
5437 if (nid >= 0x0f && nid < 0x11) {
5438 nid_vol = nid - 0x7;
5439 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5440 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5441 } else if (nid == 0x11) {
5442 nid_vol = nid - 0x7;
5443 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5444 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5445 } else if (nid >= 0x12 && nid <= 0x15) {
5446 nid_vol = 0x08;
5447 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5448 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5449 } else
5450 return 0; /* N/A */
ea1fb29a 5451
863b4518
TI
5452 if (!(*vol_bits & (1 << nid_vol))) {
5453 /* first control for the volume widget */
5454 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5455 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5456 if (err < 0)
5457 return err;
5458 *vol_bits |= (1 << nid_vol);
5459 }
df694daa 5460 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
5461 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5462 if (err < 0)
df694daa
KY
5463 return err;
5464 return 1;
5465}
5466
5467/* add playback controls from the parsed DAC table */
5468static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5469 const struct auto_pin_cfg *cfg)
5470{
5471 hda_nid_t nid;
5472 int err;
863b4518 5473 int vols = 0;
df694daa
KY
5474
5475 spec->multiout.num_dacs = 1;
5476 spec->multiout.dac_nids = spec->private_dac_nids;
5477 spec->multiout.dac_nids[0] = 0x02;
5478
5479 nid = cfg->line_out_pins[0];
5480 if (nid) {
863b4518 5481 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
df694daa
KY
5482 if (err < 0)
5483 return err;
5484 }
5485
82bc955f 5486 nid = cfg->speaker_pins[0];
df694daa 5487 if (nid) {
863b4518 5488 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
5489 if (err < 0)
5490 return err;
5491 }
5492
eb06ed8f 5493 nid = cfg->hp_pins[0];
df694daa 5494 if (nid) {
863b4518
TI
5495 err = alc260_add_playback_controls(spec, nid, "Headphone",
5496 &vols);
df694daa
KY
5497 if (err < 0)
5498 return err;
5499 }
f12ab1e0 5500 return 0;
df694daa
KY
5501}
5502
5503/* create playback/capture controls for input pins */
5504static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5505 const struct auto_pin_cfg *cfg)
5506{
61b9b9b1 5507 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
5508 int i, err, idx;
5509
5510 for (i = 0; i < AUTO_PIN_LAST; i++) {
5511 if (cfg->input_pins[i] >= 0x12) {
5512 idx = cfg->input_pins[i] - 0x12;
4a471b7d 5513 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5514 auto_pin_cfg_labels[i], idx,
5515 0x07);
df694daa
KY
5516 if (err < 0)
5517 return err;
f12ab1e0
TI
5518 imux->items[imux->num_items].label =
5519 auto_pin_cfg_labels[i];
df694daa
KY
5520 imux->items[imux->num_items].index = idx;
5521 imux->num_items++;
5522 }
f12ab1e0 5523 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 5524 idx = cfg->input_pins[i] - 0x09;
4a471b7d 5525 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5526 auto_pin_cfg_labels[i], idx,
5527 0x07);
df694daa
KY
5528 if (err < 0)
5529 return err;
f12ab1e0
TI
5530 imux->items[imux->num_items].label =
5531 auto_pin_cfg_labels[i];
df694daa
KY
5532 imux->items[imux->num_items].index = idx;
5533 imux->num_items++;
5534 }
5535 }
5536 return 0;
5537}
5538
5539static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5540 hda_nid_t nid, int pin_type,
5541 int sel_idx)
5542{
f6c7e546 5543 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
5544 /* need the manual connection? */
5545 if (nid >= 0x12) {
5546 int idx = nid - 0x12;
5547 snd_hda_codec_write(codec, idx + 0x0b, 0,
5548 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
5549 }
5550}
5551
5552static void alc260_auto_init_multi_out(struct hda_codec *codec)
5553{
5554 struct alc_spec *spec = codec->spec;
5555 hda_nid_t nid;
5556
bc9f98a9 5557 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 5558 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
5559 if (nid) {
5560 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5561 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5562 }
ea1fb29a 5563
82bc955f 5564 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
5565 if (nid)
5566 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5567
eb06ed8f 5568 nid = spec->autocfg.hp_pins[0];
df694daa 5569 if (nid)
baba8ee9 5570 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 5571}
df694daa
KY
5572
5573#define ALC260_PIN_CD_NID 0x16
5574static void alc260_auto_init_analog_input(struct hda_codec *codec)
5575{
5576 struct alc_spec *spec = codec->spec;
5577 int i;
5578
5579 for (i = 0; i < AUTO_PIN_LAST; i++) {
5580 hda_nid_t nid = spec->autocfg.input_pins[i];
5581 if (nid >= 0x12) {
f12ab1e0
TI
5582 snd_hda_codec_write(codec, nid, 0,
5583 AC_VERB_SET_PIN_WIDGET_CONTROL,
5584 i <= AUTO_PIN_FRONT_MIC ?
5585 PIN_VREF80 : PIN_IN);
df694daa 5586 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
5587 snd_hda_codec_write(codec, nid, 0,
5588 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
5589 AMP_OUT_MUTE);
5590 }
5591 }
5592}
5593
5594/*
5595 * generic initialization of ADC, input mixers and output mixers
5596 */
5597static struct hda_verb alc260_volume_init_verbs[] = {
5598 /*
5599 * Unmute ADC0-1 and set the default input to mic-in
5600 */
5601 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5602 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5603 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5604 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 5605
df694daa
KY
5606 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5607 * mixer widget
f12ab1e0
TI
5608 * Note: PASD motherboards uses the Line In 2 as the input for
5609 * front panel mic (mic 2)
df694daa
KY
5610 */
5611 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5612 /* mute analog inputs */
5613 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5615 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5618
5619 /*
5620 * Set up output mixers (0x08 - 0x0a)
5621 */
5622 /* set vol=0 to output mixers */
5623 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5624 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5625 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5626 /* set up input amps for analog loopback */
5627 /* Amp Indices: DAC = 0, mixer = 1 */
5628 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5630 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5631 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5632 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5633 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 5634
df694daa
KY
5635 { }
5636};
5637
5638static int alc260_parse_auto_config(struct hda_codec *codec)
5639{
5640 struct alc_spec *spec = codec->spec;
df694daa
KY
5641 int err;
5642 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5643
f12ab1e0
TI
5644 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5645 alc260_ignore);
5646 if (err < 0)
df694daa 5647 return err;
f12ab1e0
TI
5648 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5649 if (err < 0)
4a471b7d 5650 return err;
603c4019 5651 if (!spec->kctls.list)
df694daa 5652 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
5653 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5654 if (err < 0)
df694daa
KY
5655 return err;
5656
5657 spec->multiout.max_channels = 2;
5658
5659 if (spec->autocfg.dig_out_pin)
5660 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 5661 if (spec->kctls.list)
d88897ea 5662 add_mixer(spec, spec->kctls.list);
df694daa 5663
d88897ea 5664 add_verb(spec, alc260_volume_init_verbs);
df694daa 5665
a1e8d2da 5666 spec->num_mux_defs = 1;
61b9b9b1 5667 spec->input_mux = &spec->private_imux[0];
df694daa 5668
e044c39a 5669 store_pin_configs(codec);
df694daa
KY
5670 return 1;
5671}
5672
ae6b813a
TI
5673/* additional initialization for auto-configuration model */
5674static void alc260_auto_init(struct hda_codec *codec)
df694daa 5675{
f6c7e546 5676 struct alc_spec *spec = codec->spec;
df694daa
KY
5677 alc260_auto_init_multi_out(codec);
5678 alc260_auto_init_analog_input(codec);
f6c7e546 5679 if (spec->unsol_event)
7fb0d78f 5680 alc_inithook(codec);
df694daa
KY
5681}
5682
cb53c626
TI
5683#ifdef CONFIG_SND_HDA_POWER_SAVE
5684static struct hda_amp_list alc260_loopbacks[] = {
5685 { 0x07, HDA_INPUT, 0 },
5686 { 0x07, HDA_INPUT, 1 },
5687 { 0x07, HDA_INPUT, 2 },
5688 { 0x07, HDA_INPUT, 3 },
5689 { 0x07, HDA_INPUT, 4 },
5690 { } /* end */
5691};
5692#endif
5693
df694daa
KY
5694/*
5695 * ALC260 configurations
5696 */
f5fcc13c
TI
5697static const char *alc260_models[ALC260_MODEL_LAST] = {
5698 [ALC260_BASIC] = "basic",
5699 [ALC260_HP] = "hp",
5700 [ALC260_HP_3013] = "hp-3013",
2922c9af 5701 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
5702 [ALC260_FUJITSU_S702X] = "fujitsu",
5703 [ALC260_ACER] = "acer",
bc9f98a9
KY
5704 [ALC260_WILL] = "will",
5705 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 5706#ifdef CONFIG_SND_DEBUG
f5fcc13c 5707 [ALC260_TEST] = "test",
7cf51e48 5708#endif
f5fcc13c
TI
5709 [ALC260_AUTO] = "auto",
5710};
5711
5712static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5713 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5714 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 5715 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5716 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c 5717 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 5718 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 5719 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
5720 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5721 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5722 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5723 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5724 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5725 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5726 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5727 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5728 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5729 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5730 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5731 {}
5732};
5733
5734static struct alc_config_preset alc260_presets[] = {
5735 [ALC260_BASIC] = {
5736 .mixers = { alc260_base_output_mixer,
5737 alc260_input_mixer,
f9e336f6 5738 alc260_pc_beep_mixer },
df694daa
KY
5739 .init_verbs = { alc260_init_verbs },
5740 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5741 .dac_nids = alc260_dac_nids,
f9e336f6 5742 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
df694daa
KY
5743 .adc_nids = alc260_adc_nids,
5744 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5745 .channel_mode = alc260_modes,
5746 .input_mux = &alc260_capture_source,
5747 },
5748 [ALC260_HP] = {
bec15c3a 5749 .mixers = { alc260_hp_output_mixer,
f9e336f6 5750 alc260_input_mixer },
bec15c3a
TI
5751 .init_verbs = { alc260_init_verbs,
5752 alc260_hp_unsol_verbs },
df694daa
KY
5753 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5754 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5755 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5756 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
5757 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5758 .channel_mode = alc260_modes,
5759 .input_mux = &alc260_capture_source,
bec15c3a
TI
5760 .unsol_event = alc260_hp_unsol_event,
5761 .init_hook = alc260_hp_automute,
df694daa 5762 },
3f878308
KY
5763 [ALC260_HP_DC7600] = {
5764 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 5765 alc260_input_mixer },
3f878308
KY
5766 .init_verbs = { alc260_init_verbs,
5767 alc260_hp_dc7600_verbs },
5768 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5769 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5770 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5771 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
5772 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5773 .channel_mode = alc260_modes,
5774 .input_mux = &alc260_capture_source,
5775 .unsol_event = alc260_hp_3012_unsol_event,
5776 .init_hook = alc260_hp_3012_automute,
5777 },
df694daa
KY
5778 [ALC260_HP_3013] = {
5779 .mixers = { alc260_hp_3013_mixer,
f9e336f6 5780 alc260_input_mixer },
bec15c3a
TI
5781 .init_verbs = { alc260_hp_3013_init_verbs,
5782 alc260_hp_3013_unsol_verbs },
df694daa
KY
5783 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5784 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5785 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5786 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
5787 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5788 .channel_mode = alc260_modes,
5789 .input_mux = &alc260_capture_source,
bec15c3a
TI
5790 .unsol_event = alc260_hp_3013_unsol_event,
5791 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5792 },
5793 [ALC260_FUJITSU_S702X] = {
f9e336f6 5794 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
5795 .init_verbs = { alc260_fujitsu_init_verbs },
5796 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5797 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5798 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5799 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5800 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5801 .channel_mode = alc260_modes,
a1e8d2da
JW
5802 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5803 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5804 },
0bfc90e9 5805 [ALC260_ACER] = {
f9e336f6 5806 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
5807 .init_verbs = { alc260_acer_init_verbs },
5808 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5809 .dac_nids = alc260_dac_nids,
5810 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5811 .adc_nids = alc260_dual_adc_nids,
5812 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5813 .channel_mode = alc260_modes,
a1e8d2da
JW
5814 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5815 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5816 },
bc9f98a9 5817 [ALC260_WILL] = {
f9e336f6 5818 .mixers = { alc260_will_mixer },
bc9f98a9
KY
5819 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5820 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5821 .dac_nids = alc260_dac_nids,
5822 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5823 .adc_nids = alc260_adc_nids,
5824 .dig_out_nid = ALC260_DIGOUT_NID,
5825 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5826 .channel_mode = alc260_modes,
5827 .input_mux = &alc260_capture_source,
5828 },
5829 [ALC260_REPLACER_672V] = {
f9e336f6 5830 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
5831 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5832 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5833 .dac_nids = alc260_dac_nids,
5834 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5835 .adc_nids = alc260_adc_nids,
5836 .dig_out_nid = ALC260_DIGOUT_NID,
5837 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5838 .channel_mode = alc260_modes,
5839 .input_mux = &alc260_capture_source,
5840 .unsol_event = alc260_replacer_672v_unsol_event,
5841 .init_hook = alc260_replacer_672v_automute,
5842 },
7cf51e48
JW
5843#ifdef CONFIG_SND_DEBUG
5844 [ALC260_TEST] = {
f9e336f6 5845 .mixers = { alc260_test_mixer },
7cf51e48
JW
5846 .init_verbs = { alc260_test_init_verbs },
5847 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5848 .dac_nids = alc260_test_dac_nids,
5849 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5850 .adc_nids = alc260_test_adc_nids,
5851 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5852 .channel_mode = alc260_modes,
a1e8d2da
JW
5853 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5854 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5855 },
5856#endif
df694daa
KY
5857};
5858
5859static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5860{
5861 struct alc_spec *spec;
df694daa 5862 int err, board_config;
1da177e4 5863
e560d8d8 5864 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5865 if (spec == NULL)
5866 return -ENOMEM;
5867
5868 codec->spec = spec;
5869
f5fcc13c
TI
5870 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5871 alc260_models,
5872 alc260_cfg_tbl);
5873 if (board_config < 0) {
9c7f852e
TI
5874 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5875 "trying auto-probe from BIOS...\n");
df694daa 5876 board_config = ALC260_AUTO;
16ded525 5877 }
1da177e4 5878
df694daa
KY
5879 if (board_config == ALC260_AUTO) {
5880 /* automatic parse from the BIOS config */
5881 err = alc260_parse_auto_config(codec);
5882 if (err < 0) {
5883 alc_free(codec);
5884 return err;
f12ab1e0 5885 } else if (!err) {
9c7f852e
TI
5886 printk(KERN_INFO
5887 "hda_codec: Cannot set up configuration "
5888 "from BIOS. Using base mode...\n");
df694daa
KY
5889 board_config = ALC260_BASIC;
5890 }
a9430dd8 5891 }
e9edcee0 5892
680cd536
KK
5893 err = snd_hda_attach_beep_device(codec, 0x1);
5894 if (err < 0) {
5895 alc_free(codec);
5896 return err;
5897 }
5898
df694daa
KY
5899 if (board_config != ALC260_AUTO)
5900 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
5901
5902 spec->stream_name_analog = "ALC260 Analog";
5903 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5904 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5905
a3bcba38
TI
5906 spec->stream_name_digital = "ALC260 Digital";
5907 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5908 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5909
4ef0ef19
TI
5910 if (!spec->adc_nids && spec->input_mux) {
5911 /* check whether NID 0x04 is valid */
5912 unsigned int wcap = get_wcaps(codec, 0x04);
5913 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5914 /* get type */
5915 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5916 spec->adc_nids = alc260_adc_nids_alt;
5917 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5918 } else {
5919 spec->adc_nids = alc260_adc_nids;
5920 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5921 }
5922 }
f9e336f6
TI
5923 set_capture_mixer(spec);
5924
2134ea4f
TI
5925 spec->vmaster_nid = 0x08;
5926
1da177e4 5927 codec->patch_ops = alc_patch_ops;
df694daa 5928 if (board_config == ALC260_AUTO)
ae6b813a 5929 spec->init_hook = alc260_auto_init;
cb53c626
TI
5930#ifdef CONFIG_SND_HDA_POWER_SAVE
5931 if (!spec->loopback.amplist)
5932 spec->loopback.amplist = alc260_loopbacks;
5933#endif
daead538 5934 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
5935
5936 return 0;
5937}
5938
e9edcee0 5939
1da177e4
LT
5940/*
5941 * ALC882 support
5942 *
5943 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5944 * configuration. Each pin widget can choose any input DACs and a mixer.
5945 * Each ADC is connected from a mixer of all inputs. This makes possible
5946 * 6-channel independent captures.
5947 *
5948 * In addition, an independent DAC for the multi-playback (not used in this
5949 * driver yet).
5950 */
df694daa
KY
5951#define ALC882_DIGOUT_NID 0x06
5952#define ALC882_DIGIN_NID 0x0a
1da177e4 5953
d2a6d7dc 5954static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
5955 { 8, NULL }
5956};
5957
5958static hda_nid_t alc882_dac_nids[4] = {
5959 /* front, rear, clfe, rear_surr */
5960 0x02, 0x03, 0x04, 0x05
5961};
5962
df694daa
KY
5963/* identical with ALC880 */
5964#define alc882_adc_nids alc880_adc_nids
5965#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 5966
e1406348
TI
5967static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5968static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5969
1da177e4
LT
5970/* input MUX */
5971/* FIXME: should be a matrix-type input source selection */
5972
5973static struct hda_input_mux alc882_capture_source = {
5974 .num_items = 4,
5975 .items = {
5976 { "Mic", 0x0 },
5977 { "Front Mic", 0x1 },
5978 { "Line", 0x2 },
5979 { "CD", 0x4 },
5980 },
5981};
272a527c
KY
5982/*
5983 * 2ch mode
5984 */
5985static struct hda_verb alc882_3ST_ch2_init[] = {
5986 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5987 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5988 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5989 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5990 { } /* end */
5991};
5992
5993/*
5994 * 6ch mode
5995 */
5996static struct hda_verb alc882_3ST_ch6_init[] = {
5997 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5998 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5999 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6000 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6001 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6002 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6003 { } /* end */
6004};
6005
6006static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6007 { 2, alc882_3ST_ch2_init },
6008 { 6, alc882_3ST_ch6_init },
6009};
6010
df694daa
KY
6011/*
6012 * 6ch mode
6013 */
6014static struct hda_verb alc882_sixstack_ch6_init[] = {
6015 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6016 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6017 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6018 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6019 { } /* end */
6020};
6021
6022/*
6023 * 8ch mode
6024 */
6025static struct hda_verb alc882_sixstack_ch8_init[] = {
6026 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6027 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6028 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6029 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6030 { } /* end */
6031};
6032
6033static struct hda_channel_mode alc882_sixstack_modes[2] = {
6034 { 6, alc882_sixstack_ch6_init },
6035 { 8, alc882_sixstack_ch8_init },
6036};
6037
87350ad0
TI
6038/*
6039 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6040 */
6041
6042/*
6043 * 2ch mode
6044 */
6045static struct hda_verb alc885_mbp_ch2_init[] = {
6046 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6047 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6048 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6049 { } /* end */
6050};
6051
6052/*
6053 * 6ch mode
6054 */
6055static struct hda_verb alc885_mbp_ch6_init[] = {
6056 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6057 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6058 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6059 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6060 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6061 { } /* end */
6062};
6063
6064static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6065 { 2, alc885_mbp_ch2_init },
6066 { 6, alc885_mbp_ch6_init },
6067};
6068
6069
1da177e4
LT
6070/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6071 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6072 */
c8b6bf9b 6073static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 6074 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 6075 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 6076 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 6077 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
6078 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6079 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
6080 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6081 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 6082 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 6083 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
6084 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6085 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6086 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6087 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6088 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6090 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
6091 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6092 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6093 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
6094 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6095 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6096 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
6097 { } /* end */
6098};
6099
87350ad0 6100static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
6101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6102 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6103 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6104 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6105 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6106 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
6107 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6108 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 6109 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
6110 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6111 { } /* end */
6112};
bdd148a3
KY
6113static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6114 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6115 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6116 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6117 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6118 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6119 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6120 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6121 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6122 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6123 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6124 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6125 { } /* end */
6126};
6127
272a527c
KY
6128static struct snd_kcontrol_new alc882_targa_mixer[] = {
6129 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6130 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6131 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6132 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6133 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6134 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6135 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6138 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6139 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6140 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 6141 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
6142 { } /* end */
6143};
6144
6145/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6146 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6147 */
6148static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6149 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6150 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6152 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6153 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6154 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6155 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6156 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6157 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6158 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6159 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6160 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6161 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6162 { } /* end */
6163};
6164
914759b7
TI
6165static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6166 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6167 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6168 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6169 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6170 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6171 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6172 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6173 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6174 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6175 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6176 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6177 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6178 { } /* end */
6179};
6180
df694daa
KY
6181static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6182 {
6183 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6184 .name = "Channel Mode",
6185 .info = alc_ch_mode_info,
6186 .get = alc_ch_mode_get,
6187 .put = alc_ch_mode_put,
6188 },
6189 { } /* end */
6190};
6191
1da177e4
LT
6192static struct hda_verb alc882_init_verbs[] = {
6193 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
6194 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6197 /* Rear mixer */
05acb863
TI
6198 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6199 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6200 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6201 /* CLFE mixer */
05acb863
TI
6202 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6203 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6204 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6205 /* Side mixer */
05acb863
TI
6206 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6207 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6208 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6209
e9edcee0 6210 /* Front Pin: output 0 (0x0c) */
05acb863 6211 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6213 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 6214 /* Rear Pin: output 1 (0x0d) */
05acb863 6215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6216 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6217 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 6218 /* CLFE Pin: output 2 (0x0e) */
05acb863 6219 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6220 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6221 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 6222 /* Side Pin: output 3 (0x0f) */
05acb863 6223 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6224 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6225 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 6226 /* Mic (rear) pin: input vref at 80% */
16ded525 6227 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6228 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6229 /* Front Mic pin: input vref at 80% */
16ded525 6230 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6231 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6232 /* Line In pin: input */
05acb863 6233 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
6234 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6235 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6236 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6237 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6238 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6239 /* CD pin widget for input */
05acb863 6240 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
6241
6242 /* FIXME: use matrix-type input source selection */
6243 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6244 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
6245 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6247 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6248 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6249 /* Input mixer2 */
05acb863
TI
6250 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6251 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6252 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6253 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6254 /* Input mixer3 */
05acb863
TI
6255 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6256 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6257 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6259 /* ADC1: mute amp left and right */
6260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6261 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6262 /* ADC2: mute amp left and right */
6263 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6264 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6265 /* ADC3: mute amp left and right */
6266 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6267 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
6268
6269 { }
6270};
6271
4b146cb0
TI
6272static struct hda_verb alc882_eapd_verbs[] = {
6273 /* change to EAPD mode */
6274 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 6275 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 6276 { }
4b146cb0
TI
6277};
6278
9102cd1c
TD
6279/* Mac Pro test */
6280static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6281 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6282 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6283 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6284 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6285 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6286 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6287 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6288 { } /* end */
6289};
6290
6291static struct hda_verb alc882_macpro_init_verbs[] = {
6292 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6293 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6296 /* Front Pin: output 0 (0x0c) */
6297 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6298 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6299 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6300 /* Front Mic pin: input vref at 80% */
6301 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6302 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6303 /* Speaker: output */
6304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6306 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6307 /* Headphone output (output 0 - 0x0c) */
6308 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6309 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6310 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6311
6312 /* FIXME: use matrix-type input source selection */
6313 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6314 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6318 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6319 /* Input mixer2 */
6320 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6321 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6323 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6324 /* Input mixer3 */
6325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6328 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6329 /* ADC1: mute amp left and right */
6330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6331 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6332 /* ADC2: mute amp left and right */
6333 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6334 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6335 /* ADC3: mute amp left and right */
6336 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6337 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6338
6339 { }
6340};
f12ab1e0 6341
87350ad0
TI
6342/* Macbook Pro rev3 */
6343static struct hda_verb alc885_mbp3_init_verbs[] = {
6344 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6347 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6348 /* Rear mixer */
6349 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6350 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6351 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6352 /* Front Pin: output 0 (0x0c) */
6353 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6354 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6355 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6356 /* HP Pin: output 0 (0x0d) */
6357 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6358 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6359 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6360 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6361 /* Mic (rear) pin: input vref at 80% */
6362 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6363 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6364 /* Front Mic pin: input vref at 80% */
6365 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6366 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6367 /* Line In pin: use output 1 when in LineOut mode */
6368 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6369 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6370 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6371
6372 /* FIXME: use matrix-type input source selection */
6373 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6374 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6379 /* Input mixer2 */
6380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6384 /* Input mixer3 */
6385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6389 /* ADC1: mute amp left and right */
6390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6392 /* ADC2: mute amp left and right */
6393 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6394 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6395 /* ADC3: mute amp left and right */
6396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6397 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6398
6399 { }
6400};
6401
c54728d8
NF
6402/* iMac 24 mixer. */
6403static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6404 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6405 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6406 { } /* end */
6407};
6408
6409/* iMac 24 init verbs. */
6410static struct hda_verb alc885_imac24_init_verbs[] = {
6411 /* Internal speakers: output 0 (0x0c) */
6412 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6413 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6414 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6415 /* Internal speakers: output 0 (0x0c) */
6416 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6417 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6418 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6419 /* Headphone: output 0 (0x0c) */
6420 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6422 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6423 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6424 /* Front Mic: input vref at 80% */
6425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6426 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6427 { }
6428};
6429
6430/* Toggle speaker-output according to the hp-jack state */
6431static void alc885_imac24_automute(struct hda_codec *codec)
6432{
6433 unsigned int present;
6434
6435 present = snd_hda_codec_read(codec, 0x14, 0,
6436 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
6437 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6438 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6439 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6440 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
6441}
6442
6443/* Processes unsolicited events. */
6444static void alc885_imac24_unsol_event(struct hda_codec *codec,
6445 unsigned int res)
6446{
6447 /* Headphone insertion or removal. */
6448 if ((res >> 26) == ALC880_HP_EVENT)
6449 alc885_imac24_automute(codec);
6450}
6451
87350ad0
TI
6452static void alc885_mbp3_automute(struct hda_codec *codec)
6453{
6454 unsigned int present;
6455
6456 present = snd_hda_codec_read(codec, 0x15, 0,
6457 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6458 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6459 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6460 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6461 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6462
6463}
6464static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6465 unsigned int res)
6466{
6467 /* Headphone insertion or removal. */
6468 if ((res >> 26) == ALC880_HP_EVENT)
6469 alc885_mbp3_automute(codec);
6470}
6471
6472
272a527c
KY
6473static struct hda_verb alc882_targa_verbs[] = {
6474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6476
6477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6478 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6479
272a527c
KY
6480 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6482 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6483
6484 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6485 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6486 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6487 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6488 { } /* end */
6489};
6490
6491/* toggle speaker-output according to the hp-jack state */
6492static void alc882_targa_automute(struct hda_codec *codec)
6493{
6494 unsigned int present;
ea1fb29a 6495
272a527c
KY
6496 present = snd_hda_codec_read(codec, 0x14, 0,
6497 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
6498 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6499 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
6500 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6501 present ? 1 : 3);
272a527c
KY
6502}
6503
6504static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6505{
6506 /* Looks like the unsol event is incompatible with the standard
6507 * definition. 4bit tag is placed at 26 bit!
6508 */
6509 if (((res >> 26) == ALC880_HP_EVENT)) {
6510 alc882_targa_automute(codec);
6511 }
6512}
6513
6514static struct hda_verb alc882_asus_a7j_verbs[] = {
6515 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6517
6518 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6520 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6521
272a527c
KY
6522 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6523 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6524 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6525
6526 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6527 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6528 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6529 { } /* end */
6530};
6531
914759b7
TI
6532static struct hda_verb alc882_asus_a7m_verbs[] = {
6533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6535
6536 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6537 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6538 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6539
914759b7
TI
6540 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6541 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6542 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6543
6544 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6545 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6546 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6547 { } /* end */
6548};
6549
9102cd1c
TD
6550static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6551{
6552 unsigned int gpiostate, gpiomask, gpiodir;
6553
6554 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6555 AC_VERB_GET_GPIO_DATA, 0);
6556
6557 if (!muted)
6558 gpiostate |= (1 << pin);
6559 else
6560 gpiostate &= ~(1 << pin);
6561
6562 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6563 AC_VERB_GET_GPIO_MASK, 0);
6564 gpiomask |= (1 << pin);
6565
6566 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6567 AC_VERB_GET_GPIO_DIRECTION, 0);
6568 gpiodir |= (1 << pin);
6569
6570
6571 snd_hda_codec_write(codec, codec->afg, 0,
6572 AC_VERB_SET_GPIO_MASK, gpiomask);
6573 snd_hda_codec_write(codec, codec->afg, 0,
6574 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6575
6576 msleep(1);
6577
6578 snd_hda_codec_write(codec, codec->afg, 0,
6579 AC_VERB_SET_GPIO_DATA, gpiostate);
6580}
6581
7debbe51
TI
6582/* set up GPIO at initialization */
6583static void alc885_macpro_init_hook(struct hda_codec *codec)
6584{
6585 alc882_gpio_mute(codec, 0, 0);
6586 alc882_gpio_mute(codec, 1, 0);
6587}
6588
6589/* set up GPIO and update auto-muting at initialization */
6590static void alc885_imac24_init_hook(struct hda_codec *codec)
6591{
6592 alc885_macpro_init_hook(codec);
6593 alc885_imac24_automute(codec);
6594}
6595
df694daa
KY
6596/*
6597 * generic initialization of ADC, input mixers and output mixers
6598 */
6599static struct hda_verb alc882_auto_init_verbs[] = {
6600 /*
6601 * Unmute ADC0-2 and set the default input to mic-in
6602 */
6603 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6604 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6605 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6607 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 6609
cb53c626 6610 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 6611 * mixer widget
f12ab1e0
TI
6612 * Note: PASD motherboards uses the Line In 2 as the input for
6613 * front panel mic (mic 2)
df694daa
KY
6614 */
6615 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6616 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6617 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6618 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6619 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6620 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 6621
df694daa
KY
6622 /*
6623 * Set up output mixers (0x0c - 0x0f)
6624 */
6625 /* set vol=0 to output mixers */
6626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6627 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6628 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6629 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6630 /* set up input amps for analog loopback */
6631 /* Amp Indices: DAC = 0, mixer = 1 */
6632 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6633 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6634 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6635 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6636 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6637 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6638 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6639 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6640 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6641 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6642
6643 /* FIXME: use matrix-type input source selection */
6644 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6645 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6650 /* Input mixer2 */
6651 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6652 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6653 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6655 /* Input mixer3 */
6656 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6657 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6660
6661 { }
6662};
6663
cb53c626
TI
6664#ifdef CONFIG_SND_HDA_POWER_SAVE
6665#define alc882_loopbacks alc880_loopbacks
6666#endif
6667
df694daa
KY
6668/* pcm configuration: identiacal with ALC880 */
6669#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6670#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6671#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6672#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6673
6674/*
6675 * configuration and preset
6676 */
f5fcc13c
TI
6677static const char *alc882_models[ALC882_MODEL_LAST] = {
6678 [ALC882_3ST_DIG] = "3stack-dig",
6679 [ALC882_6ST_DIG] = "6stack-dig",
6680 [ALC882_ARIMA] = "arima",
bdd148a3 6681 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6682 [ALC882_TARGA] = "targa",
6683 [ALC882_ASUS_A7J] = "asus-a7j",
6684 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6685 [ALC885_MACPRO] = "macpro",
87350ad0 6686 [ALC885_MBP3] = "mbp3",
c54728d8 6687 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6688 [ALC882_AUTO] = "auto",
6689};
6690
6691static struct snd_pci_quirk alc882_cfg_tbl[] = {
6692 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6693 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6694 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6695 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6696 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6697 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6698 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6699 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6700 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6701 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6702 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6703 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6704 {}
6705};
6706
6707static struct alc_config_preset alc882_presets[] = {
6708 [ALC882_3ST_DIG] = {
6709 .mixers = { alc882_base_mixer },
6710 .init_verbs = { alc882_init_verbs },
6711 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6712 .dac_nids = alc882_dac_nids,
6713 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6714 .dig_in_nid = ALC882_DIGIN_NID,
6715 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6716 .channel_mode = alc882_ch_modes,
4e195a7b 6717 .need_dac_fix = 1,
df694daa
KY
6718 .input_mux = &alc882_capture_source,
6719 },
6720 [ALC882_6ST_DIG] = {
6721 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6722 .init_verbs = { alc882_init_verbs },
6723 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6724 .dac_nids = alc882_dac_nids,
6725 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6726 .dig_in_nid = ALC882_DIGIN_NID,
6727 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6728 .channel_mode = alc882_sixstack_modes,
6729 .input_mux = &alc882_capture_source,
6730 },
4b146cb0
TI
6731 [ALC882_ARIMA] = {
6732 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6733 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6734 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6735 .dac_nids = alc882_dac_nids,
6736 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6737 .channel_mode = alc882_sixstack_modes,
6738 .input_mux = &alc882_capture_source,
6739 },
bdd148a3
KY
6740 [ALC882_W2JC] = {
6741 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6742 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6743 alc880_gpio1_init_verbs },
6744 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6745 .dac_nids = alc882_dac_nids,
6746 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6747 .channel_mode = alc880_threestack_modes,
6748 .need_dac_fix = 1,
6749 .input_mux = &alc882_capture_source,
6750 .dig_out_nid = ALC882_DIGOUT_NID,
6751 },
87350ad0
TI
6752 [ALC885_MBP3] = {
6753 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6754 .init_verbs = { alc885_mbp3_init_verbs,
6755 alc880_gpio1_init_verbs },
6756 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6757 .dac_nids = alc882_dac_nids,
6758 .channel_mode = alc885_mbp_6ch_modes,
6759 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6760 .input_mux = &alc882_capture_source,
6761 .dig_out_nid = ALC882_DIGOUT_NID,
6762 .dig_in_nid = ALC882_DIGIN_NID,
6763 .unsol_event = alc885_mbp3_unsol_event,
6764 .init_hook = alc885_mbp3_automute,
6765 },
9102cd1c
TD
6766 [ALC885_MACPRO] = {
6767 .mixers = { alc882_macpro_mixer },
6768 .init_verbs = { alc882_macpro_init_verbs },
6769 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6770 .dac_nids = alc882_dac_nids,
6771 .dig_out_nid = ALC882_DIGOUT_NID,
6772 .dig_in_nid = ALC882_DIGIN_NID,
6773 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6774 .channel_mode = alc882_ch_modes,
6775 .input_mux = &alc882_capture_source,
7debbe51 6776 .init_hook = alc885_macpro_init_hook,
9102cd1c 6777 },
c54728d8
NF
6778 [ALC885_IMAC24] = {
6779 .mixers = { alc885_imac24_mixer },
6780 .init_verbs = { alc885_imac24_init_verbs },
6781 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6782 .dac_nids = alc882_dac_nids,
6783 .dig_out_nid = ALC882_DIGOUT_NID,
6784 .dig_in_nid = ALC882_DIGIN_NID,
6785 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6786 .channel_mode = alc882_ch_modes,
6787 .input_mux = &alc882_capture_source,
6788 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6789 .init_hook = alc885_imac24_init_hook,
c54728d8 6790 },
272a527c 6791 [ALC882_TARGA] = {
f9e336f6 6792 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
272a527c
KY
6793 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6794 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6795 .dac_nids = alc882_dac_nids,
6796 .dig_out_nid = ALC882_DIGOUT_NID,
6797 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6798 .adc_nids = alc882_adc_nids,
e1406348 6799 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6800 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6801 .channel_mode = alc882_3ST_6ch_modes,
6802 .need_dac_fix = 1,
6803 .input_mux = &alc882_capture_source,
6804 .unsol_event = alc882_targa_unsol_event,
6805 .init_hook = alc882_targa_automute,
6806 },
6807 [ALC882_ASUS_A7J] = {
f9e336f6 6808 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
272a527c
KY
6809 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6810 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6811 .dac_nids = alc882_dac_nids,
6812 .dig_out_nid = ALC882_DIGOUT_NID,
6813 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6814 .adc_nids = alc882_adc_nids,
e1406348 6815 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6816 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6817 .channel_mode = alc882_3ST_6ch_modes,
6818 .need_dac_fix = 1,
6819 .input_mux = &alc882_capture_source,
ea1fb29a 6820 },
914759b7
TI
6821 [ALC882_ASUS_A7M] = {
6822 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6823 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6824 alc880_gpio1_init_verbs,
6825 alc882_asus_a7m_verbs },
6826 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6827 .dac_nids = alc882_dac_nids,
6828 .dig_out_nid = ALC882_DIGOUT_NID,
6829 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6830 .channel_mode = alc880_threestack_modes,
6831 .need_dac_fix = 1,
6832 .input_mux = &alc882_capture_source,
ea1fb29a 6833 },
df694daa
KY
6834};
6835
6836
f95474ec
TI
6837/*
6838 * Pin config fixes
6839 */
ea1fb29a 6840enum {
f95474ec
TI
6841 PINFIX_ABIT_AW9D_MAX
6842};
6843
6844static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6845 { 0x15, 0x01080104 }, /* side */
6846 { 0x16, 0x01011012 }, /* rear */
6847 { 0x17, 0x01016011 }, /* clfe */
6848 { }
6849};
6850
6851static const struct alc_pincfg *alc882_pin_fixes[] = {
6852 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6853};
6854
6855static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6856 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6857 {}
6858};
6859
df694daa
KY
6860/*
6861 * BIOS auto configuration
6862 */
6863static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6864 hda_nid_t nid, int pin_type,
6865 int dac_idx)
6866{
6867 /* set as output */
6868 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
6869 int idx;
6870
f6c7e546 6871 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6872 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6873 idx = 4;
6874 else
6875 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
6876 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6877
6878}
6879
6880static void alc882_auto_init_multi_out(struct hda_codec *codec)
6881{
6882 struct alc_spec *spec = codec->spec;
6883 int i;
6884
bc9f98a9 6885 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6886 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6887 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6888 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6889 if (nid)
baba8ee9 6890 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6891 i);
df694daa
KY
6892 }
6893}
6894
6895static void alc882_auto_init_hp_out(struct hda_codec *codec)
6896{
6897 struct alc_spec *spec = codec->spec;
6898 hda_nid_t pin;
6899
eb06ed8f 6900 pin = spec->autocfg.hp_pins[0];
df694daa 6901 if (pin) /* connect to front */
f12ab1e0
TI
6902 /* use dac 0 */
6903 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
6904 pin = spec->autocfg.speaker_pins[0];
6905 if (pin)
6906 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
6907}
6908
6909#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6910#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6911
6912static void alc882_auto_init_analog_input(struct hda_codec *codec)
6913{
6914 struct alc_spec *spec = codec->spec;
6915 int i;
6916
6917 for (i = 0; i < AUTO_PIN_LAST; i++) {
6918 hda_nid_t nid = spec->autocfg.input_pins[i];
7194cae6
TI
6919 unsigned int vref;
6920 if (!nid)
6921 continue;
6922 vref = PIN_IN;
6923 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
531240ff
KY
6924 unsigned int pincap;
6925 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6926 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
7194cae6
TI
6927 AC_PINCAP_VREF_80)
6928 vref = PIN_VREF80;
df694daa 6929 }
7194cae6
TI
6930 snd_hda_codec_write(codec, nid, 0,
6931 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6932 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6933 snd_hda_codec_write(codec, nid, 0,
6934 AC_VERB_SET_AMP_GAIN_MUTE,
6935 AMP_OUT_MUTE);
df694daa
KY
6936 }
6937}
6938
f511b01c
TI
6939static void alc882_auto_init_input_src(struct hda_codec *codec)
6940{
6941 struct alc_spec *spec = codec->spec;
f511b01c
TI
6942 int c;
6943
6944 for (c = 0; c < spec->num_adc_nids; c++) {
6945 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6946 hda_nid_t nid = spec->capsrc_nids[c];
b98b7b34
HRK
6947 unsigned int mux_idx;
6948 const struct hda_input_mux *imux;
f511b01c
TI
6949 int conns, mute, idx, item;
6950
6951 conns = snd_hda_get_connections(codec, nid, conn_list,
6952 ARRAY_SIZE(conn_list));
6953 if (conns < 0)
6954 continue;
b98b7b34
HRK
6955 mux_idx = c >= spec->num_mux_defs ? 0 : c;
6956 imux = &spec->input_mux[mux_idx];
f511b01c
TI
6957 for (idx = 0; idx < conns; idx++) {
6958 /* if the current connection is the selected one,
6959 * unmute it as default - otherwise mute it
6960 */
6961 mute = AMP_IN_MUTE(idx);
6962 for (item = 0; item < imux->num_items; item++) {
6963 if (imux->items[item].index == idx) {
6964 if (spec->cur_mux[c] == item)
6965 mute = AMP_IN_UNMUTE(idx);
6966 break;
6967 }
6968 }
b98b7b34
HRK
6969 /* check if we have a selector or mixer
6970 * we could check for the widget type instead, but
6971 * just check for Amp-In presence (in case of mixer
6972 * without amp-in there is something wrong, this
6973 * function shouldn't be used or capsrc nid is wrong)
6974 */
6975 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
6976 snd_hda_codec_write(codec, nid, 0,
6977 AC_VERB_SET_AMP_GAIN_MUTE,
6978 mute);
6979 else if (mute != AMP_IN_MUTE(idx))
6980 snd_hda_codec_write(codec, nid, 0,
6981 AC_VERB_SET_CONNECT_SEL,
6982 idx);
f511b01c
TI
6983 }
6984 }
6985}
6986
776e184e
TI
6987/* add mic boosts if needed */
6988static int alc_auto_add_mic_boost(struct hda_codec *codec)
6989{
6990 struct alc_spec *spec = codec->spec;
6991 int err;
6992 hda_nid_t nid;
6993
6994 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 6995 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6996 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6997 "Mic Boost",
6998 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6999 if (err < 0)
7000 return err;
7001 }
7002 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 7003 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
7004 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7005 "Front Mic Boost",
7006 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7007 if (err < 0)
7008 return err;
7009 }
7010 return 0;
7011}
7012
df694daa
KY
7013/* almost identical with ALC880 parser... */
7014static int alc882_parse_auto_config(struct hda_codec *codec)
7015{
7016 struct alc_spec *spec = codec->spec;
7017 int err = alc880_parse_auto_config(codec);
7018
7019 if (err < 0)
7020 return err;
776e184e
TI
7021 else if (!err)
7022 return 0; /* no config found */
7023
7024 err = alc_auto_add_mic_boost(codec);
7025 if (err < 0)
7026 return err;
7027
7028 /* hack - override the init verbs */
7029 spec->init_verbs[0] = alc882_auto_init_verbs;
7030
7031 return 1; /* config found */
df694daa
KY
7032}
7033
ae6b813a
TI
7034/* additional initialization for auto-configuration model */
7035static void alc882_auto_init(struct hda_codec *codec)
df694daa 7036{
f6c7e546 7037 struct alc_spec *spec = codec->spec;
df694daa
KY
7038 alc882_auto_init_multi_out(codec);
7039 alc882_auto_init_hp_out(codec);
7040 alc882_auto_init_analog_input(codec);
f511b01c 7041 alc882_auto_init_input_src(codec);
f6c7e546 7042 if (spec->unsol_event)
7fb0d78f 7043 alc_inithook(codec);
df694daa
KY
7044}
7045
7943a8ab
TI
7046static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7047
df694daa
KY
7048static int patch_alc882(struct hda_codec *codec)
7049{
7050 struct alc_spec *spec;
7051 int err, board_config;
7052
7053 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7054 if (spec == NULL)
7055 return -ENOMEM;
7056
7057 codec->spec = spec;
7058
f5fcc13c
TI
7059 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7060 alc882_models,
7061 alc882_cfg_tbl);
df694daa
KY
7062
7063 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
7064 /* Pick up systems that don't supply PCI SSID */
7065 switch (codec->subsystem_id) {
7066 case 0x106b0c00: /* Mac Pro */
7067 board_config = ALC885_MACPRO;
7068 break;
c54728d8 7069 case 0x106b1000: /* iMac 24 */
f3911c5a 7070 case 0x106b2800: /* AppleTV */
3077e44c 7071 case 0x106b3e00: /* iMac 24 Aluminium */
c54728d8
NF
7072 board_config = ALC885_IMAC24;
7073 break;
c7e0757a 7074 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
9c95c43d 7075 case 0x106b00a4: /* MacbookPro4,1 */
87350ad0 7076 case 0x106b2c00: /* Macbook Pro rev3 */
c7e0757a 7077 case 0x106b3600: /* Macbook 3.1 */
2a88464c 7078 case 0x106b3800: /* MacbookPro4,1 - latter revision */
87350ad0
TI
7079 board_config = ALC885_MBP3;
7080 break;
081d17c4 7081 default:
7943a8ab 7082 /* ALC889A is handled better as ALC888-compatible */
669faba2
CM
7083 if (codec->revision_id == 0x100101 ||
7084 codec->revision_id == 0x100103) {
7943a8ab
TI
7085 alc_free(codec);
7086 return patch_alc883(codec);
7087 }
081d17c4
TD
7088 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7089 "trying auto-probe from BIOS...\n");
7090 board_config = ALC882_AUTO;
7091 }
df694daa
KY
7092 }
7093
f95474ec
TI
7094 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7095
df694daa
KY
7096 if (board_config == ALC882_AUTO) {
7097 /* automatic parse from the BIOS config */
7098 err = alc882_parse_auto_config(codec);
7099 if (err < 0) {
7100 alc_free(codec);
7101 return err;
f12ab1e0 7102 } else if (!err) {
9c7f852e
TI
7103 printk(KERN_INFO
7104 "hda_codec: Cannot set up configuration "
7105 "from BIOS. Using base mode...\n");
df694daa
KY
7106 board_config = ALC882_3ST_DIG;
7107 }
7108 }
7109
680cd536
KK
7110 err = snd_hda_attach_beep_device(codec, 0x1);
7111 if (err < 0) {
7112 alc_free(codec);
7113 return err;
7114 }
7115
df694daa
KY
7116 if (board_config != ALC882_AUTO)
7117 setup_preset(spec, &alc882_presets[board_config]);
1da177e4 7118
2f893286
KY
7119 if (codec->vendor_id == 0x10ec0885) {
7120 spec->stream_name_analog = "ALC885 Analog";
7121 spec->stream_name_digital = "ALC885 Digital";
7122 } else {
7123 spec->stream_name_analog = "ALC882 Analog";
7124 spec->stream_name_digital = "ALC882 Digital";
7125 }
7126
df694daa
KY
7127 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7128 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
7129 /* FIXME: setup DAC5 */
7130 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7131 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 7132
df694daa
KY
7133 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7134 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 7135
61b9b9b1 7136 spec->capture_style = CAPT_MIX; /* matrix-style capture */
f12ab1e0 7137 if (!spec->adc_nids && spec->input_mux) {
df694daa 7138 /* check whether NID 0x07 is valid */
4a471b7d 7139 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
7140 /* get type */
7141 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
7142 if (wcap != AC_WID_AUD_IN) {
7143 spec->adc_nids = alc882_adc_nids_alt;
7144 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 7145 spec->capsrc_nids = alc882_capsrc_nids_alt;
df694daa
KY
7146 } else {
7147 spec->adc_nids = alc882_adc_nids;
7148 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 7149 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
7150 }
7151 }
f9e336f6 7152 set_capture_mixer(spec);
1da177e4 7153
2134ea4f
TI
7154 spec->vmaster_nid = 0x0c;
7155
1da177e4 7156 codec->patch_ops = alc_patch_ops;
df694daa 7157 if (board_config == ALC882_AUTO)
ae6b813a 7158 spec->init_hook = alc882_auto_init;
cb53c626
TI
7159#ifdef CONFIG_SND_HDA_POWER_SAVE
7160 if (!spec->loopback.amplist)
7161 spec->loopback.amplist = alc882_loopbacks;
7162#endif
daead538 7163 codec->proc_widget_hook = print_realtek_coef;
df694daa
KY
7164
7165 return 0;
7166}
7167
7168/*
9c7f852e
TI
7169 * ALC883 support
7170 *
7171 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7172 * configuration. Each pin widget can choose any input DACs and a mixer.
7173 * Each ADC is connected from a mixer of all inputs. This makes possible
7174 * 6-channel independent captures.
7175 *
7176 * In addition, an independent DAC for the multi-playback (not used in this
7177 * driver yet).
df694daa 7178 */
9c7f852e
TI
7179#define ALC883_DIGOUT_NID 0x06
7180#define ALC883_DIGIN_NID 0x0a
df694daa 7181
3ab90935
WF
7182#define ALC1200_DIGOUT_NID 0x10
7183
9c7f852e
TI
7184static hda_nid_t alc883_dac_nids[4] = {
7185 /* front, rear, clfe, rear_surr */
f32a19e3 7186 0x02, 0x03, 0x04, 0x05
9c7f852e 7187};
df694daa 7188
9c7f852e
TI
7189static hda_nid_t alc883_adc_nids[2] = {
7190 /* ADC1-2 */
7191 0x08, 0x09,
7192};
f12ab1e0 7193
f9e336f6
TI
7194static hda_nid_t alc883_adc_nids_alt[1] = {
7195 /* ADC1 */
7196 0x08,
7197};
7198
5b2d1eca
VP
7199static hda_nid_t alc883_adc_nids_rev[2] = {
7200 /* ADC2-1 */
7201 0x09, 0x08
7202};
7203
61b9b9b1
HRK
7204#define alc889_adc_nids alc880_adc_nids
7205
e1406348
TI
7206static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7207
5b2d1eca
VP
7208static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7209
61b9b9b1
HRK
7210#define alc889_capsrc_nids alc882_capsrc_nids
7211
9c7f852e
TI
7212/* input MUX */
7213/* FIXME: should be a matrix-type input source selection */
df694daa 7214
9c7f852e
TI
7215static struct hda_input_mux alc883_capture_source = {
7216 .num_items = 4,
7217 .items = {
7218 { "Mic", 0x0 },
7219 { "Front Mic", 0x1 },
7220 { "Line", 0x2 },
7221 { "CD", 0x4 },
7222 },
7223};
bc9f98a9 7224
17bba1b7
J
7225static struct hda_input_mux alc883_3stack_6ch_intel = {
7226 .num_items = 4,
7227 .items = {
7228 { "Mic", 0x1 },
7229 { "Front Mic", 0x0 },
7230 { "Line", 0x2 },
7231 { "CD", 0x4 },
7232 },
7233};
7234
bc9f98a9
KY
7235static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7236 .num_items = 2,
7237 .items = {
7238 { "Mic", 0x1 },
7239 { "Line", 0x2 },
7240 },
7241};
7242
272a527c
KY
7243static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7244 .num_items = 4,
7245 .items = {
7246 { "Mic", 0x0 },
7247 { "iMic", 0x1 },
7248 { "Line", 0x2 },
7249 { "CD", 0x4 },
7250 },
7251};
7252
fb97dc67
J
7253static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7254 .num_items = 2,
7255 .items = {
7256 { "Mic", 0x0 },
7257 { "Int Mic", 0x1 },
7258 },
7259};
7260
e2757d5e
KY
7261static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7262 .num_items = 3,
7263 .items = {
7264 { "Mic", 0x0 },
7265 { "Front Mic", 0x1 },
7266 { "Line", 0x4 },
7267 },
7268};
7269
7270static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7271 .num_items = 2,
7272 .items = {
7273 { "Mic", 0x0 },
7274 { "Line", 0x2 },
7275 },
7276};
7277
9c7f852e
TI
7278/*
7279 * 2ch mode
7280 */
7281static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7282 { 2, NULL }
7283};
7284
7285/*
7286 * 2ch mode
7287 */
7288static struct hda_verb alc883_3ST_ch2_init[] = {
7289 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7290 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7291 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7292 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7293 { } /* end */
7294};
7295
b201131c
TD
7296/*
7297 * 4ch mode
7298 */
7299static struct hda_verb alc883_3ST_ch4_init[] = {
7300 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7301 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7302 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7303 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7304 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7305 { } /* end */
7306};
7307
9c7f852e
TI
7308/*
7309 * 6ch mode
7310 */
7311static struct hda_verb alc883_3ST_ch6_init[] = {
7312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7314 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7315 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7316 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7317 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7318 { } /* end */
7319};
7320
b201131c 7321static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 7322 { 2, alc883_3ST_ch2_init },
b201131c 7323 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
7324 { 6, alc883_3ST_ch6_init },
7325};
7326
17bba1b7
J
7327/*
7328 * 2ch mode
7329 */
7330static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7331 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7332 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7333 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7334 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7335 { } /* end */
7336};
7337
7338/*
7339 * 4ch mode
7340 */
7341static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7342 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7343 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7344 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7345 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7346 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7347 { } /* end */
7348};
7349
7350/*
7351 * 6ch mode
7352 */
7353static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7354 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7355 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7356 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7357 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7358 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7359 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7360 { } /* end */
7361};
7362
7363static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7364 { 2, alc883_3ST_ch2_intel_init },
7365 { 4, alc883_3ST_ch4_intel_init },
7366 { 6, alc883_3ST_ch6_intel_init },
7367};
7368
9c7f852e
TI
7369/*
7370 * 6ch mode
7371 */
7372static struct hda_verb alc883_sixstack_ch6_init[] = {
7373 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7374 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7375 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7376 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7377 { } /* end */
7378};
7379
7380/*
7381 * 8ch mode
7382 */
7383static struct hda_verb alc883_sixstack_ch8_init[] = {
7384 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7385 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7386 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7387 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7388 { } /* end */
7389};
7390
7391static struct hda_channel_mode alc883_sixstack_modes[2] = {
7392 { 6, alc883_sixstack_ch6_init },
7393 { 8, alc883_sixstack_ch8_init },
7394};
7395
b373bdeb
AN
7396static struct hda_verb alc883_medion_eapd_verbs[] = {
7397 /* eanable EAPD on medion laptop */
7398 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7399 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7400 { }
7401};
7402
9c7f852e
TI
7403/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7404 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7405 */
7406
7407static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 7408 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
7409 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7410 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7411 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7412 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7413 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7414 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7415 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7416 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7417 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7418 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
7419 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7420 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7424 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 7425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 7426 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7427 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7429 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7430 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
df694daa 7431 { } /* end */
834be88d
TI
7432};
7433
a8848bd6
AS
7434static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7436 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7437 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7438 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7439 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7440 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7441 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7443 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7444 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7445 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7446 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7447 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
7448 { } /* end */
7449};
7450
0c4cc443 7451static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
7452 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7453 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7454 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7455 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7457 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7459 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7460 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7461 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
7462 { } /* end */
7463};
7464
fb97dc67
J
7465static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7466 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7467 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7468 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7469 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7470 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7471 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7472 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7473 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7474 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7475 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
7476 { } /* end */
7477};
7478
9c7f852e
TI
7479static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7480 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7481 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7482 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7483 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7484 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7485 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7486 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7487 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7488 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7489 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7490 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7491 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7492 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7493 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7494 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9c7f852e
TI
7495 { } /* end */
7496};
df694daa 7497
9c7f852e
TI
7498static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7499 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7500 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7501 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7502 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7503 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7504 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7505 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7506 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7508 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7509 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7510 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7511 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7513 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7515 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7516 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7517 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7518 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7519 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9c7f852e
TI
7520 { } /* end */
7521};
7522
17bba1b7
J
7523static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7524 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7525 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7526 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7527 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7528 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7529 HDA_OUTPUT),
7530 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7531 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7532 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7533 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7534 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7535 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7536 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7537 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7538 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7539 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7540 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7541 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7542 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7543 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7544 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7545 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
17bba1b7
J
7546 { } /* end */
7547};
7548
d1d985f0 7549static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 7550 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 7551 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 7552 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 7553 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
7554 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7555 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
7556 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7557 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
7558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7559 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7560 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7561 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7562 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7564 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
7565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7566 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7567 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
7568 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7569 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7570 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
c07584c8
TD
7571 { } /* end */
7572};
7573
ccc656ce
KY
7574static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7575 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7577 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7578 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7579 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7580 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7581 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7582 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7583 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7589 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 7591 { } /* end */
f12ab1e0 7592};
ccc656ce
KY
7593
7594static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7595 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7597 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7598 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7599 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7601 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7602 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
7603 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7604 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7605 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 7606 { } /* end */
f12ab1e0 7607};
ccc656ce 7608
bc9f98a9
KY
7609static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7610 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7611 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
7612 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7613 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
7614 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7615 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7616 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 7618 { } /* end */
f12ab1e0 7619};
bc9f98a9 7620
272a527c
KY
7621static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7622 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7623 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7624 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7625 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7626 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7629 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7630 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
7631 { } /* end */
7632};
7633
7634static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7635 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7636 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7637 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7638 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7639 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7641 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 7644 { } /* end */
ea1fb29a 7645};
272a527c 7646
2880a867 7647static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7648 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7649 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7651 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7652 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7653 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7654 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 7656 { } /* end */
d1a991a6 7657};
2880a867 7658
e2757d5e
KY
7659static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7660 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7661 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7662 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7663 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7664 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7665 0x0d, 1, 0x0, HDA_OUTPUT),
7666 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7667 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7668 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7669 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7670 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7672 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7678 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7680 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7681 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7682 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
7683 { } /* end */
7684};
7685
7686static struct hda_bind_ctls alc883_bind_cap_vol = {
7687 .ops = &snd_hda_bind_vol,
7688 .values = {
7689 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7690 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7691 0
7692 },
7693};
7694
7695static struct hda_bind_ctls alc883_bind_cap_switch = {
7696 .ops = &snd_hda_bind_sw,
7697 .values = {
7698 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7699 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7700 0
7701 },
7702};
7703
7704static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7705 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7706 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7707 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7711 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7712 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f9e336f6
TI
7713 { } /* end */
7714};
7715
7716static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
e2757d5e
KY
7717 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7718 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7719 {
7720 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7721 /* .name = "Capture Source", */
7722 .name = "Input Source",
7723 .count = 1,
54cbc9ab
TI
7724 .info = alc_mux_enum_info,
7725 .get = alc_mux_enum_get,
7726 .put = alc_mux_enum_put,
e2757d5e
KY
7727 },
7728 { } /* end */
7729};
7730
9c7f852e
TI
7731static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7732 {
7733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7734 .name = "Channel Mode",
7735 .info = alc_ch_mode_info,
7736 .get = alc_ch_mode_get,
7737 .put = alc_ch_mode_put,
7738 },
7739 { } /* end */
7740};
7741
7742static struct hda_verb alc883_init_verbs[] = {
7743 /* ADC1: mute amp left and right */
e2757d5e 7744 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
df694daa 7745 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7746 /* ADC2: mute amp left and right */
7747 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7748 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7749 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7750 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7753 /* Rear mixer */
7754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7757 /* CLFE mixer */
7758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7760 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7761 /* Side mixer */
7762 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7763 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7765
cb53c626
TI
7766 /* mute analog input loopbacks */
7767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7771 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7772
9c7f852e
TI
7773 /* Front Pin: output 0 (0x0c) */
7774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7776 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7777 /* Rear Pin: output 1 (0x0d) */
7778 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7779 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7780 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7781 /* CLFE Pin: output 2 (0x0e) */
7782 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7783 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7784 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7785 /* Side Pin: output 3 (0x0f) */
7786 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7787 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7788 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7789 /* Mic (rear) pin: input vref at 80% */
7790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7791 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7792 /* Front Mic pin: input vref at 80% */
7793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7794 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7795 /* Line In pin: input */
7796 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7797 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7798 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7799 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7800 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7801 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7802 /* CD pin widget for input */
7803 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7804
7805 /* FIXME: use matrix-type input source selection */
7806 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7807 /* Input mixer2 */
7808 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
7809 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7810 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7811 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7812 /* Input mixer3 */
7813 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
7814 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7817 { }
7818};
7819
a8848bd6
AS
7820/* toggle speaker-output according to the hp-jack state */
7821static void alc883_mitac_hp_automute(struct hda_codec *codec)
7822{
7823 unsigned int present;
7824
7825 present = snd_hda_codec_read(codec, 0x15, 0,
7826 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7827 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7828 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7829 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7830 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7831}
7832
7833/* auto-toggle front mic */
7834/*
7835static void alc883_mitac_mic_automute(struct hda_codec *codec)
7836{
7837 unsigned int present;
7838 unsigned char bits;
7839
7840 present = snd_hda_codec_read(codec, 0x18, 0,
7841 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7842 bits = present ? HDA_AMP_MUTE : 0;
7843 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7844}
7845*/
7846
7847static void alc883_mitac_automute(struct hda_codec *codec)
7848{
7849 alc883_mitac_hp_automute(codec);
7850 /* alc883_mitac_mic_automute(codec); */
7851}
7852
7853static void alc883_mitac_unsol_event(struct hda_codec *codec,
7854 unsigned int res)
7855{
7856 switch (res >> 26) {
7857 case ALC880_HP_EVENT:
7858 alc883_mitac_hp_automute(codec);
7859 break;
7860 case ALC880_MIC_EVENT:
7861 /* alc883_mitac_mic_automute(codec); */
7862 break;
7863 }
7864}
7865
7866static struct hda_verb alc883_mitac_verbs[] = {
7867 /* HP */
7868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7869 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7870 /* Subwoofer */
7871 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7872 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7873
7874 /* enable unsolicited event */
7875 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7876 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7877
7878 { } /* end */
7879};
7880
0c4cc443 7881static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
7882 /* HP */
7883 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7885 /* Int speaker */
7886 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7888
7889 /* enable unsolicited event */
7890 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 7891 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
7892
7893 { } /* end */
7894};
7895
fb97dc67
J
7896static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7897 /* HP */
7898 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7899 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7900 /* Subwoofer */
7901 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7902 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7903
7904 /* enable unsolicited event */
7905 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7906
7907 { } /* end */
7908};
7909
ccc656ce
KY
7910static struct hda_verb alc883_tagra_verbs[] = {
7911 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7912 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7913
7914 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7915 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7916
ccc656ce
KY
7917 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7918 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7919 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7920
7921 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
7922 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7923 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7924 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
7925
7926 { } /* end */
7927};
7928
bc9f98a9
KY
7929static struct hda_verb alc883_lenovo_101e_verbs[] = {
7930 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7931 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7932 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7933 { } /* end */
7934};
7935
272a527c
KY
7936static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7937 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7938 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7939 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7940 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7941 { } /* end */
7942};
7943
7944static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7946 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7947 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7948 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7949 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7950 { } /* end */
7951};
7952
189609ae
KY
7953static struct hda_verb alc883_haier_w66_verbs[] = {
7954 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7955 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7956
7957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7958
7959 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7961 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7962 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7963 { } /* end */
7964};
7965
e2757d5e
KY
7966static struct hda_verb alc888_lenovo_sky_verbs[] = {
7967 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7968 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7969 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7971 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7972 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7973 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7974 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7975 { } /* end */
7976};
7977
4723c022 7978static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 7979 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
7980 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7981 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8341de60
CM
7982 { }
7983};
7984
5795b9e6 7985static struct hda_verb alc888_6st_dell_verbs[] = {
5795b9e6
CM
7986 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7987 { }
7988};
7989
4723c022 7990static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7991 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7992 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7993 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7994 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7995 { }
7996};
7997
4723c022 7998static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7999 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8000 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8001 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8002 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8003 { }
8004};
8005
4723c022
CM
8006static struct hda_channel_mode alc888_3st_hp_modes[2] = {
8007 { 2, alc888_3st_hp_2ch_init },
8008 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
8009};
8010
272a527c
KY
8011/* toggle front-jack and RCA according to the hp-jack state */
8012static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8013{
8014 unsigned int present;
ea1fb29a 8015
272a527c
KY
8016 present = snd_hda_codec_read(codec, 0x1b, 0,
8017 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8018 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8019 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8020 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8021 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8022}
8023
8024/* toggle RCA according to the front-jack state */
8025static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8026{
8027 unsigned int present;
ea1fb29a 8028
272a527c
KY
8029 present = snd_hda_codec_read(codec, 0x14, 0,
8030 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8031 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8032 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 8033}
47fd830a 8034
272a527c
KY
8035static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8036 unsigned int res)
8037{
8038 if ((res >> 26) == ALC880_HP_EVENT)
8039 alc888_lenovo_ms7195_front_automute(codec);
8040 if ((res >> 26) == ALC880_FRONT_EVENT)
8041 alc888_lenovo_ms7195_rca_automute(codec);
8042}
8043
8044static struct hda_verb alc883_medion_md2_verbs[] = {
8045 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8047
8048 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8049
8050 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8051 { } /* end */
8052};
8053
8054/* toggle speaker-output according to the hp-jack state */
8055static void alc883_medion_md2_automute(struct hda_codec *codec)
8056{
8057 unsigned int present;
ea1fb29a 8058
272a527c
KY
8059 present = snd_hda_codec_read(codec, 0x14, 0,
8060 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8061 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8062 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8063}
8064
8065static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8066 unsigned int res)
8067{
8068 if ((res >> 26) == ALC880_HP_EVENT)
8069 alc883_medion_md2_automute(codec);
8070}
8071
ccc656ce
KY
8072/* toggle speaker-output according to the hp-jack state */
8073static void alc883_tagra_automute(struct hda_codec *codec)
8074{
8075 unsigned int present;
f12ab1e0 8076 unsigned char bits;
ccc656ce
KY
8077
8078 present = snd_hda_codec_read(codec, 0x14, 0,
8079 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8080 bits = present ? HDA_AMP_MUTE : 0;
8081 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8082 HDA_AMP_MUTE, bits);
82beb8fd
TI
8083 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8084 present ? 1 : 3);
ccc656ce
KY
8085}
8086
8087static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
8088{
8089 if ((res >> 26) == ALC880_HP_EVENT)
8090 alc883_tagra_automute(codec);
8091}
8092
368c7a95 8093/* toggle speaker-output according to the hp-jack state */
0c4cc443 8094static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
368c7a95
J
8095{
8096 unsigned int present;
8097 unsigned char bits;
8098
8099 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8100 & AC_PINSENSE_PRESENCE;
8101 bits = present ? HDA_AMP_MUTE : 0;
8102 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8103 HDA_AMP_MUTE, bits);
8104}
8105
0c4cc443
HRK
8106static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8107{
8108 unsigned int present;
8109
8110 present = snd_hda_codec_read(codec, 0x18, 0,
8111 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8112 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8113 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8114}
8115
8116static void alc883_clevo_m720_automute(struct hda_codec *codec)
8117{
8118 alc883_clevo_m720_hp_automute(codec);
8119 alc883_clevo_m720_mic_automute(codec);
8120}
8121
8122static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8123 unsigned int res)
8124{
0c4cc443
HRK
8125 switch (res >> 26) {
8126 case ALC880_HP_EVENT:
8127 alc883_clevo_m720_hp_automute(codec);
8128 break;
8129 case ALC880_MIC_EVENT:
8130 alc883_clevo_m720_mic_automute(codec);
8131 break;
8132 }
368c7a95
J
8133}
8134
fb97dc67
J
8135/* toggle speaker-output according to the hp-jack state */
8136static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8137{
8138 unsigned int present;
8139 unsigned char bits;
8140
8141 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8142 & AC_PINSENSE_PRESENCE;
8143 bits = present ? HDA_AMP_MUTE : 0;
8144 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8145 HDA_AMP_MUTE, bits);
8146}
8147
8148static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8149 unsigned int res)
8150{
8151 if ((res >> 26) == ALC880_HP_EVENT)
8152 alc883_2ch_fujitsu_pi2515_automute(codec);
8153}
8154
189609ae
KY
8155static void alc883_haier_w66_automute(struct hda_codec *codec)
8156{
8157 unsigned int present;
8158 unsigned char bits;
8159
8160 present = snd_hda_codec_read(codec, 0x1b, 0,
8161 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8162 bits = present ? 0x80 : 0;
8163 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8164 0x80, bits);
8165}
8166
8167static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8168 unsigned int res)
8169{
8170 if ((res >> 26) == ALC880_HP_EVENT)
8171 alc883_haier_w66_automute(codec);
8172}
8173
bc9f98a9
KY
8174static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8175{
8176 unsigned int present;
f12ab1e0 8177 unsigned char bits;
bc9f98a9
KY
8178
8179 present = snd_hda_codec_read(codec, 0x14, 0,
8180 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8181 bits = present ? HDA_AMP_MUTE : 0;
8182 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8183 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8184}
8185
8186static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8187{
8188 unsigned int present;
f12ab1e0 8189 unsigned char bits;
bc9f98a9
KY
8190
8191 present = snd_hda_codec_read(codec, 0x1b, 0,
8192 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8193 bits = present ? HDA_AMP_MUTE : 0;
8194 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8195 HDA_AMP_MUTE, bits);
8196 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8197 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8198}
8199
8200static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8201 unsigned int res)
8202{
8203 if ((res >> 26) == ALC880_HP_EVENT)
8204 alc883_lenovo_101e_all_automute(codec);
8205 if ((res >> 26) == ALC880_FRONT_EVENT)
8206 alc883_lenovo_101e_ispeaker_automute(codec);
8207}
8208
676a9b53
TI
8209/* toggle speaker-output according to the hp-jack state */
8210static void alc883_acer_aspire_automute(struct hda_codec *codec)
8211{
8212 unsigned int present;
ea1fb29a 8213
676a9b53
TI
8214 present = snd_hda_codec_read(codec, 0x14, 0,
8215 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8216 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8217 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8218 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8219 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8220}
8221
8222static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8223 unsigned int res)
8224{
8225 if ((res >> 26) == ALC880_HP_EVENT)
8226 alc883_acer_aspire_automute(codec);
8227}
8228
d1a991a6
KY
8229static struct hda_verb alc883_acer_eapd_verbs[] = {
8230 /* HP Pin: output 0 (0x0c) */
8231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8233 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8234 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
8235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8236 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 8237 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
8238 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8239 /* eanable EAPD on medion laptop */
8240 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8241 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
8242 /* enable unsolicited event */
8243 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
8244 { }
8245};
8246
5795b9e6
CM
8247static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8248{
8249 unsigned int present;
ea1fb29a 8250
5795b9e6
CM
8251 present = snd_hda_codec_read(codec, 0x1b, 0,
8252 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8253 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8254 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8255 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8256 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8257 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8258 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8259 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8260 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8261}
8262
8263static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8264 unsigned int res)
8265{
8266 switch (res >> 26) {
8267 case ALC880_HP_EVENT:
939778ae 8268 /* printk(KERN_DEBUG "hp_event\n"); */
5795b9e6
CM
8269 alc888_6st_dell_front_automute(codec);
8270 break;
8271 }
8272}
8273
e2757d5e
KY
8274static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8275{
8276 unsigned int mute;
8277 unsigned int present;
8278
8279 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8280 present = snd_hda_codec_read(codec, 0x1b, 0,
8281 AC_VERB_GET_PIN_SENSE, 0);
8282 present = (present & 0x80000000) != 0;
8283 if (present) {
8284 /* mute internal speaker */
8285 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8286 HDA_AMP_MUTE, HDA_AMP_MUTE);
8287 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8288 HDA_AMP_MUTE, HDA_AMP_MUTE);
8289 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8290 HDA_AMP_MUTE, HDA_AMP_MUTE);
8291 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8292 HDA_AMP_MUTE, HDA_AMP_MUTE);
8293 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8294 HDA_AMP_MUTE, HDA_AMP_MUTE);
8295 } else {
8296 /* unmute internal speaker if necessary */
8297 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8298 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8299 HDA_AMP_MUTE, mute);
8300 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8301 HDA_AMP_MUTE, mute);
8302 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8303 HDA_AMP_MUTE, mute);
8304 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8305 HDA_AMP_MUTE, mute);
8306 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8307 HDA_AMP_MUTE, mute);
8308 }
8309}
8310
8311static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8312 unsigned int res)
8313{
8314 if ((res >> 26) == ALC880_HP_EVENT)
8315 alc888_lenovo_sky_front_automute(codec);
8316}
8317
9c7f852e
TI
8318/*
8319 * generic initialization of ADC, input mixers and output mixers
8320 */
8321static struct hda_verb alc883_auto_init_verbs[] = {
8322 /*
8323 * Unmute ADC0-2 and set the default input to mic-in
8324 */
8325 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8326 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8327 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8329
cb53c626 8330 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8331 * mixer widget
f12ab1e0
TI
8332 * Note: PASD motherboards uses the Line In 2 as the input for
8333 * front panel mic (mic 2)
9c7f852e
TI
8334 */
8335 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8341
8342 /*
8343 * Set up output mixers (0x0c - 0x0f)
8344 */
8345 /* set vol=0 to output mixers */
8346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8347 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8349 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8350 /* set up input amps for analog loopback */
8351 /* Amp Indices: DAC = 0, mixer = 1 */
8352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8355 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8356 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8358 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8359 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8360 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8361 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8362
8363 /* FIXME: use matrix-type input source selection */
8364 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8365 /* Input mixer1 */
8366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8369 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
8370 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8371 /* Input mixer2 */
8372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8375 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 8376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
8377
8378 { }
8379};
8380
e2757d5e
KY
8381static struct hda_verb alc888_asus_m90v_verbs[] = {
8382 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8384 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8385 /* enable unsolicited event */
8386 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8387 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8388 { } /* end */
8389};
8390
8391static void alc883_nb_mic_automute(struct hda_codec *codec)
8392{
8393 unsigned int present;
8394
8395 present = snd_hda_codec_read(codec, 0x18, 0,
8396 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8397 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8398 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8399 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8400 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8401}
8402
8403static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8404{
8405 unsigned int present;
8406 unsigned char bits;
8407
8408 present = snd_hda_codec_read(codec, 0x1b, 0,
8409 AC_VERB_GET_PIN_SENSE, 0)
8410 & AC_PINSENSE_PRESENCE;
8411 bits = present ? 0 : PIN_OUT;
8412 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8413 bits);
8414 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8415 bits);
8416 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8417 bits);
8418}
8419
8420static void alc883_mode2_unsol_event(struct hda_codec *codec,
8421 unsigned int res)
8422{
8423 switch (res >> 26) {
8424 case ALC880_HP_EVENT:
8425 alc883_M90V_speaker_automute(codec);
8426 break;
8427 case ALC880_MIC_EVENT:
8428 alc883_nb_mic_automute(codec);
8429 break;
8430 }
8431}
8432
8433static void alc883_mode2_inithook(struct hda_codec *codec)
8434{
8435 alc883_M90V_speaker_automute(codec);
8436 alc883_nb_mic_automute(codec);
8437}
8438
8439static struct hda_verb alc888_asus_eee1601_verbs[] = {
8440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8441 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8442 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8443 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8444 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8445 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8446 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8447 /* enable unsolicited event */
8448 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8449 { } /* end */
8450};
8451
8452static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8453{
8454 unsigned int present;
8455 unsigned char bits;
8456
8457 present = snd_hda_codec_read(codec, 0x14, 0,
8458 AC_VERB_GET_PIN_SENSE, 0)
8459 & AC_PINSENSE_PRESENCE;
8460 bits = present ? 0 : PIN_OUT;
8461 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8462 bits);
8463}
8464
8465static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8466 unsigned int res)
8467{
8468 switch (res >> 26) {
8469 case ALC880_HP_EVENT:
8470 alc883_eee1601_speaker_automute(codec);
8471 break;
8472 }
8473}
8474
8475static void alc883_eee1601_inithook(struct hda_codec *codec)
8476{
8477 alc883_eee1601_speaker_automute(codec);
8478}
8479
cb53c626
TI
8480#ifdef CONFIG_SND_HDA_POWER_SAVE
8481#define alc883_loopbacks alc880_loopbacks
8482#endif
8483
9c7f852e
TI
8484/* pcm configuration: identiacal with ALC880 */
8485#define alc883_pcm_analog_playback alc880_pcm_analog_playback
8486#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 8487#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
8488#define alc883_pcm_digital_playback alc880_pcm_digital_playback
8489#define alc883_pcm_digital_capture alc880_pcm_digital_capture
8490
8491/*
8492 * configuration and preset
8493 */
f5fcc13c
TI
8494static const char *alc883_models[ALC883_MODEL_LAST] = {
8495 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8496 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8497 [ALC883_3ST_6ch] = "3stack-6ch",
8498 [ALC883_6ST_DIG] = "6stack-dig",
8499 [ALC883_TARGA_DIG] = "targa-dig",
8500 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 8501 [ALC883_ACER] = "acer",
2880a867 8502 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 8503 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
f5fcc13c 8504 [ALC883_MEDION] = "medion",
272a527c 8505 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 8506 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 8507 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
8508 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8509 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 8510 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 8511 [ALC883_HAIER_W66] = "haier-w66",
4723c022 8512 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 8513 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 8514 [ALC883_MITAC] = "mitac",
0c4cc443 8515 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 8516 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 8517 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 8518 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
3ab90935 8519 [ALC1200_ASUS_P5Q] = "asus-p5q",
f5fcc13c
TI
8520 [ALC883_AUTO] = "auto",
8521};
8522
8523static struct snd_pci_quirk alc883_cfg_tbl[] = {
8524 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741 8525 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 8526 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
ac3e3741
TI
8527 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8528 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 8529 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
8530 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8531 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd
LW
8532 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8533 ALC888_ACER_ASPIRE_4930G),
8534 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8535 ALC888_ACER_ASPIRE_4930G),
ac3e3741 8536 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
5795b9e6 8537 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 8538 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
8539 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8540 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 8541 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 8542 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
a01c30cb 8543 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
ac3e3741 8544 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
3ab90935 8545 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 8546 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
97ec710c 8547 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
f5fcc13c 8548 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
2de686d2 8549 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
8550 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8551 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 8552 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 8553 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 8554 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 8555 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 8556 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8557 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4383fae0 8558 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 8559 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 8560 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 8561 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8562 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8563 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8564 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 8565 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 8566 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8567 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8568 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8569 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
8570 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8571 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8572 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 8573 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 8574 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8575 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8576 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 8577 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8578 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
8579 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8580 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
ac3e3741 8581 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 8582 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 8583 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
f67d8176
TI
8584 SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550",
8585 ALC883_FUJITSU_PI2515),
fb97dc67 8586 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
ef8ef5fb
VP
8587 SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530",
8588 ALC888_FUJITSU_XA3530),
272a527c 8589 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 8590 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
8591 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8592 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 8593 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 8594 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 8595 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 8596 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 8597 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
17bba1b7
J
8598 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8599 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 8600 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
4b558991 8601 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
ac3e3741 8602 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
8603 {}
8604};
8605
8606static struct alc_config_preset alc883_presets[] = {
8607 [ALC883_3ST_2ch_DIG] = {
8608 .mixers = { alc883_3ST_2ch_mixer },
8609 .init_verbs = { alc883_init_verbs },
8610 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8611 .dac_nids = alc883_dac_nids,
8612 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8613 .dig_in_nid = ALC883_DIGIN_NID,
8614 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8615 .channel_mode = alc883_3ST_2ch_modes,
8616 .input_mux = &alc883_capture_source,
8617 },
8618 [ALC883_3ST_6ch_DIG] = {
8619 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8620 .init_verbs = { alc883_init_verbs },
8621 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8622 .dac_nids = alc883_dac_nids,
8623 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8624 .dig_in_nid = ALC883_DIGIN_NID,
8625 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8626 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8627 .need_dac_fix = 1,
9c7f852e 8628 .input_mux = &alc883_capture_source,
f12ab1e0 8629 },
9c7f852e
TI
8630 [ALC883_3ST_6ch] = {
8631 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8632 .init_verbs = { alc883_init_verbs },
8633 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8634 .dac_nids = alc883_dac_nids,
9c7f852e
TI
8635 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8636 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8637 .need_dac_fix = 1,
9c7f852e 8638 .input_mux = &alc883_capture_source,
f12ab1e0 8639 },
17bba1b7
J
8640 [ALC883_3ST_6ch_INTEL] = {
8641 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8642 .init_verbs = { alc883_init_verbs },
8643 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8644 .dac_nids = alc883_dac_nids,
8645 .dig_out_nid = ALC883_DIGOUT_NID,
8646 .dig_in_nid = ALC883_DIGIN_NID,
8647 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8648 .channel_mode = alc883_3ST_6ch_intel_modes,
8649 .need_dac_fix = 1,
8650 .input_mux = &alc883_3stack_6ch_intel,
8651 },
9c7f852e
TI
8652 [ALC883_6ST_DIG] = {
8653 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8654 .init_verbs = { alc883_init_verbs },
8655 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8656 .dac_nids = alc883_dac_nids,
8657 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8658 .dig_in_nid = ALC883_DIGIN_NID,
8659 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8660 .channel_mode = alc883_sixstack_modes,
8661 .input_mux = &alc883_capture_source,
8662 },
ccc656ce
KY
8663 [ALC883_TARGA_DIG] = {
8664 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8665 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8666 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8667 .dac_nids = alc883_dac_nids,
8668 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8669 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8670 .channel_mode = alc883_3ST_6ch_modes,
8671 .need_dac_fix = 1,
8672 .input_mux = &alc883_capture_source,
8673 .unsol_event = alc883_tagra_unsol_event,
8674 .init_hook = alc883_tagra_automute,
8675 },
8676 [ALC883_TARGA_2ch_DIG] = {
8677 .mixers = { alc883_tagra_2ch_mixer},
8678 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8679 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8680 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8681 .adc_nids = alc883_adc_nids_alt,
8682 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
ccc656ce 8683 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8684 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8685 .channel_mode = alc883_3ST_2ch_modes,
8686 .input_mux = &alc883_capture_source,
8687 .unsol_event = alc883_tagra_unsol_event,
8688 .init_hook = alc883_tagra_automute,
8689 },
bab282b9 8690 [ALC883_ACER] = {
676a9b53 8691 .mixers = { alc883_base_mixer },
bab282b9
VA
8692 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8693 * and the headphone jack. Turn this on and rely on the
8694 * standard mute methods whenever the user wants to turn
8695 * these outputs off.
8696 */
8697 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8698 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8699 .dac_nids = alc883_dac_nids,
bab282b9
VA
8700 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8701 .channel_mode = alc883_3ST_2ch_modes,
8702 .input_mux = &alc883_capture_source,
8703 },
2880a867 8704 [ALC883_ACER_ASPIRE] = {
676a9b53 8705 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 8706 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
8707 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8708 .dac_nids = alc883_dac_nids,
8709 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
8710 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8711 .channel_mode = alc883_3ST_2ch_modes,
8712 .input_mux = &alc883_capture_source,
676a9b53
TI
8713 .unsol_event = alc883_acer_aspire_unsol_event,
8714 .init_hook = alc883_acer_aspire_automute,
d1a991a6 8715 },
5b2d1eca 8716 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 8717 .mixers = { alc888_base_mixer,
5b2d1eca
VP
8718 alc883_chmode_mixer },
8719 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8720 alc888_acer_aspire_4930g_verbs },
8721 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8722 .dac_nids = alc883_dac_nids,
8723 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8724 .adc_nids = alc883_adc_nids_rev,
8725 .capsrc_nids = alc883_capsrc_nids_rev,
8726 .dig_out_nid = ALC883_DIGOUT_NID,
8727 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8728 .channel_mode = alc883_3ST_6ch_modes,
8729 .need_dac_fix = 1,
8730 .num_mux_defs =
ef8ef5fb
VP
8731 ARRAY_SIZE(alc888_2_capture_sources),
8732 .input_mux = alc888_2_capture_sources,
5b2d1eca
VP
8733 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8734 .init_hook = alc888_acer_aspire_4930g_automute,
8735 },
c07584c8
TD
8736 [ALC883_MEDION] = {
8737 .mixers = { alc883_fivestack_mixer,
8738 alc883_chmode_mixer },
8739 .init_verbs = { alc883_init_verbs,
b373bdeb 8740 alc883_medion_eapd_verbs },
c07584c8
TD
8741 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8742 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8743 .adc_nids = alc883_adc_nids_alt,
8744 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
c07584c8
TD
8745 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8746 .channel_mode = alc883_sixstack_modes,
8747 .input_mux = &alc883_capture_source,
b373bdeb 8748 },
272a527c
KY
8749 [ALC883_MEDION_MD2] = {
8750 .mixers = { alc883_medion_md2_mixer},
8751 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8752 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8753 .dac_nids = alc883_dac_nids,
8754 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8755 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8756 .channel_mode = alc883_3ST_2ch_modes,
8757 .input_mux = &alc883_capture_source,
8758 .unsol_event = alc883_medion_md2_unsol_event,
8759 .init_hook = alc883_medion_md2_automute,
ea1fb29a 8760 },
b373bdeb 8761 [ALC883_LAPTOP_EAPD] = {
676a9b53 8762 .mixers = { alc883_base_mixer },
b373bdeb
AN
8763 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8764 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8765 .dac_nids = alc883_dac_nids,
b373bdeb
AN
8766 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8767 .channel_mode = alc883_3ST_2ch_modes,
8768 .input_mux = &alc883_capture_source,
8769 },
0c4cc443
HRK
8770 [ALC883_CLEVO_M720] = {
8771 .mixers = { alc883_clevo_m720_mixer },
8772 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
8773 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8774 .dac_nids = alc883_dac_nids,
8775 .dig_out_nid = ALC883_DIGOUT_NID,
8776 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8777 .channel_mode = alc883_3ST_2ch_modes,
8778 .input_mux = &alc883_capture_source,
0c4cc443
HRK
8779 .unsol_event = alc883_clevo_m720_unsol_event,
8780 .init_hook = alc883_clevo_m720_automute,
368c7a95 8781 },
bc9f98a9
KY
8782 [ALC883_LENOVO_101E_2ch] = {
8783 .mixers = { alc883_lenovo_101e_2ch_mixer},
8784 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8786 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8787 .adc_nids = alc883_adc_nids_alt,
8788 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
bc9f98a9
KY
8789 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8790 .channel_mode = alc883_3ST_2ch_modes,
8791 .input_mux = &alc883_lenovo_101e_capture_source,
8792 .unsol_event = alc883_lenovo_101e_unsol_event,
8793 .init_hook = alc883_lenovo_101e_all_automute,
8794 },
272a527c
KY
8795 [ALC883_LENOVO_NB0763] = {
8796 .mixers = { alc883_lenovo_nb0763_mixer },
8797 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8798 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8799 .dac_nids = alc883_dac_nids,
272a527c
KY
8800 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8801 .channel_mode = alc883_3ST_2ch_modes,
8802 .need_dac_fix = 1,
8803 .input_mux = &alc883_lenovo_nb0763_capture_source,
8804 .unsol_event = alc883_medion_md2_unsol_event,
8805 .init_hook = alc883_medion_md2_automute,
8806 },
8807 [ALC888_LENOVO_MS7195_DIG] = {
8808 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8809 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8810 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8811 .dac_nids = alc883_dac_nids,
8812 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8813 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8814 .channel_mode = alc883_3ST_6ch_modes,
8815 .need_dac_fix = 1,
8816 .input_mux = &alc883_capture_source,
8817 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8818 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
8819 },
8820 [ALC883_HAIER_W66] = {
8821 .mixers = { alc883_tagra_2ch_mixer},
8822 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8823 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8824 .dac_nids = alc883_dac_nids,
8825 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
8826 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8827 .channel_mode = alc883_3ST_2ch_modes,
8828 .input_mux = &alc883_capture_source,
8829 .unsol_event = alc883_haier_w66_unsol_event,
8830 .init_hook = alc883_haier_w66_automute,
eea6419e 8831 },
4723c022 8832 [ALC888_3ST_HP] = {
eea6419e 8833 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 8834 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
8835 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8836 .dac_nids = alc883_dac_nids,
4723c022
CM
8837 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8838 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
8839 .need_dac_fix = 1,
8840 .input_mux = &alc883_capture_source,
8841 },
5795b9e6 8842 [ALC888_6ST_DELL] = {
f24dbdc6 8843 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
8844 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8845 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8846 .dac_nids = alc883_dac_nids,
8847 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
8848 .dig_in_nid = ALC883_DIGIN_NID,
8849 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8850 .channel_mode = alc883_sixstack_modes,
8851 .input_mux = &alc883_capture_source,
8852 .unsol_event = alc888_6st_dell_unsol_event,
8853 .init_hook = alc888_6st_dell_front_automute,
8854 },
a8848bd6
AS
8855 [ALC883_MITAC] = {
8856 .mixers = { alc883_mitac_mixer },
8857 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8859 .dac_nids = alc883_dac_nids,
a8848bd6
AS
8860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8861 .channel_mode = alc883_3ST_2ch_modes,
8862 .input_mux = &alc883_capture_source,
8863 .unsol_event = alc883_mitac_unsol_event,
8864 .init_hook = alc883_mitac_automute,
8865 },
fb97dc67
J
8866 [ALC883_FUJITSU_PI2515] = {
8867 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8868 .init_verbs = { alc883_init_verbs,
8869 alc883_2ch_fujitsu_pi2515_verbs},
8870 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8871 .dac_nids = alc883_dac_nids,
8872 .dig_out_nid = ALC883_DIGOUT_NID,
8873 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8874 .channel_mode = alc883_3ST_2ch_modes,
8875 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8876 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8877 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8878 },
ef8ef5fb
VP
8879 [ALC888_FUJITSU_XA3530] = {
8880 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8881 .init_verbs = { alc883_init_verbs,
8882 alc888_fujitsu_xa3530_verbs },
8883 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8884 .dac_nids = alc883_dac_nids,
8885 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8886 .adc_nids = alc883_adc_nids_rev,
8887 .capsrc_nids = alc883_capsrc_nids_rev,
8888 .dig_out_nid = ALC883_DIGOUT_NID,
8889 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8890 .channel_mode = alc888_4ST_8ch_intel_modes,
8891 .num_mux_defs =
8892 ARRAY_SIZE(alc888_2_capture_sources),
8893 .input_mux = alc888_2_capture_sources,
8894 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
8895 .init_hook = alc888_fujitsu_xa3530_automute,
8896 },
e2757d5e
KY
8897 [ALC888_LENOVO_SKY] = {
8898 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8899 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8900 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8901 .dac_nids = alc883_dac_nids,
8902 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
8903 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8904 .channel_mode = alc883_sixstack_modes,
8905 .need_dac_fix = 1,
8906 .input_mux = &alc883_lenovo_sky_capture_source,
8907 .unsol_event = alc883_lenovo_sky_unsol_event,
8908 .init_hook = alc888_lenovo_sky_front_automute,
8909 },
8910 [ALC888_ASUS_M90V] = {
8911 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8912 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8913 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8914 .dac_nids = alc883_dac_nids,
8915 .dig_out_nid = ALC883_DIGOUT_NID,
8916 .dig_in_nid = ALC883_DIGIN_NID,
8917 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8918 .channel_mode = alc883_3ST_6ch_modes,
8919 .need_dac_fix = 1,
8920 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8921 .unsol_event = alc883_mode2_unsol_event,
8922 .init_hook = alc883_mode2_inithook,
8923 },
8924 [ALC888_ASUS_EEE1601] = {
8925 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 8926 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
8927 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8928 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8929 .dac_nids = alc883_dac_nids,
8930 .dig_out_nid = ALC883_DIGOUT_NID,
8931 .dig_in_nid = ALC883_DIGIN_NID,
8932 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8933 .channel_mode = alc883_3ST_2ch_modes,
8934 .need_dac_fix = 1,
8935 .input_mux = &alc883_asus_eee1601_capture_source,
8936 .unsol_event = alc883_eee1601_unsol_event,
8937 .init_hook = alc883_eee1601_inithook,
8938 },
3ab90935
WF
8939 [ALC1200_ASUS_P5Q] = {
8940 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8941 .init_verbs = { alc883_init_verbs },
8942 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8943 .dac_nids = alc883_dac_nids,
8944 .dig_out_nid = ALC1200_DIGOUT_NID,
8945 .dig_in_nid = ALC883_DIGIN_NID,
8946 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8947 .channel_mode = alc883_sixstack_modes,
8948 .input_mux = &alc883_capture_source,
8949 },
9c7f852e
TI
8950};
8951
8952
8953/*
8954 * BIOS auto configuration
8955 */
8956static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8957 hda_nid_t nid, int pin_type,
8958 int dac_idx)
8959{
8960 /* set as output */
8961 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
8962 int idx;
8963
f6c7e546 8964 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
8965 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8966 idx = 4;
8967 else
8968 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
8969 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8970
8971}
8972
8973static void alc883_auto_init_multi_out(struct hda_codec *codec)
8974{
8975 struct alc_spec *spec = codec->spec;
8976 int i;
8977
bc9f98a9 8978 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 8979 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 8980 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 8981 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 8982 if (nid)
baba8ee9 8983 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 8984 i);
9c7f852e
TI
8985 }
8986}
8987
8988static void alc883_auto_init_hp_out(struct hda_codec *codec)
8989{
8990 struct alc_spec *spec = codec->spec;
8991 hda_nid_t pin;
8992
eb06ed8f 8993 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
8994 if (pin) /* connect to front */
8995 /* use dac 0 */
8996 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
8997 pin = spec->autocfg.speaker_pins[0];
8998 if (pin)
8999 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
9000}
9001
9002#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9003#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9004
9005static void alc883_auto_init_analog_input(struct hda_codec *codec)
9006{
9007 struct alc_spec *spec = codec->spec;
9008 int i;
9009
9010 for (i = 0; i < AUTO_PIN_LAST; i++) {
9011 hda_nid_t nid = spec->autocfg.input_pins[i];
9012 if (alc883_is_input_pin(nid)) {
9013 snd_hda_codec_write(codec, nid, 0,
9014 AC_VERB_SET_PIN_WIDGET_CONTROL,
9015 (i <= AUTO_PIN_FRONT_MIC ?
9016 PIN_VREF80 : PIN_IN));
9017 if (nid != ALC883_PIN_CD_NID)
9018 snd_hda_codec_write(codec, nid, 0,
9019 AC_VERB_SET_AMP_GAIN_MUTE,
9020 AMP_OUT_MUTE);
9021 }
9022 }
9023}
9024
f511b01c
TI
9025#define alc883_auto_init_input_src alc882_auto_init_input_src
9026
9c7f852e
TI
9027/* almost identical with ALC880 parser... */
9028static int alc883_parse_auto_config(struct hda_codec *codec)
9029{
9030 struct alc_spec *spec = codec->spec;
9031 int err = alc880_parse_auto_config(codec);
61b9b9b1
HRK
9032 struct auto_pin_cfg *cfg = &spec->autocfg;
9033 int i;
9c7f852e
TI
9034
9035 if (err < 0)
9036 return err;
776e184e
TI
9037 else if (!err)
9038 return 0; /* no config found */
9039
9040 err = alc_auto_add_mic_boost(codec);
9041 if (err < 0)
9042 return err;
9043
9044 /* hack - override the init verbs */
9045 spec->init_verbs[0] = alc883_auto_init_verbs;
776e184e 9046
61b9b9b1
HRK
9047 /* setup input_mux for ALC889 */
9048 if (codec->vendor_id == 0x10ec0889) {
9049 /* digital-mic input pin is excluded in alc880_auto_create..()
9050 * because it's under 0x18
9051 */
9052 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9053 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9054 struct hda_input_mux *imux = &spec->private_imux[0];
9055 for (i = 1; i < 3; i++)
9056 memcpy(&spec->private_imux[i],
9057 &spec->private_imux[0],
9058 sizeof(spec->private_imux[0]));
9059 imux->items[imux->num_items].label = "Int DMic";
9060 imux->items[imux->num_items].index = 0x0b;
9061 imux->num_items++;
9062 spec->num_mux_defs = 3;
9063 spec->input_mux = spec->private_imux;
9064 }
9065 }
9066
776e184e 9067 return 1; /* config found */
9c7f852e
TI
9068}
9069
9070/* additional initialization for auto-configuration model */
9071static void alc883_auto_init(struct hda_codec *codec)
9072{
f6c7e546 9073 struct alc_spec *spec = codec->spec;
9c7f852e
TI
9074 alc883_auto_init_multi_out(codec);
9075 alc883_auto_init_hp_out(codec);
9076 alc883_auto_init_analog_input(codec);
f511b01c 9077 alc883_auto_init_input_src(codec);
f6c7e546 9078 if (spec->unsol_event)
7fb0d78f 9079 alc_inithook(codec);
9c7f852e
TI
9080}
9081
9082static int patch_alc883(struct hda_codec *codec)
9083{
9084 struct alc_spec *spec;
9085 int err, board_config;
9086
9087 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9088 if (spec == NULL)
9089 return -ENOMEM;
9090
9091 codec->spec = spec;
9092
2c3bf9ab
TI
9093 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9094
f5fcc13c
TI
9095 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9096 alc883_models,
9097 alc883_cfg_tbl);
9098 if (board_config < 0) {
9c7f852e
TI
9099 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9100 "trying auto-probe from BIOS...\n");
9101 board_config = ALC883_AUTO;
9102 }
9103
9104 if (board_config == ALC883_AUTO) {
9105 /* automatic parse from the BIOS config */
9106 err = alc883_parse_auto_config(codec);
9107 if (err < 0) {
9108 alc_free(codec);
9109 return err;
f12ab1e0 9110 } else if (!err) {
9c7f852e
TI
9111 printk(KERN_INFO
9112 "hda_codec: Cannot set up configuration "
9113 "from BIOS. Using base mode...\n");
9114 board_config = ALC883_3ST_2ch_DIG;
9115 }
9116 }
9117
680cd536
KK
9118 err = snd_hda_attach_beep_device(codec, 0x1);
9119 if (err < 0) {
9120 alc_free(codec);
9121 return err;
9122 }
9123
9c7f852e
TI
9124 if (board_config != ALC883_AUTO)
9125 setup_preset(spec, &alc883_presets[board_config]);
9126
2f893286
KY
9127 switch (codec->vendor_id) {
9128 case 0x10ec0888:
4442608d
KY
9129 if (codec->revision_id == 0x100101) {
9130 spec->stream_name_analog = "ALC1200 Analog";
9131 spec->stream_name_digital = "ALC1200 Digital";
9132 } else {
9133 spec->stream_name_analog = "ALC888 Analog";
9134 spec->stream_name_digital = "ALC888 Digital";
9135 }
61b9b9b1
HRK
9136 if (!spec->num_adc_nids) {
9137 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9138 spec->adc_nids = alc883_adc_nids;
9139 }
9140 if (!spec->capsrc_nids)
9141 spec->capsrc_nids = alc883_capsrc_nids;
9142 spec->capture_style = CAPT_MIX; /* matrix-style capture */
2f893286
KY
9143 break;
9144 case 0x10ec0889:
9145 spec->stream_name_analog = "ALC889 Analog";
9146 spec->stream_name_digital = "ALC889 Digital";
61b9b9b1
HRK
9147 if (!spec->num_adc_nids) {
9148 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9149 spec->adc_nids = alc889_adc_nids;
9150 }
9151 if (!spec->capsrc_nids)
9152 spec->capsrc_nids = alc889_capsrc_nids;
9153 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9154 capture */
2f893286
KY
9155 break;
9156 default:
9157 spec->stream_name_analog = "ALC883 Analog";
9158 spec->stream_name_digital = "ALC883 Digital";
61b9b9b1
HRK
9159 if (!spec->num_adc_nids) {
9160 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9161 spec->adc_nids = alc883_adc_nids;
9162 }
9163 if (!spec->capsrc_nids)
9164 spec->capsrc_nids = alc883_capsrc_nids;
9165 spec->capture_style = CAPT_MIX; /* matrix-style capture */
2f893286
KY
9166 break;
9167 }
9168
9c7f852e
TI
9169 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9170 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 9171 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e 9172
9c7f852e
TI
9173 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9174 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9175
f9e336f6
TI
9176 if (!spec->cap_mixer)
9177 set_capture_mixer(spec);
9c7f852e 9178
2134ea4f
TI
9179 spec->vmaster_nid = 0x0c;
9180
9c7f852e
TI
9181 codec->patch_ops = alc_patch_ops;
9182 if (board_config == ALC883_AUTO)
9183 spec->init_hook = alc883_auto_init;
f9423e7a 9184
cb53c626
TI
9185#ifdef CONFIG_SND_HDA_POWER_SAVE
9186 if (!spec->loopback.amplist)
9187 spec->loopback.amplist = alc883_loopbacks;
9188#endif
daead538 9189 codec->proc_widget_hook = print_realtek_coef;
9c7f852e
TI
9190
9191 return 0;
9192}
9193
9194/*
9195 * ALC262 support
9196 */
9197
9198#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9199#define ALC262_DIGIN_NID ALC880_DIGIN_NID
9200
9201#define alc262_dac_nids alc260_dac_nids
9202#define alc262_adc_nids alc882_adc_nids
9203#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
9204#define alc262_capsrc_nids alc882_capsrc_nids
9205#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
9206
9207#define alc262_modes alc260_modes
9208#define alc262_capture_source alc882_capture_source
9209
4e555fe5
KY
9210static hda_nid_t alc262_dmic_adc_nids[1] = {
9211 /* ADC0 */
9212 0x09
9213};
9214
9215static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9216
9c7f852e
TI
9217static struct snd_kcontrol_new alc262_base_mixer[] = {
9218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9219 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9226 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9227 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9229 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 9230 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 9231 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9c7f852e
TI
9232 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9233 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9234 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9235 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9236 { } /* end */
9237};
9238
ccc656ce
KY
9239static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9241 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9242 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9243 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9245 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9247 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9248 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
9249 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9250 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9251 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce 9252 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 9253 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
ccc656ce
KY
9254 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9255 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9256 { } /* end */
9257};
9258
ce875f07
TI
9259/* update HP, line and mono-out pins according to the master switch */
9260static void alc262_hp_master_update(struct hda_codec *codec)
9261{
9262 struct alc_spec *spec = codec->spec;
9263 int val = spec->master_sw;
9264
9265 /* HP & line-out */
9266 snd_hda_codec_write_cache(codec, 0x1b, 0,
9267 AC_VERB_SET_PIN_WIDGET_CONTROL,
9268 val ? PIN_HP : 0);
9269 snd_hda_codec_write_cache(codec, 0x15, 0,
9270 AC_VERB_SET_PIN_WIDGET_CONTROL,
9271 val ? PIN_HP : 0);
9272 /* mono (speaker) depending on the HP jack sense */
9273 val = val && !spec->jack_present;
9274 snd_hda_codec_write_cache(codec, 0x16, 0,
9275 AC_VERB_SET_PIN_WIDGET_CONTROL,
9276 val ? PIN_OUT : 0);
9277}
9278
9279static void alc262_hp_bpc_automute(struct hda_codec *codec)
9280{
9281 struct alc_spec *spec = codec->spec;
9282 unsigned int presence;
9283 presence = snd_hda_codec_read(codec, 0x1b, 0,
9284 AC_VERB_GET_PIN_SENSE, 0);
9285 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9286 alc262_hp_master_update(codec);
9287}
9288
9289static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9290{
9291 if ((res >> 26) != ALC880_HP_EVENT)
9292 return;
9293 alc262_hp_bpc_automute(codec);
9294}
9295
9296static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9297{
9298 struct alc_spec *spec = codec->spec;
9299 unsigned int presence;
9300 presence = snd_hda_codec_read(codec, 0x15, 0,
9301 AC_VERB_GET_PIN_SENSE, 0);
9302 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9303 alc262_hp_master_update(codec);
9304}
9305
9306static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9307 unsigned int res)
9308{
9309 if ((res >> 26) != ALC880_HP_EVENT)
9310 return;
9311 alc262_hp_wildwest_automute(codec);
9312}
9313
9314static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9315 struct snd_ctl_elem_value *ucontrol)
9316{
9317 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9318 struct alc_spec *spec = codec->spec;
9319 *ucontrol->value.integer.value = spec->master_sw;
9320 return 0;
9321}
9322
9323static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9324 struct snd_ctl_elem_value *ucontrol)
9325{
9326 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9327 struct alc_spec *spec = codec->spec;
9328 int val = !!*ucontrol->value.integer.value;
9329
9330 if (val == spec->master_sw)
9331 return 0;
9332 spec->master_sw = val;
9333 alc262_hp_master_update(codec);
9334 return 1;
9335}
9336
9c7f852e 9337static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
9338 {
9339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9340 .name = "Master Playback Switch",
9341 .info = snd_ctl_boolean_mono_info,
9342 .get = alc262_hp_master_sw_get,
9343 .put = alc262_hp_master_sw_put,
9344 },
9c7f852e
TI
9345 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9346 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9347 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
9348 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9349 HDA_OUTPUT),
9350 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9351 HDA_OUTPUT),
9c7f852e
TI
9352 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9354 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9355 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9356 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9357 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9360 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9361 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9362 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9363 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9364 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9365 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9366 { } /* end */
9367};
9368
cd7509a4 9369static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
9370 {
9371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9372 .name = "Master Playback Switch",
9373 .info = snd_ctl_boolean_mono_info,
9374 .get = alc262_hp_master_sw_get,
9375 .put = alc262_hp_master_sw_put,
9376 },
cd7509a4
KY
9377 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9378 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9379 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9380 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
9381 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9382 HDA_OUTPUT),
9383 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9384 HDA_OUTPUT),
cd7509a4
KY
9385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 9387 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
9388 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9389 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9390 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9391 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9392 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9393 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9394 { } /* end */
9395};
9396
9397static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9398 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9399 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9400 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
9401 { } /* end */
9402};
9403
66d2a9d6
KY
9404/* mute/unmute internal speaker according to the hp jack and mute state */
9405static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9406{
9407 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
9408
9409 if (force || !spec->sense_updated) {
9410 unsigned int present;
9411 present = snd_hda_codec_read(codec, 0x15, 0,
9412 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 9413 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
9414 spec->sense_updated = 1;
9415 }
4bb26130
TI
9416 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9417 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
9418}
9419
9420static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9421 unsigned int res)
9422{
9423 if ((res >> 26) != ALC880_HP_EVENT)
9424 return;
9425 alc262_hp_t5735_automute(codec, 1);
9426}
9427
9428static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9429{
9430 alc262_hp_t5735_automute(codec, 1);
9431}
9432
9433static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
9434 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9435 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
9436 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9441 { } /* end */
9442};
9443
9444static struct hda_verb alc262_hp_t5735_verbs[] = {
9445 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9447
9448 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9449 { }
9450};
9451
8c427226 9452static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
9453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
9455 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9456 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
9457 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9458 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9459 { } /* end */
9460};
9461
9462static struct hda_verb alc262_hp_rp5700_verbs[] = {
9463 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9464 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9465 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9466 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9467 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9468 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9469 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9472 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9473 {}
9474};
9475
9476static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9477 .num_items = 1,
9478 .items = {
9479 { "Line", 0x1 },
9480 },
9481};
9482
0724ea2a
TI
9483/* bind hp and internal speaker mute (with plug check) */
9484static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9485 struct snd_ctl_elem_value *ucontrol)
9486{
9487 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9488 long *valp = ucontrol->value.integer.value;
9489 int change;
9490
9491 /* change hp mute */
9492 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9493 HDA_AMP_MUTE,
9494 valp[0] ? 0 : HDA_AMP_MUTE);
9495 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9496 HDA_AMP_MUTE,
9497 valp[1] ? 0 : HDA_AMP_MUTE);
9498 if (change) {
9499 /* change speaker according to HP jack state */
9500 struct alc_spec *spec = codec->spec;
9501 unsigned int mute;
9502 if (spec->jack_present)
9503 mute = HDA_AMP_MUTE;
9504 else
9505 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9506 HDA_OUTPUT, 0);
9507 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9508 HDA_AMP_MUTE, mute);
9509 }
9510 return change;
9511}
5b31954e 9512
272a527c 9513static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
9514 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9515 {
9516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9517 .name = "Master Playback Switch",
9518 .info = snd_hda_mixer_amp_switch_info,
9519 .get = snd_hda_mixer_amp_switch_get,
9520 .put = alc262_sony_master_sw_put,
9521 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9522 },
272a527c
KY
9523 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9524 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9525 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9526 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9527 { } /* end */
9528};
9529
83c34218
KY
9530static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9531 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9532 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9533 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9535 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9536 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9537 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9538 { } /* end */
9539};
272a527c 9540
ba340e82
TV
9541static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9542 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9543 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9544 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9545 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9546 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9547 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9550 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9551 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9552 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9553 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9554 { } /* end */
9555};
9556
9557static struct hda_verb alc262_tyan_verbs[] = {
9558 /* Headphone automute */
9559 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9560 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9561 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9562
9563 /* P11 AUX_IN, white 4-pin connector */
9564 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9565 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9566 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9567 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9568
9569 {}
9570};
9571
9572/* unsolicited event for HP jack sensing */
9573static void alc262_tyan_automute(struct hda_codec *codec)
9574{
9575 unsigned int mute;
9576 unsigned int present;
9577
9578 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9579 present = snd_hda_codec_read(codec, 0x1b, 0,
9580 AC_VERB_GET_PIN_SENSE, 0);
9581 present = (present & 0x80000000) != 0;
9582 if (present) {
9583 /* mute line output on ATX panel */
9584 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9585 HDA_AMP_MUTE, HDA_AMP_MUTE);
9586 } else {
9587 /* unmute line output if necessary */
9588 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9589 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9590 HDA_AMP_MUTE, mute);
9591 }
9592}
9593
9594static void alc262_tyan_unsol_event(struct hda_codec *codec,
9595 unsigned int res)
9596{
9597 if ((res >> 26) != ALC880_HP_EVENT)
9598 return;
9599 alc262_tyan_automute(codec);
9600}
9601
9c7f852e
TI
9602#define alc262_capture_mixer alc882_capture_mixer
9603#define alc262_capture_alt_mixer alc882_capture_alt_mixer
9604
9605/*
9606 * generic initialization of ADC, input mixers and output mixers
9607 */
9608static struct hda_verb alc262_init_verbs[] = {
9609 /*
9610 * Unmute ADC0-2 and set the default input to mic-in
9611 */
9612 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9613 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9614 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9615 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9616 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9617 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9618
cb53c626 9619 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 9620 * mixer widget
f12ab1e0
TI
9621 * Note: PASD motherboards uses the Line In 2 as the input for
9622 * front panel mic (mic 2)
9c7f852e
TI
9623 */
9624 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9629 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
9630
9631 /*
df694daa
KY
9632 * Set up output mixers (0x0c - 0x0e)
9633 */
9634 /* set vol=0 to output mixers */
9635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9637 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9638 /* set up input amps for analog loopback */
9639 /* Amp Indices: DAC = 0, mixer = 1 */
9640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9644 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9645 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9646
9647 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9649 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9650 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9651 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9652 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9653
9654 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9655 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9656 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9657 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9658 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 9659
df694daa
KY
9660 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9661 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 9662
df694daa
KY
9663 /* FIXME: use matrix-type input source selection */
9664 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9665 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9667 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9668 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9670 /* Input mixer2 */
9671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9672 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9673 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9674 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9675 /* Input mixer3 */
9676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 9679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
9680
9681 { }
9682};
1da177e4 9683
4e555fe5
KY
9684static struct hda_verb alc262_eapd_verbs[] = {
9685 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9686 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9687 { }
9688};
9689
ccc656ce
KY
9690static struct hda_verb alc262_hippo_unsol_verbs[] = {
9691 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9693 {}
9694};
9695
9696static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9697 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9698 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9699 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9700
9701 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9702 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9703 {}
9704};
9705
272a527c
KY
9706static struct hda_verb alc262_sony_unsol_verbs[] = {
9707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9708 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9709 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9710
9711 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9712 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 9713 {}
272a527c
KY
9714};
9715
4e555fe5
KY
9716static struct hda_input_mux alc262_dmic_capture_source = {
9717 .num_items = 2,
9718 .items = {
9719 { "Int DMic", 0x9 },
9720 { "Mic", 0x0 },
9721 },
9722};
9723
9724static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9725 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9726 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9727 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
9730 { } /* end */
9731};
9732
9733static struct hda_verb alc262_toshiba_s06_verbs[] = {
9734 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9735 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9736 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9737 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9738 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9739 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9740 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9741 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9742 {}
9743};
9744
9745static void alc262_dmic_automute(struct hda_codec *codec)
9746{
9747 unsigned int present;
9748
9749 present = snd_hda_codec_read(codec, 0x18, 0,
9750 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9751 snd_hda_codec_write(codec, 0x22, 0,
9752 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9753}
9754
9755/* toggle speaker-output according to the hp-jack state */
9756static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9757{
9758 unsigned int present;
9759 unsigned char bits;
9760
9761 present = snd_hda_codec_read(codec, 0x15, 0,
9762 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9763 bits = present ? 0 : PIN_OUT;
9764 snd_hda_codec_write(codec, 0x14, 0,
9765 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9766}
9767
9768
9769
9770/* unsolicited event for HP jack sensing */
9771static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9772 unsigned int res)
9773{
9774 if ((res >> 26) == ALC880_HP_EVENT)
9775 alc262_toshiba_s06_speaker_automute(codec);
9776 if ((res >> 26) == ALC880_MIC_EVENT)
9777 alc262_dmic_automute(codec);
9778
9779}
9780
9781static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9782{
9783 alc262_toshiba_s06_speaker_automute(codec);
9784 alc262_dmic_automute(codec);
9785}
9786
ccc656ce 9787/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 9788static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
9789{
9790 struct alc_spec *spec = codec->spec;
9791 unsigned int mute;
5b31954e 9792 unsigned int present;
ccc656ce 9793
5b31954e
TI
9794 /* need to execute and sync at first */
9795 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9796 present = snd_hda_codec_read(codec, 0x15, 0,
9797 AC_VERB_GET_PIN_SENSE, 0);
9798 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
9799 if (spec->jack_present) {
9800 /* mute internal speaker */
47fd830a
TI
9801 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9802 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
9803 } else {
9804 /* unmute internal speaker if necessary */
9805 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
9806 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9807 HDA_AMP_MUTE, mute);
ccc656ce
KY
9808 }
9809}
9810
9811/* unsolicited event for HP jack sensing */
9812static void alc262_hippo_unsol_event(struct hda_codec *codec,
9813 unsigned int res)
9814{
9815 if ((res >> 26) != ALC880_HP_EVENT)
9816 return;
5b31954e 9817 alc262_hippo_automute(codec);
ccc656ce
KY
9818}
9819
5b31954e 9820static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 9821{
ccc656ce 9822 unsigned int mute;
5b31954e 9823 unsigned int present;
ccc656ce 9824
5b31954e
TI
9825 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9826 present = snd_hda_codec_read(codec, 0x1b, 0,
9827 AC_VERB_GET_PIN_SENSE, 0);
9828 present = (present & 0x80000000) != 0;
9829 if (present) {
ccc656ce 9830 /* mute internal speaker */
47fd830a
TI
9831 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9832 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
9833 } else {
9834 /* unmute internal speaker if necessary */
9835 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
9836 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9837 HDA_AMP_MUTE, mute);
ccc656ce
KY
9838 }
9839}
9840
9841/* unsolicited event for HP jack sensing */
9842static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9843 unsigned int res)
9844{
9845 if ((res >> 26) != ALC880_HP_EVENT)
9846 return;
5b31954e 9847 alc262_hippo1_automute(codec);
ccc656ce
KY
9848}
9849
e8f9ae2a
PT
9850/*
9851 * nec model
9852 * 0x15 = headphone
9853 * 0x16 = internal speaker
9854 * 0x18 = external mic
9855 */
9856
9857static struct snd_kcontrol_new alc262_nec_mixer[] = {
9858 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9859 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9860
9861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9863 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9864
9865 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9866 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9867 { } /* end */
9868};
9869
9870static struct hda_verb alc262_nec_verbs[] = {
9871 /* Unmute Speaker */
9872 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9873
9874 /* Headphone */
9875 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9877
9878 /* External mic to headphone */
9879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9880 /* External mic to speaker */
9881 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9882 {}
9883};
9884
834be88d
TI
9885/*
9886 * fujitsu model
5d9fab2d
TV
9887 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9888 * 0x1b = port replicator headphone out
834be88d
TI
9889 */
9890
9891#define ALC_HP_EVENT 0x37
9892
9893static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9894 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
9896 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9897 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
9898 {}
9899};
9900
0e31daf7
J
9901static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9902 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9903 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9904 {}
9905};
9906
834be88d 9907static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 9908 .num_items = 3,
834be88d
TI
9909 .items = {
9910 { "Mic", 0x0 },
39d3ed38 9911 { "Int Mic", 0x1 },
834be88d
TI
9912 { "CD", 0x4 },
9913 },
9914};
9915
9c7f852e
TI
9916static struct hda_input_mux alc262_HP_capture_source = {
9917 .num_items = 5,
9918 .items = {
9919 { "Mic", 0x0 },
accbe498 9920 { "Front Mic", 0x1 },
9c7f852e
TI
9921 { "Line", 0x2 },
9922 { "CD", 0x4 },
9923 { "AUX IN", 0x6 },
9924 },
9925};
9926
accbe498 9927static struct hda_input_mux alc262_HP_D7000_capture_source = {
9928 .num_items = 4,
9929 .items = {
9930 { "Mic", 0x0 },
9931 { "Front Mic", 0x2 },
9932 { "Line", 0x1 },
9933 { "CD", 0x4 },
9934 },
9935};
9936
ebc7a406 9937/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
9938static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9939{
9940 struct alc_spec *spec = codec->spec;
9941 unsigned int mute;
9942
f12ab1e0 9943 if (force || !spec->sense_updated) {
ebc7a406 9944 unsigned int present;
834be88d
TI
9945 /* need to execute and sync at first */
9946 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
9947 /* check laptop HP jack */
9948 present = snd_hda_codec_read(codec, 0x14, 0,
9949 AC_VERB_GET_PIN_SENSE, 0);
9950 /* need to execute and sync at first */
9951 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9952 /* check docking HP jack */
9953 present |= snd_hda_codec_read(codec, 0x1b, 0,
9954 AC_VERB_GET_PIN_SENSE, 0);
9955 if (present & AC_PINSENSE_PRESENCE)
9956 spec->jack_present = 1;
9957 else
9958 spec->jack_present = 0;
834be88d
TI
9959 spec->sense_updated = 1;
9960 }
ebc7a406
TI
9961 /* unmute internal speaker only if both HPs are unplugged and
9962 * master switch is on
9963 */
9964 if (spec->jack_present)
9965 mute = HDA_AMP_MUTE;
9966 else
834be88d 9967 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
9968 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9969 HDA_AMP_MUTE, mute);
834be88d
TI
9970}
9971
9972/* unsolicited event for HP jack sensing */
9973static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9974 unsigned int res)
9975{
9976 if ((res >> 26) != ALC_HP_EVENT)
9977 return;
9978 alc262_fujitsu_automute(codec, 1);
9979}
9980
ebc7a406
TI
9981static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9982{
9983 alc262_fujitsu_automute(codec, 1);
9984}
9985
834be88d 9986/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
9987static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9988 .ops = &snd_hda_bind_vol,
9989 .values = {
9990 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9991 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9992 0
9993 },
9994};
834be88d 9995
0e31daf7
J
9996/* mute/unmute internal speaker according to the hp jack and mute state */
9997static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9998{
9999 struct alc_spec *spec = codec->spec;
10000 unsigned int mute;
10001
10002 if (force || !spec->sense_updated) {
10003 unsigned int present_int_hp;
10004 /* need to execute and sync at first */
10005 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10006 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10007 AC_VERB_GET_PIN_SENSE, 0);
10008 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10009 spec->sense_updated = 1;
10010 }
10011 if (spec->jack_present) {
10012 /* mute internal speaker */
10013 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10014 HDA_AMP_MUTE, HDA_AMP_MUTE);
10015 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10016 HDA_AMP_MUTE, HDA_AMP_MUTE);
10017 } else {
10018 /* unmute internal speaker if necessary */
10019 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10020 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10021 HDA_AMP_MUTE, mute);
10022 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10023 HDA_AMP_MUTE, mute);
10024 }
10025}
10026
10027/* unsolicited event for HP jack sensing */
10028static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10029 unsigned int res)
10030{
10031 if ((res >> 26) != ALC_HP_EVENT)
10032 return;
10033 alc262_lenovo_3000_automute(codec, 1);
10034}
10035
834be88d
TI
10036/* bind hp and internal speaker mute (with plug check) */
10037static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10038 struct snd_ctl_elem_value *ucontrol)
10039{
10040 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10041 long *valp = ucontrol->value.integer.value;
10042 int change;
10043
5d9fab2d
TV
10044 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10045 HDA_AMP_MUTE,
10046 valp ? 0 : HDA_AMP_MUTE);
10047 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10048 HDA_AMP_MUTE,
10049 valp ? 0 : HDA_AMP_MUTE);
10050
82beb8fd
TI
10051 if (change)
10052 alc262_fujitsu_automute(codec, 0);
834be88d
TI
10053 return change;
10054}
10055
10056static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 10057 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
10058 {
10059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10060 .name = "Master Playback Switch",
10061 .info = snd_hda_mixer_amp_switch_info,
10062 .get = snd_hda_mixer_amp_switch_get,
10063 .put = alc262_fujitsu_master_sw_put,
10064 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10065 },
10066 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10067 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
06a9c30c
TV
10068 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
10069 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
834be88d
TI
10070 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10071 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10072 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
10073 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10074 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10075 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
10076 { } /* end */
10077};
10078
0e31daf7
J
10079/* bind hp and internal speaker mute (with plug check) */
10080static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10081 struct snd_ctl_elem_value *ucontrol)
10082{
10083 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10084 long *valp = ucontrol->value.integer.value;
10085 int change;
10086
10087 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10088 HDA_AMP_MUTE,
10089 valp ? 0 : HDA_AMP_MUTE);
10090
10091 if (change)
10092 alc262_lenovo_3000_automute(codec, 0);
10093 return change;
10094}
10095
10096static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10097 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10098 {
10099 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10100 .name = "Master Playback Switch",
10101 .info = snd_hda_mixer_amp_switch_info,
10102 .get = snd_hda_mixer_amp_switch_get,
10103 .put = alc262_lenovo_3000_master_sw_put,
10104 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10105 },
10106 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10107 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10108 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10109 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10110 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10111 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10112 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10113 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10114 { } /* end */
10115};
10116
9f99a638
HM
10117static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10118 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10119 {
10120 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10121 .name = "Master Playback Switch",
10122 .info = snd_hda_mixer_amp_switch_info,
10123 .get = snd_hda_mixer_amp_switch_get,
10124 .put = alc262_sony_master_sw_put,
10125 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10126 },
10127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10128 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10129 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10130 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10131 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10132 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10133 { } /* end */
10134};
10135
304dcaac
TI
10136/* additional init verbs for Benq laptops */
10137static struct hda_verb alc262_EAPD_verbs[] = {
10138 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10139 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10140 {}
10141};
10142
83c34218
KY
10143static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10144 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10145 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10146
10147 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10148 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10149 {}
10150};
10151
f651b50b
TD
10152/* Samsung Q1 Ultra Vista model setup */
10153static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
10154 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10155 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
10156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10158 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 10159 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
10160 { } /* end */
10161};
10162
10163static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
10164 /* output mixer */
10165 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10166 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10167 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10168 /* speaker */
10169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10171 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10172 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10173 /* HP */
f651b50b 10174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
10175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10176 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10178 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10179 /* internal mic */
10180 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10181 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10182 /* ADC, choose mic */
10183 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10184 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10185 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10186 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10187 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10188 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10189 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10190 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10191 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10192 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
10193 {}
10194};
10195
f651b50b
TD
10196/* mute/unmute internal speaker according to the hp jack and mute state */
10197static void alc262_ultra_automute(struct hda_codec *codec)
10198{
10199 struct alc_spec *spec = codec->spec;
10200 unsigned int mute;
f651b50b 10201
bb9f76cd
TI
10202 mute = 0;
10203 /* auto-mute only when HP is used as HP */
10204 if (!spec->cur_mux[0]) {
10205 unsigned int present;
10206 /* need to execute and sync at first */
10207 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10208 present = snd_hda_codec_read(codec, 0x15, 0,
10209 AC_VERB_GET_PIN_SENSE, 0);
10210 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10211 if (spec->jack_present)
10212 mute = HDA_AMP_MUTE;
f651b50b 10213 }
bb9f76cd
TI
10214 /* mute/unmute internal speaker */
10215 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10216 HDA_AMP_MUTE, mute);
10217 /* mute/unmute HP */
10218 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10219 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
10220}
10221
10222/* unsolicited event for HP jack sensing */
10223static void alc262_ultra_unsol_event(struct hda_codec *codec,
10224 unsigned int res)
10225{
10226 if ((res >> 26) != ALC880_HP_EVENT)
10227 return;
10228 alc262_ultra_automute(codec);
10229}
10230
bb9f76cd
TI
10231static struct hda_input_mux alc262_ultra_capture_source = {
10232 .num_items = 2,
10233 .items = {
10234 { "Mic", 0x1 },
10235 { "Headphone", 0x7 },
10236 },
10237};
10238
10239static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10240 struct snd_ctl_elem_value *ucontrol)
10241{
10242 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10243 struct alc_spec *spec = codec->spec;
10244 int ret;
10245
54cbc9ab 10246 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
10247 if (!ret)
10248 return 0;
10249 /* reprogram the HP pin as mic or HP according to the input source */
10250 snd_hda_codec_write_cache(codec, 0x15, 0,
10251 AC_VERB_SET_PIN_WIDGET_CONTROL,
10252 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10253 alc262_ultra_automute(codec); /* mute/unmute HP */
10254 return ret;
10255}
10256
10257static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10258 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10259 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10260 {
10261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10262 .name = "Capture Source",
54cbc9ab
TI
10263 .info = alc_mux_enum_info,
10264 .get = alc_mux_enum_get,
bb9f76cd
TI
10265 .put = alc262_ultra_mux_enum_put,
10266 },
10267 { } /* end */
10268};
10269
df694daa 10270/* add playback controls from the parsed DAC table */
f12ab1e0
TI
10271static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10272 const struct auto_pin_cfg *cfg)
df694daa
KY
10273{
10274 hda_nid_t nid;
10275 int err;
10276
10277 spec->multiout.num_dacs = 1; /* only use one dac */
10278 spec->multiout.dac_nids = spec->private_dac_nids;
10279 spec->multiout.dac_nids[0] = 2;
10280
10281 nid = cfg->line_out_pins[0];
10282 if (nid) {
f12ab1e0
TI
10283 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10284 "Front Playback Volume",
10285 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10286 if (err < 0)
df694daa 10287 return err;
f12ab1e0
TI
10288 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10289 "Front Playback Switch",
10290 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10291 if (err < 0)
df694daa
KY
10292 return err;
10293 }
10294
82bc955f 10295 nid = cfg->speaker_pins[0];
df694daa
KY
10296 if (nid) {
10297 if (nid == 0x16) {
f12ab1e0
TI
10298 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10299 "Speaker Playback Volume",
10300 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10301 HDA_OUTPUT));
10302 if (err < 0)
df694daa 10303 return err;
f12ab1e0
TI
10304 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10305 "Speaker Playback Switch",
10306 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10307 HDA_OUTPUT));
10308 if (err < 0)
df694daa
KY
10309 return err;
10310 } else {
f12ab1e0
TI
10311 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10312 "Speaker Playback Switch",
10313 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10314 HDA_OUTPUT));
10315 if (err < 0)
df694daa
KY
10316 return err;
10317 }
10318 }
eb06ed8f 10319 nid = cfg->hp_pins[0];
df694daa
KY
10320 if (nid) {
10321 /* spec->multiout.hp_nid = 2; */
10322 if (nid == 0x16) {
f12ab1e0
TI
10323 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10324 "Headphone Playback Volume",
10325 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10326 HDA_OUTPUT));
10327 if (err < 0)
df694daa 10328 return err;
f12ab1e0
TI
10329 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10330 "Headphone Playback Switch",
10331 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10332 HDA_OUTPUT));
10333 if (err < 0)
df694daa
KY
10334 return err;
10335 } else {
f12ab1e0
TI
10336 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10337 "Headphone Playback Switch",
10338 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10339 HDA_OUTPUT));
10340 if (err < 0)
df694daa
KY
10341 return err;
10342 }
10343 }
f12ab1e0 10344 return 0;
df694daa
KY
10345}
10346
10347/* identical with ALC880 */
f12ab1e0
TI
10348#define alc262_auto_create_analog_input_ctls \
10349 alc880_auto_create_analog_input_ctls
df694daa
KY
10350
10351/*
10352 * generic initialization of ADC, input mixers and output mixers
10353 */
10354static struct hda_verb alc262_volume_init_verbs[] = {
10355 /*
10356 * Unmute ADC0-2 and set the default input to mic-in
10357 */
10358 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10359 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10360 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10362 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10364
cb53c626 10365 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 10366 * mixer widget
f12ab1e0
TI
10367 * Note: PASD motherboards uses the Line In 2 as the input for
10368 * front panel mic (mic 2)
df694daa
KY
10369 */
10370 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10372 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10373 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10374 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
10376
10377 /*
10378 * Set up output mixers (0x0c - 0x0f)
10379 */
10380 /* set vol=0 to output mixers */
10381 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10382 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10383 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 10384
df694daa
KY
10385 /* set up input amps for analog loopback */
10386 /* Amp Indices: DAC = 0, mixer = 1 */
10387 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10388 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10389 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10390 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10391 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10392 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10393
10394 /* FIXME: use matrix-type input source selection */
10395 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10396 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10397 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10398 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10399 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10400 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10401 /* Input mixer2 */
10402 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10403 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10404 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10405 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10406 /* Input mixer3 */
10407 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10408 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10409 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10410 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10411
10412 { }
10413};
10414
9c7f852e
TI
10415static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10416 /*
10417 * Unmute ADC0-2 and set the default input to mic-in
10418 */
10419 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10421 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10422 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10423 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10424 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10425
cb53c626 10426 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10427 * mixer widget
f12ab1e0
TI
10428 * Note: PASD motherboards uses the Line In 2 as the input for
10429 * front panel mic (mic 2)
9c7f852e
TI
10430 */
10431 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10432 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10433 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10434 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10435 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10436 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10437 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10438 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 10439
9c7f852e
TI
10440 /*
10441 * Set up output mixers (0x0c - 0x0e)
10442 */
10443 /* set vol=0 to output mixers */
10444 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10445 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10446 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10447
10448 /* set up input amps for analog loopback */
10449 /* Amp Indices: DAC = 0, mixer = 1 */
10450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10451 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10454 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10455 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10456
ce875f07 10457 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
10458 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10459 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10460
10461 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10462 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10463
10464 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10465 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10466
10467 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10468 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10469 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10470 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10471 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10472
10473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10474 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10475 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10476 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10477 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10478 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10479
10480
10481 /* FIXME: use matrix-type input source selection */
10482 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10483 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10484 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10485 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10486 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10487 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10488 /* Input mixer2 */
10489 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10490 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10491 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10493 /* Input mixer3 */
10494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10498
ce875f07
TI
10499 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10500
9c7f852e
TI
10501 { }
10502};
10503
cd7509a4
KY
10504static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10505 /*
10506 * Unmute ADC0-2 and set the default input to mic-in
10507 */
10508 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10510 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10511 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10512 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10513 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10514
cb53c626 10515 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
10516 * mixer widget
10517 * Note: PASD motherboards uses the Line In 2 as the input for front
10518 * panel mic (mic 2)
10519 */
10520 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
10529 /*
10530 * Set up output mixers (0x0c - 0x0e)
10531 */
10532 /* set vol=0 to output mixers */
10533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10535 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10536
10537 /* set up input amps for analog loopback */
10538 /* Amp Indices: DAC = 0, mixer = 1 */
10539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10541 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10542 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10543 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10544 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10545
10546
10547 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10548 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10549 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10550 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10551 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10552 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10553 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10554
10555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10557
10558 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10559 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10560
10561 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10562 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10563 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10564 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10565 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10566 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10567
10568 /* FIXME: use matrix-type input source selection */
10569 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10570 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10571 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10572 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10573 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10575 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10576 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10578 /* Input mixer2 */
10579 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10580 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10584 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10585 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10586 /* Input mixer3 */
10587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10590 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10591 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10592 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10593 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10594
ce875f07
TI
10595 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10596
cd7509a4
KY
10597 { }
10598};
10599
9f99a638
HM
10600static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10601
10602 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10603 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10604 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10605
10606 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10608 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10609 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10610
10611 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10612 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10613 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10614 {}
10615};
10616
10617
cb53c626
TI
10618#ifdef CONFIG_SND_HDA_POWER_SAVE
10619#define alc262_loopbacks alc880_loopbacks
10620#endif
10621
df694daa
KY
10622/* pcm configuration: identiacal with ALC880 */
10623#define alc262_pcm_analog_playback alc880_pcm_analog_playback
10624#define alc262_pcm_analog_capture alc880_pcm_analog_capture
10625#define alc262_pcm_digital_playback alc880_pcm_digital_playback
10626#define alc262_pcm_digital_capture alc880_pcm_digital_capture
10627
10628/*
10629 * BIOS auto configuration
10630 */
10631static int alc262_parse_auto_config(struct hda_codec *codec)
10632{
10633 struct alc_spec *spec = codec->spec;
10634 int err;
10635 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10636
f12ab1e0
TI
10637 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10638 alc262_ignore);
10639 if (err < 0)
df694daa 10640 return err;
e64f14f4
TI
10641 if (!spec->autocfg.line_outs) {
10642 if (spec->autocfg.dig_out_pin || spec->autocfg.dig_in_pin) {
10643 spec->multiout.max_channels = 2;
10644 spec->no_analog = 1;
10645 goto dig_only;
10646 }
df694daa 10647 return 0; /* can't find valid BIOS pin config */
e64f14f4 10648 }
f12ab1e0
TI
10649 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10650 if (err < 0)
10651 return err;
10652 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10653 if (err < 0)
df694daa
KY
10654 return err;
10655
10656 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10657
e64f14f4
TI
10658 dig_only:
10659 if (spec->autocfg.dig_out_pin) {
df694daa 10660 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
e64f14f4
TI
10661 spec->dig_out_type = spec->autocfg.dig_out_type;
10662 }
df694daa
KY
10663 if (spec->autocfg.dig_in_pin)
10664 spec->dig_in_nid = ALC262_DIGIN_NID;
10665
603c4019 10666 if (spec->kctls.list)
d88897ea 10667 add_mixer(spec, spec->kctls.list);
df694daa 10668
d88897ea 10669 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 10670 spec->num_mux_defs = 1;
61b9b9b1 10671 spec->input_mux = &spec->private_imux[0];
df694daa 10672
776e184e
TI
10673 err = alc_auto_add_mic_boost(codec);
10674 if (err < 0)
10675 return err;
10676
e044c39a 10677 store_pin_configs(codec);
df694daa
KY
10678 return 1;
10679}
10680
10681#define alc262_auto_init_multi_out alc882_auto_init_multi_out
10682#define alc262_auto_init_hp_out alc882_auto_init_hp_out
10683#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 10684#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
10685
10686
10687/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 10688static void alc262_auto_init(struct hda_codec *codec)
df694daa 10689{
f6c7e546 10690 struct alc_spec *spec = codec->spec;
df694daa
KY
10691 alc262_auto_init_multi_out(codec);
10692 alc262_auto_init_hp_out(codec);
10693 alc262_auto_init_analog_input(codec);
f511b01c 10694 alc262_auto_init_input_src(codec);
f6c7e546 10695 if (spec->unsol_event)
7fb0d78f 10696 alc_inithook(codec);
df694daa
KY
10697}
10698
10699/*
10700 * configuration and preset
10701 */
f5fcc13c
TI
10702static const char *alc262_models[ALC262_MODEL_LAST] = {
10703 [ALC262_BASIC] = "basic",
10704 [ALC262_HIPPO] = "hippo",
10705 [ALC262_HIPPO_1] = "hippo_1",
10706 [ALC262_FUJITSU] = "fujitsu",
10707 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 10708 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 10709 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 10710 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 10711 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
10712 [ALC262_BENQ_T31] = "benq-t31",
10713 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 10714 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 10715 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 10716 [ALC262_ULTRA] = "ultra",
0e31daf7 10717 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 10718 [ALC262_NEC] = "nec",
ba340e82 10719 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
10720 [ALC262_AUTO] = "auto",
10721};
10722
10723static struct snd_pci_quirk alc262_cfg_tbl[] = {
10724 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 10725 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
f5fcc13c 10726 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 10727 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
10728 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10729 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 10730 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 10731 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 10732 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 10733 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 10734 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10735 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10736 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10737 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10738 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10739 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10740 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10741 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
10742 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10743 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10744 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
10745 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10746 ALC262_HP_TC_T5735),
8c427226 10747 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 10748 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 10749 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 10750 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 10751 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741 10752 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
57a5ef48
TI
10753 SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN",
10754 ALC262_SONY_ASSAMD),
36ca6e13 10755 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 10756 ALC262_TOSHIBA_RX1),
80ffe869 10757 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 10758 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 10759 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 10760 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
f651b50b 10761 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
bb9f76cd 10762 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
3e420e78 10763 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 10764 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
10765 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10766 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10767 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
10768 {}
10769};
10770
10771static struct alc_config_preset alc262_presets[] = {
10772 [ALC262_BASIC] = {
10773 .mixers = { alc262_base_mixer },
10774 .init_verbs = { alc262_init_verbs },
10775 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10776 .dac_nids = alc262_dac_nids,
10777 .hp_nid = 0x03,
10778 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10779 .channel_mode = alc262_modes,
a3bcba38 10780 .input_mux = &alc262_capture_source,
df694daa 10781 },
ccc656ce
KY
10782 [ALC262_HIPPO] = {
10783 .mixers = { alc262_base_mixer },
10784 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10785 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10786 .dac_nids = alc262_dac_nids,
10787 .hp_nid = 0x03,
10788 .dig_out_nid = ALC262_DIGOUT_NID,
10789 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10790 .channel_mode = alc262_modes,
10791 .input_mux = &alc262_capture_source,
10792 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10793 .init_hook = alc262_hippo_automute,
ccc656ce
KY
10794 },
10795 [ALC262_HIPPO_1] = {
10796 .mixers = { alc262_hippo1_mixer },
10797 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10798 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10799 .dac_nids = alc262_dac_nids,
10800 .hp_nid = 0x02,
10801 .dig_out_nid = ALC262_DIGOUT_NID,
10802 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10803 .channel_mode = alc262_modes,
10804 .input_mux = &alc262_capture_source,
10805 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 10806 .init_hook = alc262_hippo1_automute,
ccc656ce 10807 },
834be88d
TI
10808 [ALC262_FUJITSU] = {
10809 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
10810 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10811 alc262_fujitsu_unsol_verbs },
834be88d
TI
10812 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10813 .dac_nids = alc262_dac_nids,
10814 .hp_nid = 0x03,
10815 .dig_out_nid = ALC262_DIGOUT_NID,
10816 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10817 .channel_mode = alc262_modes,
10818 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 10819 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 10820 .init_hook = alc262_fujitsu_init_hook,
834be88d 10821 },
9c7f852e
TI
10822 [ALC262_HP_BPC] = {
10823 .mixers = { alc262_HP_BPC_mixer },
10824 .init_verbs = { alc262_HP_BPC_init_verbs },
10825 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10826 .dac_nids = alc262_dac_nids,
10827 .hp_nid = 0x03,
10828 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10829 .channel_mode = alc262_modes,
10830 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
10831 .unsol_event = alc262_hp_bpc_unsol_event,
10832 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 10833 },
cd7509a4
KY
10834 [ALC262_HP_BPC_D7000_WF] = {
10835 .mixers = { alc262_HP_BPC_WildWest_mixer },
10836 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10837 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10838 .dac_nids = alc262_dac_nids,
10839 .hp_nid = 0x03,
10840 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10841 .channel_mode = alc262_modes,
accbe498 10842 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
10843 .unsol_event = alc262_hp_wildwest_unsol_event,
10844 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 10845 },
cd7509a4
KY
10846 [ALC262_HP_BPC_D7000_WL] = {
10847 .mixers = { alc262_HP_BPC_WildWest_mixer,
10848 alc262_HP_BPC_WildWest_option_mixer },
10849 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10850 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10851 .dac_nids = alc262_dac_nids,
10852 .hp_nid = 0x03,
10853 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10854 .channel_mode = alc262_modes,
accbe498 10855 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
10856 .unsol_event = alc262_hp_wildwest_unsol_event,
10857 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 10858 },
66d2a9d6
KY
10859 [ALC262_HP_TC_T5735] = {
10860 .mixers = { alc262_hp_t5735_mixer },
10861 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10862 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10863 .dac_nids = alc262_dac_nids,
10864 .hp_nid = 0x03,
10865 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10866 .channel_mode = alc262_modes,
10867 .input_mux = &alc262_capture_source,
10868 .unsol_event = alc262_hp_t5735_unsol_event,
10869 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
10870 },
10871 [ALC262_HP_RP5700] = {
10872 .mixers = { alc262_hp_rp5700_mixer },
10873 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10874 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10875 .dac_nids = alc262_dac_nids,
10876 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10877 .channel_mode = alc262_modes,
10878 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 10879 },
304dcaac
TI
10880 [ALC262_BENQ_ED8] = {
10881 .mixers = { alc262_base_mixer },
10882 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10883 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10884 .dac_nids = alc262_dac_nids,
10885 .hp_nid = 0x03,
10886 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10887 .channel_mode = alc262_modes,
10888 .input_mux = &alc262_capture_source,
f12ab1e0 10889 },
272a527c
KY
10890 [ALC262_SONY_ASSAMD] = {
10891 .mixers = { alc262_sony_mixer },
10892 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10893 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10894 .dac_nids = alc262_dac_nids,
10895 .hp_nid = 0x02,
10896 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10897 .channel_mode = alc262_modes,
10898 .input_mux = &alc262_capture_source,
10899 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10900 .init_hook = alc262_hippo_automute,
83c34218
KY
10901 },
10902 [ALC262_BENQ_T31] = {
10903 .mixers = { alc262_benq_t31_mixer },
10904 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10905 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10906 .dac_nids = alc262_dac_nids,
10907 .hp_nid = 0x03,
10908 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10909 .channel_mode = alc262_modes,
10910 .input_mux = &alc262_capture_source,
10911 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10912 .init_hook = alc262_hippo_automute,
ea1fb29a 10913 },
f651b50b 10914 [ALC262_ULTRA] = {
f9e336f6
TI
10915 .mixers = { alc262_ultra_mixer },
10916 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 10917 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
10918 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10919 .dac_nids = alc262_dac_nids,
f651b50b
TD
10920 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10921 .channel_mode = alc262_modes,
10922 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
10923 .adc_nids = alc262_adc_nids, /* ADC0 */
10924 .capsrc_nids = alc262_capsrc_nids,
10925 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
10926 .unsol_event = alc262_ultra_unsol_event,
10927 .init_hook = alc262_ultra_automute,
10928 },
0e31daf7
J
10929 [ALC262_LENOVO_3000] = {
10930 .mixers = { alc262_lenovo_3000_mixer },
10931 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10932 alc262_lenovo_3000_unsol_verbs },
10933 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10934 .dac_nids = alc262_dac_nids,
10935 .hp_nid = 0x03,
10936 .dig_out_nid = ALC262_DIGOUT_NID,
10937 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10938 .channel_mode = alc262_modes,
10939 .input_mux = &alc262_fujitsu_capture_source,
10940 .unsol_event = alc262_lenovo_3000_unsol_event,
10941 },
e8f9ae2a
PT
10942 [ALC262_NEC] = {
10943 .mixers = { alc262_nec_mixer },
10944 .init_verbs = { alc262_nec_verbs },
10945 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10946 .dac_nids = alc262_dac_nids,
10947 .hp_nid = 0x03,
10948 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10949 .channel_mode = alc262_modes,
10950 .input_mux = &alc262_capture_source,
10951 },
4e555fe5
KY
10952 [ALC262_TOSHIBA_S06] = {
10953 .mixers = { alc262_toshiba_s06_mixer },
10954 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10955 alc262_eapd_verbs },
10956 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10957 .capsrc_nids = alc262_dmic_capsrc_nids,
10958 .dac_nids = alc262_dac_nids,
10959 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10960 .dig_out_nid = ALC262_DIGOUT_NID,
10961 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10962 .channel_mode = alc262_modes,
10963 .input_mux = &alc262_dmic_capture_source,
10964 .unsol_event = alc262_toshiba_s06_unsol_event,
10965 .init_hook = alc262_toshiba_s06_init_hook,
10966 },
9f99a638
HM
10967 [ALC262_TOSHIBA_RX1] = {
10968 .mixers = { alc262_toshiba_rx1_mixer },
10969 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10970 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10971 .dac_nids = alc262_dac_nids,
10972 .hp_nid = 0x03,
10973 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10974 .channel_mode = alc262_modes,
10975 .input_mux = &alc262_capture_source,
10976 .unsol_event = alc262_hippo_unsol_event,
10977 .init_hook = alc262_hippo_automute,
10978 },
ba340e82
TV
10979 [ALC262_TYAN] = {
10980 .mixers = { alc262_tyan_mixer },
10981 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
10982 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10983 .dac_nids = alc262_dac_nids,
10984 .hp_nid = 0x02,
10985 .dig_out_nid = ALC262_DIGOUT_NID,
10986 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10987 .channel_mode = alc262_modes,
10988 .input_mux = &alc262_capture_source,
10989 .unsol_event = alc262_tyan_unsol_event,
10990 .init_hook = alc262_tyan_automute,
10991 },
df694daa
KY
10992};
10993
10994static int patch_alc262(struct hda_codec *codec)
10995{
10996 struct alc_spec *spec;
10997 int board_config;
10998 int err;
10999
dc041e0b 11000 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11001 if (spec == NULL)
11002 return -ENOMEM;
11003
11004 codec->spec = spec;
11005#if 0
f12ab1e0
TI
11006 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11007 * under-run
11008 */
df694daa
KY
11009 {
11010 int tmp;
11011 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11012 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11013 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11014 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11015 }
11016#endif
11017
2c3bf9ab
TI
11018 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11019
f5fcc13c
TI
11020 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11021 alc262_models,
11022 alc262_cfg_tbl);
cd7509a4 11023
f5fcc13c 11024 if (board_config < 0) {
9c7f852e
TI
11025 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11026 "trying auto-probe from BIOS...\n");
df694daa
KY
11027 board_config = ALC262_AUTO;
11028 }
11029
11030 if (board_config == ALC262_AUTO) {
11031 /* automatic parse from the BIOS config */
11032 err = alc262_parse_auto_config(codec);
11033 if (err < 0) {
11034 alc_free(codec);
11035 return err;
f12ab1e0 11036 } else if (!err) {
9c7f852e
TI
11037 printk(KERN_INFO
11038 "hda_codec: Cannot set up configuration "
11039 "from BIOS. Using base mode...\n");
df694daa
KY
11040 board_config = ALC262_BASIC;
11041 }
11042 }
11043
680cd536
KK
11044 err = snd_hda_attach_beep_device(codec, 0x1);
11045 if (err < 0) {
11046 alc_free(codec);
11047 return err;
11048 }
11049
df694daa
KY
11050 if (board_config != ALC262_AUTO)
11051 setup_preset(spec, &alc262_presets[board_config]);
11052
11053 spec->stream_name_analog = "ALC262 Analog";
11054 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11055 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 11056
df694daa
KY
11057 spec->stream_name_digital = "ALC262 Digital";
11058 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11059 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11060
61b9b9b1 11061 spec->capture_style = CAPT_MIX;
f12ab1e0 11062 if (!spec->adc_nids && spec->input_mux) {
df694daa 11063 /* check whether NID 0x07 is valid */
4a471b7d
TI
11064 unsigned int wcap = get_wcaps(codec, 0x07);
11065
f12ab1e0
TI
11066 /* get type */
11067 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
11068 if (wcap != AC_WID_AUD_IN) {
11069 spec->adc_nids = alc262_adc_nids_alt;
11070 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 11071 spec->capsrc_nids = alc262_capsrc_nids_alt;
df694daa
KY
11072 } else {
11073 spec->adc_nids = alc262_adc_nids;
11074 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 11075 spec->capsrc_nids = alc262_capsrc_nids;
df694daa
KY
11076 }
11077 }
e64f14f4 11078 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 11079 set_capture_mixer(spec);
df694daa 11080
2134ea4f
TI
11081 spec->vmaster_nid = 0x0c;
11082
df694daa
KY
11083 codec->patch_ops = alc_patch_ops;
11084 if (board_config == ALC262_AUTO)
ae6b813a 11085 spec->init_hook = alc262_auto_init;
cb53c626
TI
11086#ifdef CONFIG_SND_HDA_POWER_SAVE
11087 if (!spec->loopback.amplist)
11088 spec->loopback.amplist = alc262_loopbacks;
11089#endif
daead538 11090 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 11091
df694daa
KY
11092 return 0;
11093}
11094
a361d84b
KY
11095/*
11096 * ALC268 channel source setting (2 channel)
11097 */
11098#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11099#define alc268_modes alc260_modes
ea1fb29a 11100
a361d84b
KY
11101static hda_nid_t alc268_dac_nids[2] = {
11102 /* front, hp */
11103 0x02, 0x03
11104};
11105
11106static hda_nid_t alc268_adc_nids[2] = {
11107 /* ADC0-1 */
11108 0x08, 0x07
11109};
11110
11111static hda_nid_t alc268_adc_nids_alt[1] = {
11112 /* ADC0 */
11113 0x08
11114};
11115
e1406348
TI
11116static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11117
a361d84b
KY
11118static struct snd_kcontrol_new alc268_base_mixer[] = {
11119 /* output mixer control */
11120 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11121 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11122 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11123 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
11124 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11125 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11126 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
11127 { }
11128};
11129
aef9d318
TI
11130/* bind Beep switches of both NID 0x0f and 0x10 */
11131static struct hda_bind_ctls alc268_bind_beep_sw = {
11132 .ops = &snd_hda_bind_sw,
11133 .values = {
11134 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11135 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11136 0
11137 },
11138};
11139
11140static struct snd_kcontrol_new alc268_beep_mixer[] = {
11141 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11142 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11143 { }
11144};
11145
d1a991a6
KY
11146static struct hda_verb alc268_eapd_verbs[] = {
11147 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11148 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11149 { }
11150};
11151
d273809e
TI
11152/* Toshiba specific */
11153#define alc268_toshiba_automute alc262_hippo_automute
11154
11155static struct hda_verb alc268_toshiba_verbs[] = {
11156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11157 { } /* end */
11158};
11159
8ef355da
KY
11160static struct hda_input_mux alc268_acer_lc_capture_source = {
11161 .num_items = 2,
11162 .items = {
11163 { "i-Mic", 0x6 },
11164 { "E-Mic", 0x0 },
11165 },
11166};
11167
d273809e 11168/* Acer specific */
889c4395 11169/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
11170static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11171 .ops = &snd_hda_bind_vol,
11172 .values = {
11173 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11174 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11175 0
11176 },
11177};
11178
889c4395
TI
11179/* mute/unmute internal speaker according to the hp jack and mute state */
11180static void alc268_acer_automute(struct hda_codec *codec, int force)
11181{
11182 struct alc_spec *spec = codec->spec;
11183 unsigned int mute;
11184
11185 if (force || !spec->sense_updated) {
11186 unsigned int present;
11187 present = snd_hda_codec_read(codec, 0x14, 0,
11188 AC_VERB_GET_PIN_SENSE, 0);
11189 spec->jack_present = (present & 0x80000000) != 0;
11190 spec->sense_updated = 1;
11191 }
11192 if (spec->jack_present)
11193 mute = HDA_AMP_MUTE; /* mute internal speaker */
11194 else /* unmute internal speaker if necessary */
11195 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11196 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11197 HDA_AMP_MUTE, mute);
11198}
11199
11200
11201/* bind hp and internal speaker mute (with plug check) */
11202static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11203 struct snd_ctl_elem_value *ucontrol)
11204{
11205 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11206 long *valp = ucontrol->value.integer.value;
11207 int change;
11208
11209 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11210 HDA_AMP_MUTE,
11211 valp[0] ? 0 : HDA_AMP_MUTE);
11212 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11213 HDA_AMP_MUTE,
11214 valp[1] ? 0 : HDA_AMP_MUTE);
11215 if (change)
11216 alc268_acer_automute(codec, 0);
11217 return change;
11218}
d273809e 11219
8ef355da
KY
11220static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11221 /* output mixer control */
11222 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11223 {
11224 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11225 .name = "Master Playback Switch",
11226 .info = snd_hda_mixer_amp_switch_info,
11227 .get = snd_hda_mixer_amp_switch_get,
11228 .put = alc268_acer_master_sw_put,
11229 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11230 },
11231 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11232 { }
11233};
11234
d273809e
TI
11235static struct snd_kcontrol_new alc268_acer_mixer[] = {
11236 /* output mixer control */
11237 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11238 {
11239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11240 .name = "Master Playback Switch",
11241 .info = snd_hda_mixer_amp_switch_info,
11242 .get = snd_hda_mixer_amp_switch_get,
11243 .put = alc268_acer_master_sw_put,
11244 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11245 },
33bf17ab
TI
11246 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11247 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11248 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
11249 { }
11250};
11251
c238b4f4
TI
11252static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11253 /* output mixer control */
11254 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11255 {
11256 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11257 .name = "Master Playback Switch",
11258 .info = snd_hda_mixer_amp_switch_info,
11259 .get = snd_hda_mixer_amp_switch_get,
11260 .put = alc268_acer_master_sw_put,
11261 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11262 },
11263 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11264 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11265 { }
11266};
11267
8ef355da
KY
11268static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11269 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11271 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11272 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11273 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11274 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11275 { }
11276};
11277
d273809e 11278static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
11279 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11280 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
11281 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
11283 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11284 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
11285 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11286 { }
11287};
11288
11289/* unsolicited event for HP jack sensing */
11290static void alc268_toshiba_unsol_event(struct hda_codec *codec,
11291 unsigned int res)
11292{
889c4395 11293 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
11294 return;
11295 alc268_toshiba_automute(codec);
11296}
11297
11298static void alc268_acer_unsol_event(struct hda_codec *codec,
11299 unsigned int res)
11300{
889c4395 11301 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
11302 return;
11303 alc268_acer_automute(codec, 1);
11304}
11305
889c4395
TI
11306static void alc268_acer_init_hook(struct hda_codec *codec)
11307{
11308 alc268_acer_automute(codec, 1);
11309}
11310
8ef355da
KY
11311/* toggle speaker-output according to the hp-jack state */
11312static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11313{
11314 unsigned int present;
11315 unsigned char bits;
11316
11317 present = snd_hda_codec_read(codec, 0x15, 0,
11318 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11319 bits = present ? AMP_IN_MUTE(0) : 0;
11320 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11321 AMP_IN_MUTE(0), bits);
11322 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11323 AMP_IN_MUTE(0), bits);
11324}
11325
11326
11327static void alc268_acer_mic_automute(struct hda_codec *codec)
11328{
11329 unsigned int present;
11330
11331 present = snd_hda_codec_read(codec, 0x18, 0,
11332 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11333 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11334 present ? 0x0 : 0x6);
11335}
11336
11337static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11338 unsigned int res)
11339{
11340 if ((res >> 26) == ALC880_HP_EVENT)
11341 alc268_aspire_one_speaker_automute(codec);
11342 if ((res >> 26) == ALC880_MIC_EVENT)
11343 alc268_acer_mic_automute(codec);
11344}
11345
11346static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11347{
11348 alc268_aspire_one_speaker_automute(codec);
11349 alc268_acer_mic_automute(codec);
11350}
11351
3866f0b0
TI
11352static struct snd_kcontrol_new alc268_dell_mixer[] = {
11353 /* output mixer control */
11354 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11355 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11356 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11357 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11358 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11359 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11360 { }
11361};
11362
11363static struct hda_verb alc268_dell_verbs[] = {
11364 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11365 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11366 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11367 { }
11368};
11369
11370/* mute/unmute internal speaker according to the hp jack and mute state */
11371static void alc268_dell_automute(struct hda_codec *codec)
11372{
11373 unsigned int present;
11374 unsigned int mute;
11375
11376 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11377 if (present & 0x80000000)
11378 mute = HDA_AMP_MUTE;
11379 else
11380 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11381 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11382 HDA_AMP_MUTE, mute);
11383}
11384
11385static void alc268_dell_unsol_event(struct hda_codec *codec,
11386 unsigned int res)
11387{
11388 if ((res >> 26) != ALC880_HP_EVENT)
11389 return;
11390 alc268_dell_automute(codec);
11391}
11392
11393#define alc268_dell_init_hook alc268_dell_automute
11394
eb5a6621
HRK
11395static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11396 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11397 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11398 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11400 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11401 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11402 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11403 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11404 { }
11405};
11406
11407static struct hda_verb alc267_quanta_il1_verbs[] = {
11408 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11409 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11410 { }
11411};
11412
11413static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11414{
11415 unsigned int present;
11416
11417 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11418 & AC_PINSENSE_PRESENCE;
11419 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11420 present ? 0 : PIN_OUT);
11421}
11422
11423static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11424{
11425 unsigned int present;
11426
11427 present = snd_hda_codec_read(codec, 0x18, 0,
11428 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11429 snd_hda_codec_write(codec, 0x23, 0,
11430 AC_VERB_SET_CONNECT_SEL,
11431 present ? 0x00 : 0x01);
11432}
11433
11434static void alc267_quanta_il1_automute(struct hda_codec *codec)
11435{
11436 alc267_quanta_il1_hp_automute(codec);
11437 alc267_quanta_il1_mic_automute(codec);
11438}
11439
11440static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11441 unsigned int res)
11442{
11443 switch (res >> 26) {
11444 case ALC880_HP_EVENT:
11445 alc267_quanta_il1_hp_automute(codec);
11446 break;
11447 case ALC880_MIC_EVENT:
11448 alc267_quanta_il1_mic_automute(codec);
11449 break;
11450 }
11451}
11452
a361d84b
KY
11453/*
11454 * generic initialization of ADC, input mixers and output mixers
11455 */
11456static struct hda_verb alc268_base_init_verbs[] = {
11457 /* Unmute DAC0-1 and set vol = 0 */
11458 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 11459 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11460
11461 /*
11462 * Set up output mixers (0x0c - 0x0e)
11463 */
11464 /* set vol=0 to output mixers */
11465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11466 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11467
11468 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11469 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11470
11471 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11472 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11473 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11475 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11476 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11477 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11478 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11479
11480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11482 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11483 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11484 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
11485
11486 /* set PCBEEP vol = 0, mute connections */
11487 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11488 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11489 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 11490
a9b3aa8a 11491 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 11492
a9b3aa8a
JZ
11493 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11494 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11495 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 11497
a361d84b
KY
11498 { }
11499};
11500
11501/*
11502 * generic initialization of ADC, input mixers and output mixers
11503 */
11504static struct hda_verb alc268_volume_init_verbs[] = {
11505 /* set output DAC */
4cfb91c6
TI
11506 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11507 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11508
11509 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11511 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11512 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11513 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11514
a361d84b 11515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11516 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11517 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11518
11519 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11520 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11521
aef9d318
TI
11522 /* set PCBEEP vol = 0, mute connections */
11523 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11524 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11525 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
11526
11527 { }
11528};
11529
a361d84b
KY
11530static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11531 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11532 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11533 {
11534 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11535 /* The multiple "Capture Source" controls confuse alsamixer
11536 * So call somewhat different..
a361d84b
KY
11537 */
11538 /* .name = "Capture Source", */
11539 .name = "Input Source",
11540 .count = 1,
54cbc9ab
TI
11541 .info = alc_mux_enum_info,
11542 .get = alc_mux_enum_get,
11543 .put = alc_mux_enum_put,
a361d84b
KY
11544 },
11545 { } /* end */
11546};
11547
11548static struct snd_kcontrol_new alc268_capture_mixer[] = {
11549 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11550 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11551 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11552 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11553 {
11554 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11555 /* The multiple "Capture Source" controls confuse alsamixer
11556 * So call somewhat different..
a361d84b
KY
11557 */
11558 /* .name = "Capture Source", */
11559 .name = "Input Source",
11560 .count = 2,
54cbc9ab
TI
11561 .info = alc_mux_enum_info,
11562 .get = alc_mux_enum_get,
11563 .put = alc_mux_enum_put,
a361d84b
KY
11564 },
11565 { } /* end */
11566};
11567
11568static struct hda_input_mux alc268_capture_source = {
11569 .num_items = 4,
11570 .items = {
11571 { "Mic", 0x0 },
11572 { "Front Mic", 0x1 },
11573 { "Line", 0x2 },
11574 { "CD", 0x3 },
11575 },
11576};
11577
0ccb541c 11578static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
11579 .num_items = 3,
11580 .items = {
11581 { "Mic", 0x0 },
11582 { "Internal Mic", 0x1 },
11583 { "Line", 0x2 },
11584 },
11585};
11586
11587static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
11588 .num_items = 3,
11589 .items = {
11590 { "Mic", 0x0 },
11591 { "Internal Mic", 0x6 },
11592 { "Line", 0x2 },
11593 },
11594};
11595
86c53bd2
JW
11596#ifdef CONFIG_SND_DEBUG
11597static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
11598 /* Volume widgets */
11599 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11600 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11601 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11602 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11603 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11604 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11605 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11606 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11607 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11608 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11609 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11610 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11611 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
11612 /* The below appears problematic on some hardwares */
11613 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
11614 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11615 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11616 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11617 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11618
11619 /* Modes for retasking pin widgets */
11620 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11621 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11622 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11623 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11624
11625 /* Controls for GPIO pins, assuming they are configured as outputs */
11626 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11627 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11628 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11629 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11630
11631 /* Switches to allow the digital SPDIF output pin to be enabled.
11632 * The ALC268 does not have an SPDIF input.
11633 */
11634 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11635
11636 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11637 * this output to turn on an external amplifier.
11638 */
11639 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11640 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11641
11642 { } /* end */
11643};
11644#endif
11645
a361d84b
KY
11646/* create input playback/capture controls for the given pin */
11647static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11648 const char *ctlname, int idx)
11649{
11650 char name[32];
11651 int err;
11652
11653 sprintf(name, "%s Playback Volume", ctlname);
11654 if (nid == 0x14) {
11655 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11656 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11657 HDA_OUTPUT));
11658 if (err < 0)
11659 return err;
11660 } else if (nid == 0x15) {
11661 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11662 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11663 HDA_OUTPUT));
11664 if (err < 0)
11665 return err;
11666 } else
11667 return -1;
11668 sprintf(name, "%s Playback Switch", ctlname);
11669 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11670 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11671 if (err < 0)
11672 return err;
11673 return 0;
11674}
11675
11676/* add playback controls from the parsed DAC table */
11677static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11678 const struct auto_pin_cfg *cfg)
11679{
11680 hda_nid_t nid;
11681 int err;
11682
11683 spec->multiout.num_dacs = 2; /* only use one dac */
11684 spec->multiout.dac_nids = spec->private_dac_nids;
11685 spec->multiout.dac_nids[0] = 2;
11686 spec->multiout.dac_nids[1] = 3;
11687
11688 nid = cfg->line_out_pins[0];
11689 if (nid)
ea1fb29a 11690 alc268_new_analog_output(spec, nid, "Front", 0);
a361d84b
KY
11691
11692 nid = cfg->speaker_pins[0];
11693 if (nid == 0x1d) {
11694 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11695 "Speaker Playback Volume",
11696 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11697 if (err < 0)
11698 return err;
11699 }
11700 nid = cfg->hp_pins[0];
11701 if (nid)
11702 alc268_new_analog_output(spec, nid, "Headphone", 0);
11703
11704 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11705 if (nid == 0x16) {
11706 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11707 "Mono Playback Switch",
11708 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11709 if (err < 0)
11710 return err;
11711 }
ea1fb29a 11712 return 0;
a361d84b
KY
11713}
11714
11715/* create playback/capture controls for input pins */
11716static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11717 const struct auto_pin_cfg *cfg)
11718{
61b9b9b1 11719 struct hda_input_mux *imux = &spec->private_imux[0];
a361d84b
KY
11720 int i, idx1;
11721
11722 for (i = 0; i < AUTO_PIN_LAST; i++) {
11723 switch(cfg->input_pins[i]) {
11724 case 0x18:
11725 idx1 = 0; /* Mic 1 */
11726 break;
11727 case 0x19:
11728 idx1 = 1; /* Mic 2 */
11729 break;
11730 case 0x1a:
11731 idx1 = 2; /* Line In */
11732 break;
ea1fb29a 11733 case 0x1c:
a361d84b
KY
11734 idx1 = 3; /* CD */
11735 break;
7194cae6
TI
11736 case 0x12:
11737 case 0x13:
11738 idx1 = 6; /* digital mics */
11739 break;
a361d84b
KY
11740 default:
11741 continue;
11742 }
11743 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11744 imux->items[imux->num_items].index = idx1;
ea1fb29a 11745 imux->num_items++;
a361d84b
KY
11746 }
11747 return 0;
11748}
11749
11750static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11751{
11752 struct alc_spec *spec = codec->spec;
11753 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11754 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11755 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11756 unsigned int dac_vol1, dac_vol2;
11757
11758 if (speaker_nid) {
11759 snd_hda_codec_write(codec, speaker_nid, 0,
11760 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11761 snd_hda_codec_write(codec, 0x0f, 0,
11762 AC_VERB_SET_AMP_GAIN_MUTE,
11763 AMP_IN_UNMUTE(1));
11764 snd_hda_codec_write(codec, 0x10, 0,
11765 AC_VERB_SET_AMP_GAIN_MUTE,
11766 AMP_IN_UNMUTE(1));
11767 } else {
11768 snd_hda_codec_write(codec, 0x0f, 0,
11769 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11770 snd_hda_codec_write(codec, 0x10, 0,
11771 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11772 }
11773
11774 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 11775 if (line_nid == 0x14)
a361d84b
KY
11776 dac_vol2 = AMP_OUT_ZERO;
11777 else if (line_nid == 0x15)
11778 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 11779 if (hp_nid == 0x14)
a361d84b
KY
11780 dac_vol2 = AMP_OUT_ZERO;
11781 else if (hp_nid == 0x15)
11782 dac_vol1 = AMP_OUT_ZERO;
11783 if (line_nid != 0x16 || hp_nid != 0x16 ||
11784 spec->autocfg.line_out_pins[1] != 0x16 ||
11785 spec->autocfg.line_out_pins[2] != 0x16)
11786 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11787
11788 snd_hda_codec_write(codec, 0x02, 0,
11789 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11790 snd_hda_codec_write(codec, 0x03, 0,
11791 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11792}
11793
11794/* pcm configuration: identiacal with ALC880 */
11795#define alc268_pcm_analog_playback alc880_pcm_analog_playback
11796#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 11797#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
11798#define alc268_pcm_digital_playback alc880_pcm_digital_playback
11799
11800/*
11801 * BIOS auto configuration
11802 */
11803static int alc268_parse_auto_config(struct hda_codec *codec)
11804{
11805 struct alc_spec *spec = codec->spec;
11806 int err;
11807 static hda_nid_t alc268_ignore[] = { 0 };
11808
11809 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11810 alc268_ignore);
11811 if (err < 0)
11812 return err;
11813 if (!spec->autocfg.line_outs)
11814 return 0; /* can't find valid BIOS pin config */
11815
11816 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11817 if (err < 0)
11818 return err;
11819 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11820 if (err < 0)
11821 return err;
11822
11823 spec->multiout.max_channels = 2;
11824
11825 /* digital only support output */
11826 if (spec->autocfg.dig_out_pin)
11827 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11828
603c4019 11829 if (spec->kctls.list)
d88897ea 11830 add_mixer(spec, spec->kctls.list);
a361d84b 11831
aef9d318 11832 if (spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 11833 add_mixer(spec, alc268_beep_mixer);
aef9d318 11834
d88897ea 11835 add_verb(spec, alc268_volume_init_verbs);
a361d84b 11836 spec->num_mux_defs = 1;
61b9b9b1 11837 spec->input_mux = &spec->private_imux[0];
a361d84b 11838
776e184e
TI
11839 err = alc_auto_add_mic_boost(codec);
11840 if (err < 0)
11841 return err;
11842
e044c39a 11843 store_pin_configs(codec);
a361d84b
KY
11844 return 1;
11845}
11846
11847#define alc268_auto_init_multi_out alc882_auto_init_multi_out
11848#define alc268_auto_init_hp_out alc882_auto_init_hp_out
11849#define alc268_auto_init_analog_input alc882_auto_init_analog_input
11850
11851/* init callback for auto-configuration model -- overriding the default init */
11852static void alc268_auto_init(struct hda_codec *codec)
11853{
f6c7e546 11854 struct alc_spec *spec = codec->spec;
a361d84b
KY
11855 alc268_auto_init_multi_out(codec);
11856 alc268_auto_init_hp_out(codec);
11857 alc268_auto_init_mono_speaker_out(codec);
11858 alc268_auto_init_analog_input(codec);
f6c7e546 11859 if (spec->unsol_event)
7fb0d78f 11860 alc_inithook(codec);
a361d84b
KY
11861}
11862
11863/*
11864 * configuration and preset
11865 */
11866static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 11867 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 11868 [ALC268_3ST] = "3stack",
983f8ae4 11869 [ALC268_TOSHIBA] = "toshiba",
d273809e 11870 [ALC268_ACER] = "acer",
c238b4f4 11871 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 11872 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 11873 [ALC268_DELL] = "dell",
f12462c5 11874 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
11875#ifdef CONFIG_SND_DEBUG
11876 [ALC268_TEST] = "test",
11877#endif
a361d84b
KY
11878 [ALC268_AUTO] = "auto",
11879};
11880
11881static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 11882 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 11883 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 11884 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 11885 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 11886 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
11887 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11888 ALC268_ACER_ASPIRE_ONE),
3866f0b0 11889 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
57d13927 11890 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
ac3e3741 11891 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 11892 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 11893 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 11894 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
2346d0cd 11895 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
378bd6a5 11896 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 11897 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 11898 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
f12462c5 11899 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
11900 {}
11901};
11902
11903static struct alc_config_preset alc268_presets[] = {
eb5a6621
HRK
11904 [ALC267_QUANTA_IL1] = {
11905 .mixers = { alc267_quanta_il1_mixer },
11906 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11907 alc267_quanta_il1_verbs },
11908 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11909 .dac_nids = alc268_dac_nids,
11910 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11911 .adc_nids = alc268_adc_nids_alt,
11912 .hp_nid = 0x03,
11913 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11914 .channel_mode = alc268_modes,
11915 .input_mux = &alc268_capture_source,
11916 .unsol_event = alc267_quanta_il1_unsol_event,
11917 .init_hook = alc267_quanta_il1_automute,
11918 },
a361d84b 11919 [ALC268_3ST] = {
aef9d318
TI
11920 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11921 alc268_beep_mixer },
a361d84b
KY
11922 .init_verbs = { alc268_base_init_verbs },
11923 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11924 .dac_nids = alc268_dac_nids,
11925 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11926 .adc_nids = alc268_adc_nids_alt,
e1406348 11927 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
11928 .hp_nid = 0x03,
11929 .dig_out_nid = ALC268_DIGOUT_NID,
11930 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11931 .channel_mode = alc268_modes,
11932 .input_mux = &alc268_capture_source,
11933 },
d1a991a6 11934 [ALC268_TOSHIBA] = {
aef9d318
TI
11935 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11936 alc268_beep_mixer },
d273809e
TI
11937 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11938 alc268_toshiba_verbs },
d1a991a6
KY
11939 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11940 .dac_nids = alc268_dac_nids,
11941 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11942 .adc_nids = alc268_adc_nids_alt,
e1406348 11943 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
11944 .hp_nid = 0x03,
11945 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11946 .channel_mode = alc268_modes,
11947 .input_mux = &alc268_capture_source,
d273809e
TI
11948 .unsol_event = alc268_toshiba_unsol_event,
11949 .init_hook = alc268_toshiba_automute,
11950 },
11951 [ALC268_ACER] = {
aef9d318
TI
11952 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11953 alc268_beep_mixer },
d273809e
TI
11954 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11955 alc268_acer_verbs },
11956 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11957 .dac_nids = alc268_dac_nids,
11958 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11959 .adc_nids = alc268_adc_nids_alt,
e1406348 11960 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
11961 .hp_nid = 0x02,
11962 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11963 .channel_mode = alc268_modes,
0ccb541c 11964 .input_mux = &alc268_acer_capture_source,
d273809e 11965 .unsol_event = alc268_acer_unsol_event,
889c4395 11966 .init_hook = alc268_acer_init_hook,
d1a991a6 11967 },
c238b4f4
TI
11968 [ALC268_ACER_DMIC] = {
11969 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11970 alc268_beep_mixer },
11971 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11972 alc268_acer_verbs },
11973 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11974 .dac_nids = alc268_dac_nids,
11975 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11976 .adc_nids = alc268_adc_nids_alt,
11977 .capsrc_nids = alc268_capsrc_nids,
11978 .hp_nid = 0x02,
11979 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11980 .channel_mode = alc268_modes,
11981 .input_mux = &alc268_acer_dmic_capture_source,
11982 .unsol_event = alc268_acer_unsol_event,
11983 .init_hook = alc268_acer_init_hook,
11984 },
8ef355da
KY
11985 [ALC268_ACER_ASPIRE_ONE] = {
11986 .mixers = { alc268_acer_aspire_one_mixer,
11987 alc268_capture_alt_mixer },
11988 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11989 alc268_acer_aspire_one_verbs },
11990 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11991 .dac_nids = alc268_dac_nids,
11992 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11993 .adc_nids = alc268_adc_nids_alt,
11994 .capsrc_nids = alc268_capsrc_nids,
11995 .hp_nid = 0x03,
11996 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11997 .channel_mode = alc268_modes,
11998 .input_mux = &alc268_acer_lc_capture_source,
11999 .unsol_event = alc268_acer_lc_unsol_event,
12000 .init_hook = alc268_acer_lc_init_hook,
12001 },
3866f0b0 12002 [ALC268_DELL] = {
aef9d318 12003 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
12004 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12005 alc268_dell_verbs },
12006 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12007 .dac_nids = alc268_dac_nids,
12008 .hp_nid = 0x02,
12009 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12010 .channel_mode = alc268_modes,
12011 .unsol_event = alc268_dell_unsol_event,
12012 .init_hook = alc268_dell_init_hook,
12013 .input_mux = &alc268_capture_source,
12014 },
f12462c5 12015 [ALC268_ZEPTO] = {
aef9d318
TI
12016 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12017 alc268_beep_mixer },
f12462c5
MT
12018 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12019 alc268_toshiba_verbs },
12020 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12021 .dac_nids = alc268_dac_nids,
12022 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12023 .adc_nids = alc268_adc_nids_alt,
e1406348 12024 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
12025 .hp_nid = 0x03,
12026 .dig_out_nid = ALC268_DIGOUT_NID,
12027 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12028 .channel_mode = alc268_modes,
12029 .input_mux = &alc268_capture_source,
12030 .unsol_event = alc268_toshiba_unsol_event,
12031 .init_hook = alc268_toshiba_automute
12032 },
86c53bd2
JW
12033#ifdef CONFIG_SND_DEBUG
12034 [ALC268_TEST] = {
12035 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12036 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12037 alc268_volume_init_verbs },
12038 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12039 .dac_nids = alc268_dac_nids,
12040 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12041 .adc_nids = alc268_adc_nids_alt,
e1406348 12042 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
12043 .hp_nid = 0x03,
12044 .dig_out_nid = ALC268_DIGOUT_NID,
12045 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12046 .channel_mode = alc268_modes,
12047 .input_mux = &alc268_capture_source,
12048 },
12049#endif
a361d84b
KY
12050};
12051
12052static int patch_alc268(struct hda_codec *codec)
12053{
12054 struct alc_spec *spec;
12055 int board_config;
12056 int err;
12057
12058 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12059 if (spec == NULL)
12060 return -ENOMEM;
12061
12062 codec->spec = spec;
12063
12064 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12065 alc268_models,
12066 alc268_cfg_tbl);
12067
12068 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12069 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12070 "trying auto-probe from BIOS...\n");
12071 board_config = ALC268_AUTO;
12072 }
12073
12074 if (board_config == ALC268_AUTO) {
12075 /* automatic parse from the BIOS config */
12076 err = alc268_parse_auto_config(codec);
12077 if (err < 0) {
12078 alc_free(codec);
12079 return err;
12080 } else if (!err) {
12081 printk(KERN_INFO
12082 "hda_codec: Cannot set up configuration "
12083 "from BIOS. Using base mode...\n");
12084 board_config = ALC268_3ST;
12085 }
12086 }
12087
680cd536
KK
12088 err = snd_hda_attach_beep_device(codec, 0x1);
12089 if (err < 0) {
12090 alc_free(codec);
12091 return err;
12092 }
12093
a361d84b
KY
12094 if (board_config != ALC268_AUTO)
12095 setup_preset(spec, &alc268_presets[board_config]);
12096
2f893286
KY
12097 if (codec->vendor_id == 0x10ec0267) {
12098 spec->stream_name_analog = "ALC267 Analog";
12099 spec->stream_name_digital = "ALC267 Digital";
12100 } else {
12101 spec->stream_name_analog = "ALC268 Analog";
12102 spec->stream_name_digital = "ALC268 Digital";
12103 }
12104
a361d84b
KY
12105 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12106 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 12107 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 12108
a361d84b
KY
12109 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12110
aef9d318
TI
12111 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12112 /* override the amp caps for beep generator */
12113 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12114 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12115 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12116 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12117 (0 << AC_AMPCAP_MUTE_SHIFT));
12118
3866f0b0
TI
12119 if (!spec->adc_nids && spec->input_mux) {
12120 /* check whether NID 0x07 is valid */
12121 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 12122 int i;
3866f0b0
TI
12123
12124 /* get type */
12125 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 12126 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
12127 spec->adc_nids = alc268_adc_nids_alt;
12128 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
d88897ea 12129 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
12130 } else {
12131 spec->adc_nids = alc268_adc_nids;
12132 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 12133 add_mixer(spec, alc268_capture_mixer);
a361d84b 12134 }
e1406348 12135 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
12136 /* set default input source */
12137 for (i = 0; i < spec->num_adc_nids; i++)
12138 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12139 0, AC_VERB_SET_CONNECT_SEL,
12140 spec->input_mux->items[0].index);
a361d84b 12141 }
2134ea4f
TI
12142
12143 spec->vmaster_nid = 0x02;
12144
a361d84b
KY
12145 codec->patch_ops = alc_patch_ops;
12146 if (board_config == ALC268_AUTO)
12147 spec->init_hook = alc268_auto_init;
ea1fb29a 12148
daead538
TI
12149 codec->proc_widget_hook = print_realtek_coef;
12150
a361d84b
KY
12151 return 0;
12152}
12153
f6a92248
KY
12154/*
12155 * ALC269 channel source setting (2 channel)
12156 */
12157#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12158
12159#define alc269_dac_nids alc260_dac_nids
12160
12161static hda_nid_t alc269_adc_nids[1] = {
12162 /* ADC1 */
f53281e6
KY
12163 0x08,
12164};
12165
e01bf509
TI
12166static hda_nid_t alc269_capsrc_nids[1] = {
12167 0x23,
12168};
12169
12170/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12171 * not a mux!
12172 */
12173
f53281e6
KY
12174static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12175 .num_items = 2,
12176 .items = {
12177 { "i-Mic", 0x5 },
12178 { "e-Mic", 0x0 },
12179 },
12180};
12181
12182static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12183 .num_items = 2,
12184 .items = {
12185 { "i-Mic", 0x1 },
12186 { "e-Mic", 0x0 },
12187 },
f6a92248
KY
12188};
12189
12190#define alc269_modes alc260_modes
12191#define alc269_capture_source alc880_lg_lw_capture_source
12192
12193static struct snd_kcontrol_new alc269_base_mixer[] = {
12194 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12195 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12197 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2005af24
TI
12200 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
12201 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
f6a92248
KY
12202 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12203 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12204 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12205 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12207 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12208 { } /* end */
12209};
12210
60db6b53
KY
12211static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12212 /* output mixer control */
12213 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12214 {
12215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12216 .name = "Master Playback Switch",
12217 .info = snd_hda_mixer_amp_switch_info,
12218 .get = snd_hda_mixer_amp_switch_get,
12219 .put = alc268_acer_master_sw_put,
12220 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12221 },
12222 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12223 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12224 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12225 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12226 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12227 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12228 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
12229 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
12230 { }
12231};
12232
64154835
TV
12233static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12234 /* output mixer control */
12235 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12236 {
12237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12238 .name = "Master Playback Switch",
12239 .info = snd_hda_mixer_amp_switch_info,
12240 .get = snd_hda_mixer_amp_switch_get,
12241 .put = alc268_acer_master_sw_put,
12242 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12243 },
12244 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12246 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12247 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12248 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12249 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12250 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12251 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12252 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12253 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
12254 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
12255 { }
12256};
12257
f53281e6
KY
12258/* bind volumes of both NID 0x0c and 0x0d */
12259static struct hda_bind_ctls alc269_epc_bind_vol = {
12260 .ops = &snd_hda_bind_vol,
12261 .values = {
12262 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12263 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12264 0
12265 },
12266};
12267
12268static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12269 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12270 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12271 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12272 { } /* end */
12273};
12274
f53281e6
KY
12275/* capture mixer elements */
12276static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12277 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12278 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
12279 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12280 { } /* end */
12281};
12282
12283/* FSC amilo */
12284static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12287 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
f53281e6
KY
12288 { } /* end */
12289};
12290
2005af24
TI
12291/* beep control */
12292static struct snd_kcontrol_new alc269_beep_mixer[] = {
12293 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
12294 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
12295 { } /* end */
12296};
12297
60db6b53
KY
12298static struct hda_verb alc269_quanta_fl1_verbs[] = {
12299 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12300 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12302 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12304 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12305 { }
12306};
f6a92248 12307
64154835
TV
12308static struct hda_verb alc269_lifebook_verbs[] = {
12309 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12310 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12311 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12312 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12313 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12314 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12315 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12316 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12317 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12318 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12319 { }
12320};
12321
60db6b53
KY
12322/* toggle speaker-output according to the hp-jack state */
12323static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12324{
12325 unsigned int present;
12326 unsigned char bits;
f6a92248 12327
60db6b53
KY
12328 present = snd_hda_codec_read(codec, 0x15, 0,
12329 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12330 bits = present ? AMP_IN_MUTE(0) : 0;
12331 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12332 AMP_IN_MUTE(0), bits);
12333 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12334 AMP_IN_MUTE(0), bits);
f6a92248 12335
60db6b53
KY
12336 snd_hda_codec_write(codec, 0x20, 0,
12337 AC_VERB_SET_COEF_INDEX, 0x0c);
12338 snd_hda_codec_write(codec, 0x20, 0,
12339 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 12340
60db6b53
KY
12341 snd_hda_codec_write(codec, 0x20, 0,
12342 AC_VERB_SET_COEF_INDEX, 0x0c);
12343 snd_hda_codec_write(codec, 0x20, 0,
12344 AC_VERB_SET_PROC_COEF, 0x480);
12345}
f6a92248 12346
64154835
TV
12347/* toggle speaker-output according to the hp-jacks state */
12348static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12349{
12350 unsigned int present;
12351 unsigned char bits;
12352
12353 /* Check laptop headphone socket */
12354 present = snd_hda_codec_read(codec, 0x15, 0,
12355 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12356
12357 /* Check port replicator headphone socket */
12358 present |= snd_hda_codec_read(codec, 0x1a, 0,
12359 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12360
12361 bits = present ? AMP_IN_MUTE(0) : 0;
12362 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12363 AMP_IN_MUTE(0), bits);
12364 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12365 AMP_IN_MUTE(0), bits);
12366
12367 snd_hda_codec_write(codec, 0x20, 0,
12368 AC_VERB_SET_COEF_INDEX, 0x0c);
12369 snd_hda_codec_write(codec, 0x20, 0,
12370 AC_VERB_SET_PROC_COEF, 0x680);
12371
12372 snd_hda_codec_write(codec, 0x20, 0,
12373 AC_VERB_SET_COEF_INDEX, 0x0c);
12374 snd_hda_codec_write(codec, 0x20, 0,
12375 AC_VERB_SET_PROC_COEF, 0x480);
12376}
12377
60db6b53
KY
12378static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12379{
12380 unsigned int present;
f6a92248 12381
60db6b53
KY
12382 present = snd_hda_codec_read(codec, 0x18, 0,
12383 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12384 snd_hda_codec_write(codec, 0x23, 0,
12385 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12386}
f6a92248 12387
64154835
TV
12388static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12389{
12390 unsigned int present_laptop;
12391 unsigned int present_dock;
12392
12393 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12394 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12395
12396 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12397 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12398
12399 /* Laptop mic port overrides dock mic port, design decision */
12400 if (present_dock)
12401 snd_hda_codec_write(codec, 0x23, 0,
12402 AC_VERB_SET_CONNECT_SEL, 0x3);
12403 if (present_laptop)
12404 snd_hda_codec_write(codec, 0x23, 0,
12405 AC_VERB_SET_CONNECT_SEL, 0x0);
12406 if (!present_dock && !present_laptop)
12407 snd_hda_codec_write(codec, 0x23, 0,
12408 AC_VERB_SET_CONNECT_SEL, 0x1);
12409}
12410
60db6b53
KY
12411static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12412 unsigned int res)
12413{
12414 if ((res >> 26) == ALC880_HP_EVENT)
12415 alc269_quanta_fl1_speaker_automute(codec);
12416 if ((res >> 26) == ALC880_MIC_EVENT)
12417 alc269_quanta_fl1_mic_automute(codec);
12418}
f6a92248 12419
64154835
TV
12420static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12421 unsigned int res)
12422{
12423 if ((res >> 26) == ALC880_HP_EVENT)
12424 alc269_lifebook_speaker_automute(codec);
12425 if ((res >> 26) == ALC880_MIC_EVENT)
12426 alc269_lifebook_mic_autoswitch(codec);
12427}
12428
60db6b53
KY
12429static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12430{
12431 alc269_quanta_fl1_speaker_automute(codec);
12432 alc269_quanta_fl1_mic_automute(codec);
12433}
f6a92248 12434
64154835
TV
12435static void alc269_lifebook_init_hook(struct hda_codec *codec)
12436{
12437 alc269_lifebook_speaker_automute(codec);
12438 alc269_lifebook_mic_autoswitch(codec);
12439}
12440
f53281e6
KY
12441static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12442 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12443 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12444 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12446 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12447 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12448 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12449 {}
12450};
12451
12452static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12453 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12454 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12455 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12456 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12457 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12458 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12459 {}
12460};
12461
12462/* toggle speaker-output according to the hp-jack state */
12463static void alc269_speaker_automute(struct hda_codec *codec)
12464{
12465 unsigned int present;
60db6b53 12466 unsigned char bits;
f53281e6
KY
12467
12468 present = snd_hda_codec_read(codec, 0x15, 0,
60db6b53 12469 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6
KY
12470 bits = present ? AMP_IN_MUTE(0) : 0;
12471 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 12472 AMP_IN_MUTE(0), bits);
f53281e6 12473 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 12474 AMP_IN_MUTE(0), bits);
f53281e6
KY
12475}
12476
12477static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12478{
12479 unsigned int present;
12480
60db6b53
KY
12481 present = snd_hda_codec_read(codec, 0x18, 0,
12482 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12483 snd_hda_codec_write(codec, 0x23, 0,
12484 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
f53281e6
KY
12485}
12486
12487static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12488{
12489 unsigned int present;
12490
60db6b53
KY
12491 present = snd_hda_codec_read(codec, 0x18, 0,
12492 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6 12493 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12494 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
f53281e6 12495 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12496 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
f53281e6
KY
12497}
12498
12499/* unsolicited event for HP jack sensing */
12500static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
60db6b53 12501 unsigned int res)
f53281e6
KY
12502{
12503 if ((res >> 26) == ALC880_HP_EVENT)
12504 alc269_speaker_automute(codec);
12505
12506 if ((res >> 26) == ALC880_MIC_EVENT)
12507 alc269_eeepc_dmic_automute(codec);
12508}
12509
12510static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12511{
12512 alc269_speaker_automute(codec);
12513 alc269_eeepc_dmic_automute(codec);
12514}
12515
12516/* unsolicited event for HP jack sensing */
12517static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
ea1fb29a 12518 unsigned int res)
f53281e6
KY
12519{
12520 if ((res >> 26) == ALC880_HP_EVENT)
12521 alc269_speaker_automute(codec);
12522
12523 if ((res >> 26) == ALC880_MIC_EVENT)
12524 alc269_eeepc_amic_automute(codec);
12525}
12526
12527static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12528{
12529 alc269_speaker_automute(codec);
12530 alc269_eeepc_amic_automute(codec);
12531}
12532
60db6b53
KY
12533/*
12534 * generic initialization of ADC, input mixers and output mixers
12535 */
12536static struct hda_verb alc269_init_verbs[] = {
12537 /*
12538 * Unmute ADC0 and set the default input to mic-in
12539 */
12540 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12541
12542 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12543 * analog-loopback mixer widget
12544 * Note: PASD motherboards uses the Line In 2 as the input for
12545 * front panel mic (mic 2)
12546 */
12547 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12548 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12549 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12550 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12553
12554 /*
12555 * Set up output mixers (0x0c - 0x0e)
12556 */
12557 /* set vol=0 to output mixers */
12558 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12559 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12560
12561 /* set up input amps for analog loopback */
12562 /* Amp Indices: DAC = 0, mixer = 1 */
12563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12565 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12566 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12567 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12568 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12569
12570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12572 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12573 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12575 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12576 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12577
12578 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12579 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12580 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12581 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12582 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12583 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12584 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12585
12586 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12587 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12588
12589 /* FIXME: use matrix-type input source selection */
12590 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12591 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12593 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12594 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12595 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12596
12597 /* set EAPD */
12598 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12599 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12600 { }
12601};
12602
f6a92248
KY
12603/* add playback controls from the parsed DAC table */
12604static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12605 const struct auto_pin_cfg *cfg)
12606{
12607 hda_nid_t nid;
12608 int err;
12609
12610 spec->multiout.num_dacs = 1; /* only use one dac */
12611 spec->multiout.dac_nids = spec->private_dac_nids;
12612 spec->multiout.dac_nids[0] = 2;
12613
12614 nid = cfg->line_out_pins[0];
12615 if (nid) {
12616 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12617 "Front Playback Volume",
12618 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12619 if (err < 0)
12620 return err;
12621 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12622 "Front Playback Switch",
12623 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12624 if (err < 0)
12625 return err;
12626 }
12627
12628 nid = cfg->speaker_pins[0];
12629 if (nid) {
12630 if (!cfg->line_out_pins[0]) {
12631 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12632 "Speaker Playback Volume",
12633 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12634 HDA_OUTPUT));
12635 if (err < 0)
12636 return err;
12637 }
12638 if (nid == 0x16) {
12639 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12640 "Speaker Playback Switch",
12641 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12642 HDA_OUTPUT));
12643 if (err < 0)
12644 return err;
12645 } else {
12646 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12647 "Speaker Playback Switch",
12648 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12649 HDA_OUTPUT));
12650 if (err < 0)
12651 return err;
12652 }
12653 }
12654 nid = cfg->hp_pins[0];
12655 if (nid) {
12656 /* spec->multiout.hp_nid = 2; */
12657 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12658 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12659 "Headphone Playback Volume",
12660 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12661 HDA_OUTPUT));
12662 if (err < 0)
12663 return err;
12664 }
12665 if (nid == 0x16) {
12666 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12667 "Headphone Playback Switch",
12668 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12669 HDA_OUTPUT));
12670 if (err < 0)
12671 return err;
12672 } else {
12673 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12674 "Headphone Playback Switch",
12675 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12676 HDA_OUTPUT));
12677 if (err < 0)
12678 return err;
12679 }
12680 }
12681 return 0;
12682}
12683
ee956e09
TI
12684static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12685 const struct auto_pin_cfg *cfg)
12686{
12687 int err;
12688
12689 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12690 if (err < 0)
12691 return err;
12692 /* digital-mic input pin is excluded in alc880_auto_create..()
12693 * because it's under 0x18
12694 */
12695 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12696 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
61b9b9b1 12697 struct hda_input_mux *imux = &spec->private_imux[0];
ee956e09
TI
12698 imux->items[imux->num_items].label = "Int Mic";
12699 imux->items[imux->num_items].index = 0x05;
12700 imux->num_items++;
12701 }
12702 return 0;
12703}
f6a92248
KY
12704
12705#ifdef CONFIG_SND_HDA_POWER_SAVE
12706#define alc269_loopbacks alc880_loopbacks
12707#endif
12708
12709/* pcm configuration: identiacal with ALC880 */
12710#define alc269_pcm_analog_playback alc880_pcm_analog_playback
12711#define alc269_pcm_analog_capture alc880_pcm_analog_capture
12712#define alc269_pcm_digital_playback alc880_pcm_digital_playback
12713#define alc269_pcm_digital_capture alc880_pcm_digital_capture
12714
12715/*
12716 * BIOS auto configuration
12717 */
12718static int alc269_parse_auto_config(struct hda_codec *codec)
12719{
12720 struct alc_spec *spec = codec->spec;
2005af24 12721 int i, err;
f6a92248
KY
12722 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12723
12724 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12725 alc269_ignore);
12726 if (err < 0)
12727 return err;
12728
12729 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12730 if (err < 0)
12731 return err;
12732 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12733 if (err < 0)
12734 return err;
12735
12736 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12737
12738 if (spec->autocfg.dig_out_pin)
12739 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12740
603c4019 12741 if (spec->kctls.list)
d88897ea 12742 add_mixer(spec, spec->kctls.list);
f6a92248 12743
2005af24
TI
12744 /* create a beep mixer control if the pin 0x1d isn't assigned */
12745 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12746 if (spec->autocfg.input_pins[i] == 0x1d)
12747 break;
12748 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
d88897ea 12749 add_mixer(spec, alc269_beep_mixer);
2005af24 12750
d88897ea 12751 add_verb(spec, alc269_init_verbs);
f6a92248 12752 spec->num_mux_defs = 1;
61b9b9b1 12753 spec->input_mux = &spec->private_imux[0];
e01bf509
TI
12754 /* set default input source */
12755 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12756 0, AC_VERB_SET_CONNECT_SEL,
12757 spec->input_mux->items[0].index);
f6a92248
KY
12758
12759 err = alc_auto_add_mic_boost(codec);
12760 if (err < 0)
12761 return err;
12762
f9e336f6
TI
12763 if (!spec->cap_mixer)
12764 set_capture_mixer(spec);
f53281e6 12765
e044c39a 12766 store_pin_configs(codec);
f6a92248
KY
12767 return 1;
12768}
12769
12770#define alc269_auto_init_multi_out alc882_auto_init_multi_out
12771#define alc269_auto_init_hp_out alc882_auto_init_hp_out
12772#define alc269_auto_init_analog_input alc882_auto_init_analog_input
12773
12774
12775/* init callback for auto-configuration model -- overriding the default init */
12776static void alc269_auto_init(struct hda_codec *codec)
12777{
f6c7e546 12778 struct alc_spec *spec = codec->spec;
f6a92248
KY
12779 alc269_auto_init_multi_out(codec);
12780 alc269_auto_init_hp_out(codec);
12781 alc269_auto_init_analog_input(codec);
f6c7e546 12782 if (spec->unsol_event)
7fb0d78f 12783 alc_inithook(codec);
f6a92248
KY
12784}
12785
12786/*
12787 * configuration and preset
12788 */
12789static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 12790 [ALC269_BASIC] = "basic",
2922c9af
TI
12791 [ALC269_QUANTA_FL1] = "quanta",
12792 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
26f5df26 12793 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
64154835
TV
12794 [ALC269_FUJITSU] = "fujitsu",
12795 [ALC269_LIFEBOOK] = "lifebook"
f6a92248
KY
12796};
12797
12798static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 12799 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6
KY
12800 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12801 ALC269_ASUS_EEEPC_P703),
12802 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12803 ALC269_ASUS_EEEPC_P901),
60db6b53
KY
12804 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12805 ALC269_ASUS_EEEPC_P901),
26f5df26 12806 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
64154835 12807 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
f6a92248
KY
12808 {}
12809};
12810
12811static struct alc_config_preset alc269_presets[] = {
12812 [ALC269_BASIC] = {
f9e336f6 12813 .mixers = { alc269_base_mixer },
f6a92248
KY
12814 .init_verbs = { alc269_init_verbs },
12815 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12816 .dac_nids = alc269_dac_nids,
12817 .hp_nid = 0x03,
12818 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12819 .channel_mode = alc269_modes,
12820 .input_mux = &alc269_capture_source,
12821 },
60db6b53
KY
12822 [ALC269_QUANTA_FL1] = {
12823 .mixers = { alc269_quanta_fl1_mixer },
12824 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12825 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12826 .dac_nids = alc269_dac_nids,
12827 .hp_nid = 0x03,
12828 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12829 .channel_mode = alc269_modes,
12830 .input_mux = &alc269_capture_source,
12831 .unsol_event = alc269_quanta_fl1_unsol_event,
12832 .init_hook = alc269_quanta_fl1_init_hook,
12833 },
f53281e6 12834 [ALC269_ASUS_EEEPC_P703] = {
f9e336f6
TI
12835 .mixers = { alc269_eeepc_mixer },
12836 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
12837 .init_verbs = { alc269_init_verbs,
12838 alc269_eeepc_amic_init_verbs },
12839 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12840 .dac_nids = alc269_dac_nids,
12841 .hp_nid = 0x03,
12842 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12843 .channel_mode = alc269_modes,
12844 .input_mux = &alc269_eeepc_amic_capture_source,
12845 .unsol_event = alc269_eeepc_amic_unsol_event,
12846 .init_hook = alc269_eeepc_amic_inithook,
12847 },
12848 [ALC269_ASUS_EEEPC_P901] = {
f9e336f6
TI
12849 .mixers = { alc269_eeepc_mixer },
12850 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
12851 .init_verbs = { alc269_init_verbs,
12852 alc269_eeepc_dmic_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_eeepc_dmic_capture_source,
12859 .unsol_event = alc269_eeepc_dmic_unsol_event,
12860 .init_hook = alc269_eeepc_dmic_inithook,
12861 },
26f5df26
TI
12862 [ALC269_FUJITSU] = {
12863 .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12864 .cap_mixer = alc269_epc_capture_mixer,
12865 .init_verbs = { alc269_init_verbs,
12866 alc269_eeepc_dmic_init_verbs },
12867 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12868 .dac_nids = alc269_dac_nids,
12869 .hp_nid = 0x03,
12870 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12871 .channel_mode = alc269_modes,
12872 .input_mux = &alc269_eeepc_dmic_capture_source,
12873 .unsol_event = alc269_eeepc_dmic_unsol_event,
12874 .init_hook = alc269_eeepc_dmic_inithook,
12875 },
64154835
TV
12876 [ALC269_LIFEBOOK] = {
12877 .mixers = { alc269_lifebook_mixer },
12878 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12879 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12880 .dac_nids = alc269_dac_nids,
12881 .hp_nid = 0x03,
12882 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12883 .channel_mode = alc269_modes,
12884 .input_mux = &alc269_capture_source,
12885 .unsol_event = alc269_lifebook_unsol_event,
12886 .init_hook = alc269_lifebook_init_hook,
12887 },
f6a92248
KY
12888};
12889
12890static int patch_alc269(struct hda_codec *codec)
12891{
12892 struct alc_spec *spec;
12893 int board_config;
12894 int err;
12895
12896 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12897 if (spec == NULL)
12898 return -ENOMEM;
12899
12900 codec->spec = spec;
12901
2c3bf9ab
TI
12902 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12903
f6a92248
KY
12904 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12905 alc269_models,
12906 alc269_cfg_tbl);
12907
12908 if (board_config < 0) {
12909 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12910 "trying auto-probe from BIOS...\n");
12911 board_config = ALC269_AUTO;
12912 }
12913
12914 if (board_config == ALC269_AUTO) {
12915 /* automatic parse from the BIOS config */
12916 err = alc269_parse_auto_config(codec);
12917 if (err < 0) {
12918 alc_free(codec);
12919 return err;
12920 } else if (!err) {
12921 printk(KERN_INFO
12922 "hda_codec: Cannot set up configuration "
12923 "from BIOS. Using base mode...\n");
12924 board_config = ALC269_BASIC;
12925 }
12926 }
12927
680cd536
KK
12928 err = snd_hda_attach_beep_device(codec, 0x1);
12929 if (err < 0) {
12930 alc_free(codec);
12931 return err;
12932 }
12933
f6a92248
KY
12934 if (board_config != ALC269_AUTO)
12935 setup_preset(spec, &alc269_presets[board_config]);
12936
12937 spec->stream_name_analog = "ALC269 Analog";
12938 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12939 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12940
12941 spec->stream_name_digital = "ALC269 Digital";
12942 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12943 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12944
12945 spec->adc_nids = alc269_adc_nids;
12946 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
e01bf509 12947 spec->capsrc_nids = alc269_capsrc_nids;
f9e336f6
TI
12948 if (!spec->cap_mixer)
12949 set_capture_mixer(spec);
f6a92248
KY
12950
12951 codec->patch_ops = alc_patch_ops;
12952 if (board_config == ALC269_AUTO)
12953 spec->init_hook = alc269_auto_init;
12954#ifdef CONFIG_SND_HDA_POWER_SAVE
12955 if (!spec->loopback.amplist)
12956 spec->loopback.amplist = alc269_loopbacks;
12957#endif
daead538 12958 codec->proc_widget_hook = print_realtek_coef;
f6a92248
KY
12959
12960 return 0;
12961}
12962
df694daa
KY
12963/*
12964 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12965 */
12966
12967/*
12968 * set the path ways for 2 channel output
12969 * need to set the codec line out and mic 1 pin widgets to inputs
12970 */
12971static struct hda_verb alc861_threestack_ch2_init[] = {
12972 /* set pin widget 1Ah (line in) for input */
12973 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
12974 /* set pin widget 18h (mic1/2) for input, for mic also enable
12975 * the vref
12976 */
df694daa
KY
12977 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12978
9c7f852e
TI
12979 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12980#if 0
12981 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12982 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12983#endif
df694daa
KY
12984 { } /* end */
12985};
12986/*
12987 * 6ch mode
12988 * need to set the codec line out and mic 1 pin widgets to outputs
12989 */
12990static struct hda_verb alc861_threestack_ch6_init[] = {
12991 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12992 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12993 /* set pin widget 18h (mic1) for output (CLFE)*/
12994 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12995
12996 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 12997 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 12998
9c7f852e
TI
12999 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13000#if 0
13001 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13002 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13003#endif
df694daa
KY
13004 { } /* end */
13005};
13006
13007static struct hda_channel_mode alc861_threestack_modes[2] = {
13008 { 2, alc861_threestack_ch2_init },
13009 { 6, alc861_threestack_ch6_init },
13010};
22309c3e
TI
13011/* Set mic1 as input and unmute the mixer */
13012static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13013 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13014 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13015 { } /* end */
13016};
13017/* Set mic1 as output and mute mixer */
13018static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13019 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13020 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13021 { } /* end */
13022};
13023
13024static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13025 { 2, alc861_uniwill_m31_ch2_init },
13026 { 4, alc861_uniwill_m31_ch4_init },
13027};
df694daa 13028
7cdbff94
MD
13029/* Set mic1 and line-in as input and unmute the mixer */
13030static struct hda_verb alc861_asus_ch2_init[] = {
13031 /* set pin widget 1Ah (line in) for input */
13032 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13033 /* set pin widget 18h (mic1/2) for input, for mic also enable
13034 * the vref
13035 */
7cdbff94
MD
13036 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13037
13038 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13039#if 0
13040 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13041 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13042#endif
13043 { } /* end */
13044};
13045/* Set mic1 nad line-in as output and mute mixer */
13046static struct hda_verb alc861_asus_ch6_init[] = {
13047 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13048 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13049 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13050 /* set pin widget 18h (mic1) for output (CLFE)*/
13051 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13052 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13053 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13054 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13055
13056 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13057#if 0
13058 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13059 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13060#endif
13061 { } /* end */
13062};
13063
13064static struct hda_channel_mode alc861_asus_modes[2] = {
13065 { 2, alc861_asus_ch2_init },
13066 { 6, alc861_asus_ch6_init },
13067};
13068
df694daa
KY
13069/* patch-ALC861 */
13070
13071static struct snd_kcontrol_new alc861_base_mixer[] = {
13072 /* output mixer control */
13073 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13074 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13075 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13076 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13077 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13078
13079 /*Input mixer control */
13080 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13081 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13082 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13083 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13084 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13085 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13087 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13088 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13089 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13090
df694daa
KY
13091 { } /* end */
13092};
13093
13094static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13095 /* output mixer control */
13096 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13097 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13098 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13099 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13100 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13101
13102 /* Input mixer control */
13103 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13104 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13105 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13106 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13107 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13108 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13109 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13110 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13111 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13112 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13113
df694daa
KY
13114 {
13115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13116 .name = "Channel Mode",
13117 .info = alc_ch_mode_info,
13118 .get = alc_ch_mode_get,
13119 .put = alc_ch_mode_put,
13120 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13121 },
13122 { } /* end */
a53d1aec
TD
13123};
13124
d1d985f0 13125static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
13126 /* output mixer control */
13127 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13129 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 13130
a53d1aec 13131 { } /* end */
f12ab1e0 13132};
a53d1aec 13133
22309c3e
TI
13134static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13135 /* output mixer control */
13136 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13137 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13138 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13139 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13140 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13141
13142 /* Input mixer control */
13143 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13144 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13145 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13146 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13147 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13148 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13150 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13151 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13152 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13153
22309c3e
TI
13154 {
13155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13156 .name = "Channel Mode",
13157 .info = alc_ch_mode_info,
13158 .get = alc_ch_mode_get,
13159 .put = alc_ch_mode_put,
13160 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13161 },
13162 { } /* end */
f12ab1e0 13163};
7cdbff94
MD
13164
13165static struct snd_kcontrol_new alc861_asus_mixer[] = {
13166 /* output mixer control */
13167 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13168 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13169 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13170 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13171 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13172
13173 /* Input mixer control */
13174 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13175 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13176 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13177 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13178 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13179 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13180 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13181 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13182 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
13183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13184
7cdbff94
MD
13185 {
13186 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13187 .name = "Channel Mode",
13188 .info = alc_ch_mode_info,
13189 .get = alc_ch_mode_get,
13190 .put = alc_ch_mode_put,
13191 .private_value = ARRAY_SIZE(alc861_asus_modes),
13192 },
13193 { }
56bb0cab
TI
13194};
13195
13196/* additional mixer */
d1d985f0 13197static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
13198 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13199 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13200 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
13201 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
13202 { }
13203};
7cdbff94 13204
df694daa
KY
13205/*
13206 * generic initialization of ADC, input mixers and output mixers
13207 */
13208static struct hda_verb alc861_base_init_verbs[] = {
13209 /*
13210 * Unmute ADC0 and set the default input to mic-in
13211 */
13212 /* port-A for surround (rear panel) */
13213 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13214 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13215 /* port-B for mic-in (rear panel) with vref */
13216 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13217 /* port-C for line-in (rear panel) */
13218 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13219 /* port-D for Front */
13220 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13221 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13222 /* port-E for HP out (front panel) */
13223 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13224 /* route front PCM to HP */
9dece1d7 13225 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13226 /* port-F for mic-in (front panel) with vref */
13227 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13228 /* port-G for CLFE (rear panel) */
13229 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13230 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13231 /* port-H for side (rear panel) */
13232 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13233 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13234 /* CD-in */
13235 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13236 /* route front mic to ADC1*/
13237 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13238 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13239
df694daa
KY
13240 /* Unmute DAC0~3 & spdif out*/
13241 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13242 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13243 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13244 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13245 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13246
df694daa
KY
13247 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13248 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13249 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13250 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13251 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13252
df694daa
KY
13253 /* Unmute Stereo Mixer 15 */
13254 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13255 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13256 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13258
13259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13260 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13261 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13262 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13263 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13264 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13265 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13266 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13267 /* hp used DAC 3 (Front) */
13268 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13269 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13270
13271 { }
13272};
13273
13274static struct hda_verb alc861_threestack_init_verbs[] = {
13275 /*
13276 * Unmute ADC0 and set the default input to mic-in
13277 */
13278 /* port-A for surround (rear panel) */
13279 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13280 /* port-B for mic-in (rear panel) with vref */
13281 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13282 /* port-C for line-in (rear panel) */
13283 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13284 /* port-D for Front */
13285 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13286 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13287 /* port-E for HP out (front panel) */
13288 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13289 /* route front PCM to HP */
9dece1d7 13290 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13291 /* port-F for mic-in (front panel) with vref */
13292 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13293 /* port-G for CLFE (rear panel) */
13294 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13295 /* port-H for side (rear panel) */
13296 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13297 /* CD-in */
13298 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13299 /* route front mic to ADC1*/
13300 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13301 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13302 /* Unmute DAC0~3 & spdif out*/
13303 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13304 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13305 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13306 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13308
df694daa
KY
13309 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13310 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13311 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13312 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13313 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13314
df694daa
KY
13315 /* Unmute Stereo Mixer 15 */
13316 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13317 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13318 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13319 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13320
13321 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13322 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13323 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13324 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13325 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13326 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13327 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13328 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13329 /* hp used DAC 3 (Front) */
13330 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13331 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13332 { }
13333};
22309c3e
TI
13334
13335static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13336 /*
13337 * Unmute ADC0 and set the default input to mic-in
13338 */
13339 /* port-A for surround (rear panel) */
13340 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13341 /* port-B for mic-in (rear panel) with vref */
13342 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13343 /* port-C for line-in (rear panel) */
13344 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13345 /* port-D for Front */
13346 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13347 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13348 /* port-E for HP out (front panel) */
f12ab1e0
TI
13349 /* this has to be set to VREF80 */
13350 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 13351 /* route front PCM to HP */
9dece1d7 13352 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
13353 /* port-F for mic-in (front panel) with vref */
13354 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13355 /* port-G for CLFE (rear panel) */
13356 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13357 /* port-H for side (rear panel) */
13358 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13359 /* CD-in */
13360 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13361 /* route front mic to ADC1*/
13362 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13363 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13364 /* Unmute DAC0~3 & spdif out*/
13365 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13366 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13367 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13368 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13369 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13370
22309c3e
TI
13371 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13372 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13373 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13374 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13375 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13376
22309c3e
TI
13377 /* Unmute Stereo Mixer 15 */
13378 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13379 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13380 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
13382
13383 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13384 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13385 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13386 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13388 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13389 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13390 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13391 /* hp used DAC 3 (Front) */
13392 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
13393 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13394 { }
13395};
13396
7cdbff94
MD
13397static struct hda_verb alc861_asus_init_verbs[] = {
13398 /*
13399 * Unmute ADC0 and set the default input to mic-in
13400 */
f12ab1e0
TI
13401 /* port-A for surround (rear panel)
13402 * according to codec#0 this is the HP jack
13403 */
7cdbff94
MD
13404 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13405 /* route front PCM to HP */
13406 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13407 /* port-B for mic-in (rear panel) with vref */
13408 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13409 /* port-C for line-in (rear panel) */
13410 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13411 /* port-D for Front */
13412 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13413 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13414 /* port-E for HP out (front panel) */
f12ab1e0
TI
13415 /* this has to be set to VREF80 */
13416 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 13417 /* route front PCM to HP */
9dece1d7 13418 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
13419 /* port-F for mic-in (front panel) with vref */
13420 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13421 /* port-G for CLFE (rear panel) */
13422 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13423 /* port-H for side (rear panel) */
13424 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13425 /* CD-in */
13426 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13427 /* route front mic to ADC1*/
13428 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13429 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13430 /* Unmute DAC0~3 & spdif out*/
13431 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13432 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13433 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13434 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13435 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13436 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13437 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13438 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13439 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13440 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13441
7cdbff94
MD
13442 /* Unmute Stereo Mixer 15 */
13443 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
13447
13448 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13449 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13450 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13451 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13454 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13456 /* hp used DAC 3 (Front) */
13457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
13458 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13459 { }
13460};
13461
56bb0cab
TI
13462/* additional init verbs for ASUS laptops */
13463static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13464 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13465 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13466 { }
13467};
7cdbff94 13468
df694daa
KY
13469/*
13470 * generic initialization of ADC, input mixers and output mixers
13471 */
13472static struct hda_verb alc861_auto_init_verbs[] = {
13473 /*
13474 * Unmute ADC0 and set the default input to mic-in
13475 */
f12ab1e0 13476 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 13477 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13478
df694daa
KY
13479 /* Unmute DAC0~3 & spdif out*/
13480 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13481 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13482 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13483 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13485
df694daa
KY
13486 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13487 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13488 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13489 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13490 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13491
df694daa
KY
13492 /* Unmute Stereo Mixer 15 */
13493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13494 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13497
13498 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13499 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13500 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13501 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13502 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13503 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13504 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13506
13507 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13508 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13510 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13511 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13513 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13514 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 13515
f12ab1e0 13516 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
13517
13518 { }
13519};
13520
a53d1aec
TD
13521static struct hda_verb alc861_toshiba_init_verbs[] = {
13522 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 13523
a53d1aec
TD
13524 { }
13525};
13526
13527/* toggle speaker-output according to the hp-jack state */
13528static void alc861_toshiba_automute(struct hda_codec *codec)
13529{
13530 unsigned int present;
13531
13532 present = snd_hda_codec_read(codec, 0x0f, 0,
13533 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13534 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13535 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13536 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13537 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
13538}
13539
13540static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13541 unsigned int res)
13542{
a53d1aec
TD
13543 if ((res >> 26) == ALC880_HP_EVENT)
13544 alc861_toshiba_automute(codec);
13545}
13546
df694daa
KY
13547/* pcm configuration: identiacal with ALC880 */
13548#define alc861_pcm_analog_playback alc880_pcm_analog_playback
13549#define alc861_pcm_analog_capture alc880_pcm_analog_capture
13550#define alc861_pcm_digital_playback alc880_pcm_digital_playback
13551#define alc861_pcm_digital_capture alc880_pcm_digital_capture
13552
13553
13554#define ALC861_DIGOUT_NID 0x07
13555
13556static struct hda_channel_mode alc861_8ch_modes[1] = {
13557 { 8, NULL }
13558};
13559
13560static hda_nid_t alc861_dac_nids[4] = {
13561 /* front, surround, clfe, side */
13562 0x03, 0x06, 0x05, 0x04
13563};
13564
9c7f852e
TI
13565static hda_nid_t alc660_dac_nids[3] = {
13566 /* front, clfe, surround */
13567 0x03, 0x05, 0x06
13568};
13569
df694daa
KY
13570static hda_nid_t alc861_adc_nids[1] = {
13571 /* ADC0-2 */
13572 0x08,
13573};
13574
13575static struct hda_input_mux alc861_capture_source = {
13576 .num_items = 5,
13577 .items = {
13578 { "Mic", 0x0 },
13579 { "Front Mic", 0x3 },
13580 { "Line", 0x1 },
13581 { "CD", 0x4 },
13582 { "Mixer", 0x5 },
13583 },
13584};
13585
13586/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
13587static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13588 const struct auto_pin_cfg *cfg)
df694daa
KY
13589{
13590 int i;
13591 hda_nid_t nid;
13592
13593 spec->multiout.dac_nids = spec->private_dac_nids;
13594 for (i = 0; i < cfg->line_outs; i++) {
13595 nid = cfg->line_out_pins[i];
13596 if (nid) {
13597 if (i >= ARRAY_SIZE(alc861_dac_nids))
13598 continue;
13599 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13600 }
13601 }
13602 spec->multiout.num_dacs = cfg->line_outs;
13603 return 0;
13604}
13605
13606/* add playback controls from the parsed DAC table */
13607static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13608 const struct auto_pin_cfg *cfg)
13609{
13610 char name[32];
f12ab1e0
TI
13611 static const char *chname[4] = {
13612 "Front", "Surround", NULL /*CLFE*/, "Side"
13613 };
df694daa
KY
13614 hda_nid_t nid;
13615 int i, idx, err;
13616
13617 for (i = 0; i < cfg->line_outs; i++) {
13618 nid = spec->multiout.dac_nids[i];
f12ab1e0 13619 if (!nid)
df694daa
KY
13620 continue;
13621 if (nid == 0x05) {
13622 /* Center/LFE */
f12ab1e0
TI
13623 err = add_control(spec, ALC_CTL_BIND_MUTE,
13624 "Center Playback Switch",
13625 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13626 HDA_OUTPUT));
13627 if (err < 0)
df694daa 13628 return err;
f12ab1e0
TI
13629 err = add_control(spec, ALC_CTL_BIND_MUTE,
13630 "LFE Playback Switch",
13631 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13632 HDA_OUTPUT));
13633 if (err < 0)
df694daa
KY
13634 return err;
13635 } else {
f12ab1e0
TI
13636 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13637 idx++)
df694daa
KY
13638 if (nid == alc861_dac_nids[idx])
13639 break;
13640 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
13641 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13642 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13643 HDA_OUTPUT));
13644 if (err < 0)
df694daa
KY
13645 return err;
13646 }
13647 }
13648 return 0;
13649}
13650
13651static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13652{
13653 int err;
13654 hda_nid_t nid;
13655
f12ab1e0 13656 if (!pin)
df694daa
KY
13657 return 0;
13658
13659 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13660 nid = 0x03;
f12ab1e0
TI
13661 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13662 "Headphone Playback Switch",
13663 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13664 if (err < 0)
df694daa
KY
13665 return err;
13666 spec->multiout.hp_nid = nid;
13667 }
13668 return 0;
13669}
13670
13671/* create playback/capture controls for input pins */
f12ab1e0
TI
13672static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13673 const struct auto_pin_cfg *cfg)
df694daa 13674{
61b9b9b1 13675 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
13676 int i, err, idx, idx1;
13677
13678 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 13679 switch (cfg->input_pins[i]) {
df694daa
KY
13680 case 0x0c:
13681 idx1 = 1;
f12ab1e0 13682 idx = 2; /* Line In */
df694daa
KY
13683 break;
13684 case 0x0f:
13685 idx1 = 2;
f12ab1e0 13686 idx = 2; /* Line In */
df694daa
KY
13687 break;
13688 case 0x0d:
13689 idx1 = 0;
f12ab1e0 13690 idx = 1; /* Mic In */
df694daa 13691 break;
f12ab1e0 13692 case 0x10:
df694daa 13693 idx1 = 3;
f12ab1e0 13694 idx = 1; /* Mic In */
df694daa
KY
13695 break;
13696 case 0x11:
13697 idx1 = 4;
f12ab1e0 13698 idx = 0; /* CD */
df694daa
KY
13699 break;
13700 default:
13701 continue;
13702 }
13703
4a471b7d
TI
13704 err = new_analog_input(spec, cfg->input_pins[i],
13705 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
13706 if (err < 0)
13707 return err;
13708
4a471b7d 13709 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 13710 imux->items[imux->num_items].index = idx1;
f12ab1e0 13711 imux->num_items++;
df694daa
KY
13712 }
13713 return 0;
13714}
13715
f12ab1e0
TI
13716static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13717 hda_nid_t nid,
df694daa
KY
13718 int pin_type, int dac_idx)
13719{
564c5bea
JL
13720 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13721 pin_type);
13722 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13723 AMP_OUT_UNMUTE);
df694daa
KY
13724}
13725
13726static void alc861_auto_init_multi_out(struct hda_codec *codec)
13727{
13728 struct alc_spec *spec = codec->spec;
13729 int i;
13730
bc9f98a9 13731 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
13732 for (i = 0; i < spec->autocfg.line_outs; i++) {
13733 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13734 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 13735 if (nid)
baba8ee9 13736 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 13737 spec->multiout.dac_nids[i]);
df694daa
KY
13738 }
13739}
13740
13741static void alc861_auto_init_hp_out(struct hda_codec *codec)
13742{
13743 struct alc_spec *spec = codec->spec;
13744 hda_nid_t pin;
13745
eb06ed8f 13746 pin = spec->autocfg.hp_pins[0];
df694daa 13747 if (pin) /* connect to front */
f12ab1e0
TI
13748 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13749 spec->multiout.dac_nids[0]);
f6c7e546
TI
13750 pin = spec->autocfg.speaker_pins[0];
13751 if (pin)
13752 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
13753}
13754
13755static void alc861_auto_init_analog_input(struct hda_codec *codec)
13756{
13757 struct alc_spec *spec = codec->spec;
13758 int i;
13759
13760 for (i = 0; i < AUTO_PIN_LAST; i++) {
13761 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
13762 if (nid >= 0x0c && nid <= 0x11) {
13763 snd_hda_codec_write(codec, nid, 0,
13764 AC_VERB_SET_PIN_WIDGET_CONTROL,
13765 i <= AUTO_PIN_FRONT_MIC ?
13766 PIN_VREF80 : PIN_IN);
df694daa
KY
13767 }
13768 }
13769}
13770
13771/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
13772/* return 1 if successful, 0 if the proper config is not found,
13773 * or a negative error code
13774 */
df694daa
KY
13775static int alc861_parse_auto_config(struct hda_codec *codec)
13776{
13777 struct alc_spec *spec = codec->spec;
13778 int err;
13779 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13780
f12ab1e0
TI
13781 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13782 alc861_ignore);
13783 if (err < 0)
df694daa 13784 return err;
f12ab1e0 13785 if (!spec->autocfg.line_outs)
df694daa
KY
13786 return 0; /* can't find valid BIOS pin config */
13787
f12ab1e0
TI
13788 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13789 if (err < 0)
13790 return err;
13791 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13792 if (err < 0)
13793 return err;
13794 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13795 if (err < 0)
13796 return err;
13797 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13798 if (err < 0)
df694daa
KY
13799 return err;
13800
13801 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13802
13803 if (spec->autocfg.dig_out_pin)
13804 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13805
603c4019 13806 if (spec->kctls.list)
d88897ea 13807 add_mixer(spec, spec->kctls.list);
df694daa 13808
d88897ea 13809 add_verb(spec, alc861_auto_init_verbs);
df694daa 13810
a1e8d2da 13811 spec->num_mux_defs = 1;
61b9b9b1 13812 spec->input_mux = &spec->private_imux[0];
df694daa
KY
13813
13814 spec->adc_nids = alc861_adc_nids;
13815 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
f9e336f6 13816 set_capture_mixer(spec);
df694daa 13817
e044c39a 13818 store_pin_configs(codec);
df694daa
KY
13819 return 1;
13820}
13821
ae6b813a
TI
13822/* additional initialization for auto-configuration model */
13823static void alc861_auto_init(struct hda_codec *codec)
df694daa 13824{
f6c7e546 13825 struct alc_spec *spec = codec->spec;
df694daa
KY
13826 alc861_auto_init_multi_out(codec);
13827 alc861_auto_init_hp_out(codec);
13828 alc861_auto_init_analog_input(codec);
f6c7e546 13829 if (spec->unsol_event)
7fb0d78f 13830 alc_inithook(codec);
df694daa
KY
13831}
13832
cb53c626
TI
13833#ifdef CONFIG_SND_HDA_POWER_SAVE
13834static struct hda_amp_list alc861_loopbacks[] = {
13835 { 0x15, HDA_INPUT, 0 },
13836 { 0x15, HDA_INPUT, 1 },
13837 { 0x15, HDA_INPUT, 2 },
13838 { 0x15, HDA_INPUT, 3 },
13839 { } /* end */
13840};
13841#endif
13842
df694daa
KY
13843
13844/*
13845 * configuration and preset
13846 */
f5fcc13c
TI
13847static const char *alc861_models[ALC861_MODEL_LAST] = {
13848 [ALC861_3ST] = "3stack",
13849 [ALC660_3ST] = "3stack-660",
13850 [ALC861_3ST_DIG] = "3stack-dig",
13851 [ALC861_6ST_DIG] = "6stack-dig",
13852 [ALC861_UNIWILL_M31] = "uniwill-m31",
13853 [ALC861_TOSHIBA] = "toshiba",
13854 [ALC861_ASUS] = "asus",
13855 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13856 [ALC861_AUTO] = "auto",
13857};
13858
13859static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 13860 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
13861 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13862 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13863 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 13864 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 13865 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 13866 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
13867 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13868 * Any other models that need this preset?
13869 */
13870 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
13871 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13872 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 13873 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
13874 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13875 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13876 /* FIXME: the below seems conflict */
13877 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 13878 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 13879 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
13880 {}
13881};
13882
13883static struct alc_config_preset alc861_presets[] = {
13884 [ALC861_3ST] = {
13885 .mixers = { alc861_3ST_mixer },
13886 .init_verbs = { alc861_threestack_init_verbs },
13887 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13888 .dac_nids = alc861_dac_nids,
13889 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13890 .channel_mode = alc861_threestack_modes,
4e195a7b 13891 .need_dac_fix = 1,
df694daa
KY
13892 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13893 .adc_nids = alc861_adc_nids,
13894 .input_mux = &alc861_capture_source,
13895 },
13896 [ALC861_3ST_DIG] = {
13897 .mixers = { alc861_base_mixer },
13898 .init_verbs = { alc861_threestack_init_verbs },
13899 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13900 .dac_nids = alc861_dac_nids,
13901 .dig_out_nid = ALC861_DIGOUT_NID,
13902 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13903 .channel_mode = alc861_threestack_modes,
4e195a7b 13904 .need_dac_fix = 1,
df694daa
KY
13905 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13906 .adc_nids = alc861_adc_nids,
13907 .input_mux = &alc861_capture_source,
13908 },
13909 [ALC861_6ST_DIG] = {
13910 .mixers = { alc861_base_mixer },
13911 .init_verbs = { alc861_base_init_verbs },
13912 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13913 .dac_nids = alc861_dac_nids,
13914 .dig_out_nid = ALC861_DIGOUT_NID,
13915 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13916 .channel_mode = alc861_8ch_modes,
13917 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13918 .adc_nids = alc861_adc_nids,
13919 .input_mux = &alc861_capture_source,
13920 },
9c7f852e
TI
13921 [ALC660_3ST] = {
13922 .mixers = { alc861_3ST_mixer },
13923 .init_verbs = { alc861_threestack_init_verbs },
13924 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13925 .dac_nids = alc660_dac_nids,
13926 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13927 .channel_mode = alc861_threestack_modes,
4e195a7b 13928 .need_dac_fix = 1,
9c7f852e
TI
13929 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13930 .adc_nids = alc861_adc_nids,
13931 .input_mux = &alc861_capture_source,
13932 },
22309c3e
TI
13933 [ALC861_UNIWILL_M31] = {
13934 .mixers = { alc861_uniwill_m31_mixer },
13935 .init_verbs = { alc861_uniwill_m31_init_verbs },
13936 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13937 .dac_nids = alc861_dac_nids,
13938 .dig_out_nid = ALC861_DIGOUT_NID,
13939 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13940 .channel_mode = alc861_uniwill_m31_modes,
13941 .need_dac_fix = 1,
13942 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13943 .adc_nids = alc861_adc_nids,
13944 .input_mux = &alc861_capture_source,
13945 },
a53d1aec
TD
13946 [ALC861_TOSHIBA] = {
13947 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
13948 .init_verbs = { alc861_base_init_verbs,
13949 alc861_toshiba_init_verbs },
a53d1aec
TD
13950 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13951 .dac_nids = alc861_dac_nids,
13952 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13953 .channel_mode = alc883_3ST_2ch_modes,
13954 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13955 .adc_nids = alc861_adc_nids,
13956 .input_mux = &alc861_capture_source,
13957 .unsol_event = alc861_toshiba_unsol_event,
13958 .init_hook = alc861_toshiba_automute,
13959 },
7cdbff94
MD
13960 [ALC861_ASUS] = {
13961 .mixers = { alc861_asus_mixer },
13962 .init_verbs = { alc861_asus_init_verbs },
13963 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13964 .dac_nids = alc861_dac_nids,
13965 .dig_out_nid = ALC861_DIGOUT_NID,
13966 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13967 .channel_mode = alc861_asus_modes,
13968 .need_dac_fix = 1,
13969 .hp_nid = 0x06,
13970 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13971 .adc_nids = alc861_adc_nids,
13972 .input_mux = &alc861_capture_source,
13973 },
56bb0cab
TI
13974 [ALC861_ASUS_LAPTOP] = {
13975 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13976 .init_verbs = { alc861_asus_init_verbs,
13977 alc861_asus_laptop_init_verbs },
13978 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13979 .dac_nids = alc861_dac_nids,
13980 .dig_out_nid = ALC861_DIGOUT_NID,
13981 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13982 .channel_mode = alc883_3ST_2ch_modes,
13983 .need_dac_fix = 1,
13984 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13985 .adc_nids = alc861_adc_nids,
13986 .input_mux = &alc861_capture_source,
13987 },
13988};
df694daa
KY
13989
13990
13991static int patch_alc861(struct hda_codec *codec)
13992{
13993 struct alc_spec *spec;
13994 int board_config;
13995 int err;
13996
dc041e0b 13997 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
13998 if (spec == NULL)
13999 return -ENOMEM;
14000
f12ab1e0 14001 codec->spec = spec;
df694daa 14002
f5fcc13c
TI
14003 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14004 alc861_models,
14005 alc861_cfg_tbl);
9c7f852e 14006
f5fcc13c 14007 if (board_config < 0) {
9c7f852e
TI
14008 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14009 "trying auto-probe from BIOS...\n");
df694daa
KY
14010 board_config = ALC861_AUTO;
14011 }
14012
14013 if (board_config == ALC861_AUTO) {
14014 /* automatic parse from the BIOS config */
14015 err = alc861_parse_auto_config(codec);
14016 if (err < 0) {
14017 alc_free(codec);
14018 return err;
f12ab1e0 14019 } else if (!err) {
9c7f852e
TI
14020 printk(KERN_INFO
14021 "hda_codec: Cannot set up configuration "
14022 "from BIOS. Using base mode...\n");
df694daa
KY
14023 board_config = ALC861_3ST_DIG;
14024 }
14025 }
14026
680cd536
KK
14027 err = snd_hda_attach_beep_device(codec, 0x23);
14028 if (err < 0) {
14029 alc_free(codec);
14030 return err;
14031 }
14032
df694daa
KY
14033 if (board_config != ALC861_AUTO)
14034 setup_preset(spec, &alc861_presets[board_config]);
14035
14036 spec->stream_name_analog = "ALC861 Analog";
14037 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14038 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14039
14040 spec->stream_name_digital = "ALC861 Digital";
14041 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14042 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14043
2134ea4f
TI
14044 spec->vmaster_nid = 0x03;
14045
df694daa
KY
14046 codec->patch_ops = alc_patch_ops;
14047 if (board_config == ALC861_AUTO)
ae6b813a 14048 spec->init_hook = alc861_auto_init;
cb53c626
TI
14049#ifdef CONFIG_SND_HDA_POWER_SAVE
14050 if (!spec->loopback.amplist)
14051 spec->loopback.amplist = alc861_loopbacks;
14052#endif
daead538 14053 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 14054
1da177e4
LT
14055 return 0;
14056}
14057
f32610ed
JS
14058/*
14059 * ALC861-VD support
14060 *
14061 * Based on ALC882
14062 *
14063 * In addition, an independent DAC
14064 */
14065#define ALC861VD_DIGOUT_NID 0x06
14066
14067static hda_nid_t alc861vd_dac_nids[4] = {
14068 /* front, surr, clfe, side surr */
14069 0x02, 0x03, 0x04, 0x05
14070};
14071
14072/* dac_nids for ALC660vd are in a different order - according to
14073 * Realtek's driver.
14074 * This should probably tesult in a different mixer for 6stack models
14075 * of ALC660vd codecs, but for now there is only 3stack mixer
14076 * - and it is the same as in 861vd.
14077 * adc_nids in ALC660vd are (is) the same as in 861vd
14078 */
14079static hda_nid_t alc660vd_dac_nids[3] = {
14080 /* front, rear, clfe, rear_surr */
14081 0x02, 0x04, 0x03
14082};
14083
14084static hda_nid_t alc861vd_adc_nids[1] = {
14085 /* ADC0 */
14086 0x09,
14087};
14088
e1406348
TI
14089static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14090
f32610ed
JS
14091/* input MUX */
14092/* FIXME: should be a matrix-type input source selection */
14093static struct hda_input_mux alc861vd_capture_source = {
14094 .num_items = 4,
14095 .items = {
14096 { "Mic", 0x0 },
14097 { "Front Mic", 0x1 },
14098 { "Line", 0x2 },
14099 { "CD", 0x4 },
14100 },
14101};
14102
272a527c 14103static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 14104 .num_items = 2,
272a527c 14105 .items = {
b419f346
TD
14106 { "Ext Mic", 0x0 },
14107 { "Int Mic", 0x1 },
272a527c
KY
14108 },
14109};
14110
d1a991a6
KY
14111static struct hda_input_mux alc861vd_hp_capture_source = {
14112 .num_items = 2,
14113 .items = {
14114 { "Front Mic", 0x0 },
14115 { "ATAPI Mic", 0x1 },
14116 },
14117};
14118
f32610ed
JS
14119/*
14120 * 2ch mode
14121 */
14122static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14123 { 2, NULL }
14124};
14125
14126/*
14127 * 6ch mode
14128 */
14129static struct hda_verb alc861vd_6stack_ch6_init[] = {
14130 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14131 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14132 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14133 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14134 { } /* end */
14135};
14136
14137/*
14138 * 8ch mode
14139 */
14140static struct hda_verb alc861vd_6stack_ch8_init[] = {
14141 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14142 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14143 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14144 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14145 { } /* end */
14146};
14147
14148static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14149 { 6, alc861vd_6stack_ch6_init },
14150 { 8, alc861vd_6stack_ch8_init },
14151};
14152
14153static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14154 {
14155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14156 .name = "Channel Mode",
14157 .info = alc_ch_mode_info,
14158 .get = alc_ch_mode_get,
14159 .put = alc_ch_mode_put,
14160 },
14161 { } /* end */
14162};
14163
f32610ed
JS
14164/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14165 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14166 */
14167static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14168 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14169 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14170
14171 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14172 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14173
14174 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14175 HDA_OUTPUT),
14176 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14177 HDA_OUTPUT),
14178 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14179 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14180
14181 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14182 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14183
14184 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14185
14186 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14189
14190 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14192 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14193
14194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14195 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14196
14197 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14198 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14199
14200 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14201 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14202
14203 { } /* end */
14204};
14205
14206static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14207 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14208 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14209
14210 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14211
14212 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14214 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14215
14216 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14217 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14218 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14219
14220 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14221 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14222
14223 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14224 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14225
14226 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14227 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14228
14229 { } /* end */
14230};
14231
bdd148a3
KY
14232static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14233 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14234 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14235 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14236
14237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14238
14239 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14241 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14242
14243 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14244 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14245 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14246
14247 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14248 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14249
14250 { } /* end */
14251};
14252
b419f346
TD
14253/* Pin assignment: Speaker=0x14, HP = 0x15,
14254 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
14255 */
14256static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
14257 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14258 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
14259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14260 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
14261 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14262 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14263 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14264 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14265 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14266 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14267 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
14268 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
14269 { } /* end */
14270};
14271
d1a991a6
KY
14272/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14273 * Front Mic=0x18, ATAPI Mic = 0x19,
14274 */
14275static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14276 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14277 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14279 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14280 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14281 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14282 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14283 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 14284
d1a991a6
KY
14285 { } /* end */
14286};
14287
f32610ed
JS
14288/*
14289 * generic initialization of ADC, input mixers and output mixers
14290 */
14291static struct hda_verb alc861vd_volume_init_verbs[] = {
14292 /*
14293 * Unmute ADC0 and set the default input to mic-in
14294 */
14295 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14296 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14297
14298 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14299 * the analog-loopback mixer widget
14300 */
14301 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
14302 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14303 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14304 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14305 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14306 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
14307
14308 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
14309 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14310 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 14312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
14313
14314 /*
14315 * Set up output mixers (0x02 - 0x05)
14316 */
14317 /* set vol=0 to output mixers */
14318 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14319 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14320 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14321 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14322
14323 /* set up input amps for analog loopback */
14324 /* Amp Indices: DAC = 0, mixer = 1 */
14325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14328 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14330 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14331 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14332 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14333
14334 { }
14335};
14336
14337/*
14338 * 3-stack pin configuration:
14339 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14340 */
14341static struct hda_verb alc861vd_3stack_init_verbs[] = {
14342 /*
14343 * Set pin mode and muting
14344 */
14345 /* set front pin widgets 0x14 for output */
14346 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14347 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14348 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14349
14350 /* Mic (rear) pin: input vref at 80% */
14351 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14352 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14353 /* Front Mic pin: input vref at 80% */
14354 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14355 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14356 /* Line In pin: input */
14357 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14358 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14359 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14360 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14361 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14362 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14363 /* CD pin widget for input */
14364 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14365
14366 { }
14367};
14368
14369/*
14370 * 6-stack pin configuration:
14371 */
14372static struct hda_verb alc861vd_6stack_init_verbs[] = {
14373 /*
14374 * Set pin mode and muting
14375 */
14376 /* set front pin widgets 0x14 for output */
14377 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14378 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14379 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14380
14381 /* Rear Pin: output 1 (0x0d) */
14382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14383 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14384 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14385 /* CLFE Pin: output 2 (0x0e) */
14386 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14387 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14388 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14389 /* Side Pin: output 3 (0x0f) */
14390 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14391 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14392 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14393
14394 /* Mic (rear) pin: input vref at 80% */
14395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14397 /* Front Mic pin: input vref at 80% */
14398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14400 /* Line In pin: input */
14401 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14402 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14403 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14405 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14406 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14407 /* CD pin widget for input */
14408 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14409
14410 { }
14411};
14412
bdd148a3
KY
14413static struct hda_verb alc861vd_eapd_verbs[] = {
14414 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14415 { }
14416};
14417
f9423e7a
KY
14418static struct hda_verb alc660vd_eapd_verbs[] = {
14419 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14420 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14421 { }
14422};
14423
bdd148a3
KY
14424static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14428 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 14429 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
14430 {}
14431};
14432
14433/* toggle speaker-output according to the hp-jack state */
14434static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14435{
14436 unsigned int present;
14437 unsigned char bits;
14438
14439 present = snd_hda_codec_read(codec, 0x1b, 0,
14440 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14441 bits = present ? HDA_AMP_MUTE : 0;
14442 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14443 HDA_AMP_MUTE, bits);
bdd148a3
KY
14444}
14445
14446static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14447{
14448 unsigned int present;
14449 unsigned char bits;
14450
14451 present = snd_hda_codec_read(codec, 0x18, 0,
14452 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14453 bits = present ? HDA_AMP_MUTE : 0;
14454 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14455 HDA_AMP_MUTE, bits);
bdd148a3
KY
14456}
14457
14458static void alc861vd_lenovo_automute(struct hda_codec *codec)
14459{
14460 alc861vd_lenovo_hp_automute(codec);
14461 alc861vd_lenovo_mic_automute(codec);
14462}
14463
14464static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14465 unsigned int res)
14466{
14467 switch (res >> 26) {
14468 case ALC880_HP_EVENT:
14469 alc861vd_lenovo_hp_automute(codec);
14470 break;
14471 case ALC880_MIC_EVENT:
14472 alc861vd_lenovo_mic_automute(codec);
14473 break;
14474 }
14475}
14476
272a527c
KY
14477static struct hda_verb alc861vd_dallas_verbs[] = {
14478 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14479 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14480 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14481 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14482
14483 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14484 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14485 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14486 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14487 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14488 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14489 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14490 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 14491
272a527c
KY
14492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14493 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14496 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14497 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14498 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14499 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14500
14501 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14502 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14503 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14504 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14506 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14507 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14508 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14509
14510 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14512 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14513 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14514
14515 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 14516 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
14517 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14518
14519 { } /* end */
14520};
14521
14522/* toggle speaker-output according to the hp-jack state */
14523static void alc861vd_dallas_automute(struct hda_codec *codec)
14524{
14525 unsigned int present;
14526
14527 present = snd_hda_codec_read(codec, 0x15, 0,
14528 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14529 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14530 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
14531}
14532
14533static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14534{
14535 if ((res >> 26) == ALC880_HP_EVENT)
14536 alc861vd_dallas_automute(codec);
14537}
14538
cb53c626
TI
14539#ifdef CONFIG_SND_HDA_POWER_SAVE
14540#define alc861vd_loopbacks alc880_loopbacks
14541#endif
14542
f32610ed
JS
14543/* pcm configuration: identiacal with ALC880 */
14544#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14545#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14546#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14547#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14548
14549/*
14550 * configuration and preset
14551 */
14552static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14553 [ALC660VD_3ST] = "3stack-660",
983f8ae4 14554 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 14555 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
14556 [ALC861VD_3ST] = "3stack",
14557 [ALC861VD_3ST_DIG] = "3stack-digout",
14558 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 14559 [ALC861VD_LENOVO] = "lenovo",
272a527c 14560 [ALC861VD_DALLAS] = "dallas",
983f8ae4 14561 [ALC861VD_HP] = "hp",
f32610ed
JS
14562 [ALC861VD_AUTO] = "auto",
14563};
14564
14565static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
14566 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14567 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 14568 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 14569 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13c94744 14570 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 14571 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 14572 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 14573 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 14574 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 14575 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 14576 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 14577 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 14578 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
14579 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14580 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
be321a89 14581 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
625dc0bf 14582 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
14583 {}
14584};
14585
14586static struct alc_config_preset alc861vd_presets[] = {
14587 [ALC660VD_3ST] = {
14588 .mixers = { alc861vd_3st_mixer },
14589 .init_verbs = { alc861vd_volume_init_verbs,
14590 alc861vd_3stack_init_verbs },
14591 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14592 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
14593 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14594 .channel_mode = alc861vd_3stack_2ch_modes,
14595 .input_mux = &alc861vd_capture_source,
14596 },
6963f84c
MC
14597 [ALC660VD_3ST_DIG] = {
14598 .mixers = { alc861vd_3st_mixer },
14599 .init_verbs = { alc861vd_volume_init_verbs,
14600 alc861vd_3stack_init_verbs },
14601 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14602 .dac_nids = alc660vd_dac_nids,
14603 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
14604 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14605 .channel_mode = alc861vd_3stack_2ch_modes,
14606 .input_mux = &alc861vd_capture_source,
14607 },
f32610ed
JS
14608 [ALC861VD_3ST] = {
14609 .mixers = { alc861vd_3st_mixer },
14610 .init_verbs = { alc861vd_volume_init_verbs,
14611 alc861vd_3stack_init_verbs },
14612 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14613 .dac_nids = alc861vd_dac_nids,
14614 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14615 .channel_mode = alc861vd_3stack_2ch_modes,
14616 .input_mux = &alc861vd_capture_source,
14617 },
14618 [ALC861VD_3ST_DIG] = {
14619 .mixers = { alc861vd_3st_mixer },
14620 .init_verbs = { alc861vd_volume_init_verbs,
14621 alc861vd_3stack_init_verbs },
14622 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14623 .dac_nids = alc861vd_dac_nids,
14624 .dig_out_nid = ALC861VD_DIGOUT_NID,
14625 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14626 .channel_mode = alc861vd_3stack_2ch_modes,
14627 .input_mux = &alc861vd_capture_source,
14628 },
14629 [ALC861VD_6ST_DIG] = {
14630 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14631 .init_verbs = { alc861vd_volume_init_verbs,
14632 alc861vd_6stack_init_verbs },
14633 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14634 .dac_nids = alc861vd_dac_nids,
14635 .dig_out_nid = ALC861VD_DIGOUT_NID,
14636 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14637 .channel_mode = alc861vd_6stack_modes,
14638 .input_mux = &alc861vd_capture_source,
14639 },
bdd148a3
KY
14640 [ALC861VD_LENOVO] = {
14641 .mixers = { alc861vd_lenovo_mixer },
14642 .init_verbs = { alc861vd_volume_init_verbs,
14643 alc861vd_3stack_init_verbs,
14644 alc861vd_eapd_verbs,
14645 alc861vd_lenovo_unsol_verbs },
14646 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14647 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
14648 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14649 .channel_mode = alc861vd_3stack_2ch_modes,
14650 .input_mux = &alc861vd_capture_source,
14651 .unsol_event = alc861vd_lenovo_unsol_event,
14652 .init_hook = alc861vd_lenovo_automute,
14653 },
272a527c
KY
14654 [ALC861VD_DALLAS] = {
14655 .mixers = { alc861vd_dallas_mixer },
14656 .init_verbs = { alc861vd_dallas_verbs },
14657 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14658 .dac_nids = alc861vd_dac_nids,
272a527c
KY
14659 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14660 .channel_mode = alc861vd_3stack_2ch_modes,
14661 .input_mux = &alc861vd_dallas_capture_source,
14662 .unsol_event = alc861vd_dallas_unsol_event,
14663 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
14664 },
14665 [ALC861VD_HP] = {
14666 .mixers = { alc861vd_hp_mixer },
14667 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14668 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14669 .dac_nids = alc861vd_dac_nids,
d1a991a6 14670 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
14671 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14672 .channel_mode = alc861vd_3stack_2ch_modes,
14673 .input_mux = &alc861vd_hp_capture_source,
14674 .unsol_event = alc861vd_dallas_unsol_event,
14675 .init_hook = alc861vd_dallas_automute,
ea1fb29a 14676 },
13c94744
TI
14677 [ALC660VD_ASUS_V1S] = {
14678 .mixers = { alc861vd_lenovo_mixer },
14679 .init_verbs = { alc861vd_volume_init_verbs,
14680 alc861vd_3stack_init_verbs,
14681 alc861vd_eapd_verbs,
14682 alc861vd_lenovo_unsol_verbs },
14683 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14684 .dac_nids = alc660vd_dac_nids,
14685 .dig_out_nid = ALC861VD_DIGOUT_NID,
14686 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14687 .channel_mode = alc861vd_3stack_2ch_modes,
14688 .input_mux = &alc861vd_capture_source,
14689 .unsol_event = alc861vd_lenovo_unsol_event,
14690 .init_hook = alc861vd_lenovo_automute,
14691 },
f32610ed
JS
14692};
14693
14694/*
14695 * BIOS auto configuration
14696 */
14697static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14698 hda_nid_t nid, int pin_type, int dac_idx)
14699{
f6c7e546 14700 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
14701}
14702
14703static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14704{
14705 struct alc_spec *spec = codec->spec;
14706 int i;
14707
bc9f98a9 14708 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
14709 for (i = 0; i <= HDA_SIDE; i++) {
14710 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14711 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
14712 if (nid)
14713 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 14714 pin_type, i);
f32610ed
JS
14715 }
14716}
14717
14718
14719static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14720{
14721 struct alc_spec *spec = codec->spec;
14722 hda_nid_t pin;
14723
14724 pin = spec->autocfg.hp_pins[0];
14725 if (pin) /* connect to front and use dac 0 */
14726 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
14727 pin = spec->autocfg.speaker_pins[0];
14728 if (pin)
14729 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
14730}
14731
14732#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14733#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14734
14735static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14736{
14737 struct alc_spec *spec = codec->spec;
14738 int i;
14739
14740 for (i = 0; i < AUTO_PIN_LAST; i++) {
14741 hda_nid_t nid = spec->autocfg.input_pins[i];
14742 if (alc861vd_is_input_pin(nid)) {
14743 snd_hda_codec_write(codec, nid, 0,
14744 AC_VERB_SET_PIN_WIDGET_CONTROL,
14745 i <= AUTO_PIN_FRONT_MIC ?
14746 PIN_VREF80 : PIN_IN);
14747 if (nid != ALC861VD_PIN_CD_NID)
14748 snd_hda_codec_write(codec, nid, 0,
14749 AC_VERB_SET_AMP_GAIN_MUTE,
14750 AMP_OUT_MUTE);
14751 }
14752 }
14753}
14754
f511b01c
TI
14755#define alc861vd_auto_init_input_src alc882_auto_init_input_src
14756
f32610ed
JS
14757#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14758#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14759
14760/* add playback controls from the parsed DAC table */
14761/* Based on ALC880 version. But ALC861VD has separate,
14762 * different NIDs for mute/unmute switch and volume control */
14763static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14764 const struct auto_pin_cfg *cfg)
14765{
14766 char name[32];
14767 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14768 hda_nid_t nid_v, nid_s;
14769 int i, err;
14770
14771 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 14772 if (!spec->multiout.dac_nids[i])
f32610ed
JS
14773 continue;
14774 nid_v = alc861vd_idx_to_mixer_vol(
14775 alc880_dac_to_idx(
14776 spec->multiout.dac_nids[i]));
14777 nid_s = alc861vd_idx_to_mixer_switch(
14778 alc880_dac_to_idx(
14779 spec->multiout.dac_nids[i]));
14780
14781 if (i == 2) {
14782 /* Center/LFE */
f12ab1e0
TI
14783 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14784 "Center Playback Volume",
14785 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14786 HDA_OUTPUT));
14787 if (err < 0)
f32610ed 14788 return err;
f12ab1e0
TI
14789 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14790 "LFE Playback Volume",
14791 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14792 HDA_OUTPUT));
14793 if (err < 0)
f32610ed 14794 return err;
f12ab1e0
TI
14795 err = add_control(spec, ALC_CTL_BIND_MUTE,
14796 "Center Playback Switch",
14797 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14798 HDA_INPUT));
14799 if (err < 0)
f32610ed 14800 return err;
f12ab1e0
TI
14801 err = add_control(spec, ALC_CTL_BIND_MUTE,
14802 "LFE Playback Switch",
14803 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14804 HDA_INPUT));
14805 if (err < 0)
f32610ed
JS
14806 return err;
14807 } else {
14808 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
14809 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14810 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14811 HDA_OUTPUT));
14812 if (err < 0)
f32610ed
JS
14813 return err;
14814 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 14815 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 14816 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
14817 HDA_INPUT));
14818 if (err < 0)
f32610ed
JS
14819 return err;
14820 }
14821 }
14822 return 0;
14823}
14824
14825/* add playback controls for speaker and HP outputs */
14826/* Based on ALC880 version. But ALC861VD has separate,
14827 * different NIDs for mute/unmute switch and volume control */
14828static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14829 hda_nid_t pin, const char *pfx)
14830{
14831 hda_nid_t nid_v, nid_s;
14832 int err;
14833 char name[32];
14834
f12ab1e0 14835 if (!pin)
f32610ed
JS
14836 return 0;
14837
14838 if (alc880_is_fixed_pin(pin)) {
14839 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14840 /* specify the DAC as the extra output */
f12ab1e0 14841 if (!spec->multiout.hp_nid)
f32610ed
JS
14842 spec->multiout.hp_nid = nid_v;
14843 else
14844 spec->multiout.extra_out_nid[0] = nid_v;
14845 /* control HP volume/switch on the output mixer amp */
14846 nid_v = alc861vd_idx_to_mixer_vol(
14847 alc880_fixed_pin_idx(pin));
14848 nid_s = alc861vd_idx_to_mixer_switch(
14849 alc880_fixed_pin_idx(pin));
14850
14851 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
14852 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14853 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14854 if (err < 0)
f32610ed
JS
14855 return err;
14856 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14857 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14858 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14859 if (err < 0)
f32610ed
JS
14860 return err;
14861 } else if (alc880_is_multi_pin(pin)) {
14862 /* set manual connection */
14863 /* we have only a switch on HP-out PIN */
14864 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14865 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14866 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14867 if (err < 0)
f32610ed
JS
14868 return err;
14869 }
14870 return 0;
14871}
14872
14873/* parse the BIOS configuration and set up the alc_spec
14874 * return 1 if successful, 0 if the proper config is not found,
14875 * or a negative error code
14876 * Based on ALC880 version - had to change it to override
14877 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14878static int alc861vd_parse_auto_config(struct hda_codec *codec)
14879{
14880 struct alc_spec *spec = codec->spec;
14881 int err;
14882 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14883
f12ab1e0
TI
14884 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14885 alc861vd_ignore);
14886 if (err < 0)
f32610ed 14887 return err;
f12ab1e0 14888 if (!spec->autocfg.line_outs)
f32610ed
JS
14889 return 0; /* can't find valid BIOS pin config */
14890
f12ab1e0
TI
14891 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14892 if (err < 0)
14893 return err;
14894 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14895 if (err < 0)
14896 return err;
14897 err = alc861vd_auto_create_extra_out(spec,
14898 spec->autocfg.speaker_pins[0],
14899 "Speaker");
14900 if (err < 0)
14901 return err;
14902 err = alc861vd_auto_create_extra_out(spec,
14903 spec->autocfg.hp_pins[0],
14904 "Headphone");
14905 if (err < 0)
14906 return err;
14907 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14908 if (err < 0)
f32610ed
JS
14909 return err;
14910
14911 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14912
14913 if (spec->autocfg.dig_out_pin)
14914 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14915
603c4019 14916 if (spec->kctls.list)
d88897ea 14917 add_mixer(spec, spec->kctls.list);
f32610ed 14918
d88897ea 14919 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
14920
14921 spec->num_mux_defs = 1;
61b9b9b1 14922 spec->input_mux = &spec->private_imux[0];
f32610ed 14923
776e184e
TI
14924 err = alc_auto_add_mic_boost(codec);
14925 if (err < 0)
14926 return err;
14927
e044c39a 14928 store_pin_configs(codec);
f32610ed
JS
14929 return 1;
14930}
14931
14932/* additional initialization for auto-configuration model */
14933static void alc861vd_auto_init(struct hda_codec *codec)
14934{
f6c7e546 14935 struct alc_spec *spec = codec->spec;
f32610ed
JS
14936 alc861vd_auto_init_multi_out(codec);
14937 alc861vd_auto_init_hp_out(codec);
14938 alc861vd_auto_init_analog_input(codec);
f511b01c 14939 alc861vd_auto_init_input_src(codec);
f6c7e546 14940 if (spec->unsol_event)
7fb0d78f 14941 alc_inithook(codec);
f32610ed
JS
14942}
14943
14944static int patch_alc861vd(struct hda_codec *codec)
14945{
14946 struct alc_spec *spec;
14947 int err, board_config;
14948
14949 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14950 if (spec == NULL)
14951 return -ENOMEM;
14952
14953 codec->spec = spec;
14954
14955 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14956 alc861vd_models,
14957 alc861vd_cfg_tbl);
14958
14959 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14960 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14961 "ALC861VD, trying auto-probe from BIOS...\n");
14962 board_config = ALC861VD_AUTO;
14963 }
14964
14965 if (board_config == ALC861VD_AUTO) {
14966 /* automatic parse from the BIOS config */
14967 err = alc861vd_parse_auto_config(codec);
14968 if (err < 0) {
14969 alc_free(codec);
14970 return err;
f12ab1e0 14971 } else if (!err) {
f32610ed
JS
14972 printk(KERN_INFO
14973 "hda_codec: Cannot set up configuration "
14974 "from BIOS. Using base mode...\n");
14975 board_config = ALC861VD_3ST;
14976 }
14977 }
14978
680cd536
KK
14979 err = snd_hda_attach_beep_device(codec, 0x23);
14980 if (err < 0) {
14981 alc_free(codec);
14982 return err;
14983 }
14984
f32610ed
JS
14985 if (board_config != ALC861VD_AUTO)
14986 setup_preset(spec, &alc861vd_presets[board_config]);
14987
2f893286
KY
14988 if (codec->vendor_id == 0x10ec0660) {
14989 spec->stream_name_analog = "ALC660-VD Analog";
14990 spec->stream_name_digital = "ALC660-VD Digital";
f9423e7a 14991 /* always turn on EAPD */
d88897ea 14992 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
14993 } else {
14994 spec->stream_name_analog = "ALC861VD Analog";
14995 spec->stream_name_digital = "ALC861VD Digital";
14996 }
14997
f32610ed
JS
14998 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14999 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15000
f32610ed
JS
15001 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15002 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15003
15004 spec->adc_nids = alc861vd_adc_nids;
15005 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 15006 spec->capsrc_nids = alc861vd_capsrc_nids;
61b9b9b1 15007 spec->capture_style = CAPT_MIX;
f32610ed 15008
f9e336f6 15009 set_capture_mixer(spec);
f32610ed 15010
2134ea4f
TI
15011 spec->vmaster_nid = 0x02;
15012
f32610ed
JS
15013 codec->patch_ops = alc_patch_ops;
15014
15015 if (board_config == ALC861VD_AUTO)
15016 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
15017#ifdef CONFIG_SND_HDA_POWER_SAVE
15018 if (!spec->loopback.amplist)
15019 spec->loopback.amplist = alc861vd_loopbacks;
15020#endif
daead538 15021 codec->proc_widget_hook = print_realtek_coef;
f32610ed
JS
15022
15023 return 0;
15024}
15025
bc9f98a9
KY
15026/*
15027 * ALC662 support
15028 *
15029 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15030 * configuration. Each pin widget can choose any input DACs and a mixer.
15031 * Each ADC is connected from a mixer of all inputs. This makes possible
15032 * 6-channel independent captures.
15033 *
15034 * In addition, an independent DAC for the multi-playback (not used in this
15035 * driver yet).
15036 */
15037#define ALC662_DIGOUT_NID 0x06
15038#define ALC662_DIGIN_NID 0x0a
15039
15040static hda_nid_t alc662_dac_nids[4] = {
15041 /* front, rear, clfe, rear_surr */
15042 0x02, 0x03, 0x04
15043};
15044
15045static hda_nid_t alc662_adc_nids[1] = {
15046 /* ADC1-2 */
15047 0x09,
15048};
e1406348 15049
77a261b7 15050static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
e1406348 15051
bc9f98a9
KY
15052/* input MUX */
15053/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
15054static struct hda_input_mux alc662_capture_source = {
15055 .num_items = 4,
15056 .items = {
15057 { "Mic", 0x0 },
15058 { "Front Mic", 0x1 },
15059 { "Line", 0x2 },
15060 { "CD", 0x4 },
15061 },
15062};
15063
15064static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15065 .num_items = 2,
15066 .items = {
15067 { "Mic", 0x1 },
15068 { "Line", 0x2 },
15069 },
15070};
291702f0
KY
15071
15072static struct hda_input_mux alc662_eeepc_capture_source = {
15073 .num_items = 2,
15074 .items = {
15075 { "i-Mic", 0x1 },
15076 { "e-Mic", 0x0 },
15077 },
15078};
15079
6dda9f4a
KY
15080static struct hda_input_mux alc663_capture_source = {
15081 .num_items = 3,
15082 .items = {
15083 { "Mic", 0x0 },
15084 { "Front Mic", 0x1 },
15085 { "Line", 0x2 },
15086 },
15087};
15088
15089static struct hda_input_mux alc663_m51va_capture_source = {
15090 .num_items = 2,
15091 .items = {
15092 { "Ext-Mic", 0x0 },
15093 { "D-Mic", 0x9 },
15094 },
15095};
15096
bc9f98a9
KY
15097/*
15098 * 2ch mode
15099 */
15100static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15101 { 2, NULL }
15102};
15103
15104/*
15105 * 2ch mode
15106 */
15107static struct hda_verb alc662_3ST_ch2_init[] = {
15108 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15109 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15110 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15111 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15112 { } /* end */
15113};
15114
15115/*
15116 * 6ch mode
15117 */
15118static struct hda_verb alc662_3ST_ch6_init[] = {
15119 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15120 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15121 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15122 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15123 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15124 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15125 { } /* end */
15126};
15127
15128static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15129 { 2, alc662_3ST_ch2_init },
15130 { 6, alc662_3ST_ch6_init },
15131};
15132
15133/*
15134 * 2ch mode
15135 */
15136static struct hda_verb alc662_sixstack_ch6_init[] = {
15137 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15138 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15139 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15140 { } /* end */
15141};
15142
15143/*
15144 * 6ch mode
15145 */
15146static struct hda_verb alc662_sixstack_ch8_init[] = {
15147 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15148 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15149 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15150 { } /* end */
15151};
15152
15153static struct hda_channel_mode alc662_5stack_modes[2] = {
15154 { 2, alc662_sixstack_ch6_init },
15155 { 6, alc662_sixstack_ch8_init },
15156};
15157
15158/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15159 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15160 */
15161
15162static struct snd_kcontrol_new alc662_base_mixer[] = {
15163 /* output mixer control */
15164 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 15165 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15166 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 15167 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15168 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15169 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15170 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15171 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15172 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15173
15174 /*Input mixer control */
15175 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15176 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15177 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15178 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15179 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15180 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15181 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15182 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
15183 { } /* end */
15184};
15185
15186static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15187 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15188 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
15189 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15190 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15191 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15192 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15193 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15195 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15196 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15198 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
15199 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
15200 { } /* end */
15201};
15202
15203static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15204 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15205 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15206 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 15207 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15208 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15209 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15210 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15211 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15213 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15214 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15215 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15216 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15220 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15221 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
15222 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
15223 { } /* end */
15224};
15225
15226static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15227 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15228 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
15229 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15230 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
15231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15232 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15233 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15234 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15236 { } /* end */
15237};
15238
291702f0 15239static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 15240 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 15241
b4818494
HRK
15242 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15243 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
15244
15245 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15246 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15247 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15248
15249 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15250 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15251 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15252 { } /* end */
15253};
15254
8c427226 15255static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
15256 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15257 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
15258 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15259 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15260 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15261 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15262 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15263 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 15264 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
15265 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15266 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15267 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15268 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15269 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15270 { } /* end */
15271};
15272
f1d4e28b
KY
15273static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15274 .ops = &snd_hda_bind_vol,
15275 .values = {
15276 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15277 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15278 0
15279 },
15280};
15281
15282static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15283 .ops = &snd_hda_bind_sw,
15284 .values = {
15285 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15286 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15287 0
15288 },
15289};
15290
6dda9f4a 15291static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
15292 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15293 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15295 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15296 { } /* end */
15297};
15298
15299static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15300 .ops = &snd_hda_bind_sw,
15301 .values = {
15302 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15303 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15304 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15305 0
15306 },
15307};
15308
15309static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15310 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15311 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15313 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15314 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15315 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15316
15317 { } /* end */
15318};
15319
15320static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15321 .ops = &snd_hda_bind_sw,
15322 .values = {
15323 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15324 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15325 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15326 0
15327 },
15328};
15329
15330static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15331 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15332 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15333 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15334 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15335 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15336 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15337 { } /* end */
15338};
15339
15340static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
15341 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15342 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
15343 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15344 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15345 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15346 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15347 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15348 { } /* end */
15349};
15350
15351static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15352 .ops = &snd_hda_bind_vol,
15353 .values = {
15354 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15355 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15356 0
15357 },
15358};
15359
15360static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15361 .ops = &snd_hda_bind_sw,
15362 .values = {
15363 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15364 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15365 0
15366 },
15367};
15368
15369static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15370 HDA_BIND_VOL("Master Playback Volume",
15371 &alc663_asus_two_bind_master_vol),
15372 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15373 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
15374 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15376 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
15377 { } /* end */
15378};
15379
15380static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15381 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15382 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15383 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15385 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15386 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
15387 { } /* end */
15388};
15389
15390static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15391 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15392 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15393 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15394 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15396
15397 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15398 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15399 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15400 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15401 { } /* end */
15402};
15403
15404static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15405 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15406 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15407 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15408
15409 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15410 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15411 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15412 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15415 { } /* end */
15416};
15417
bc9f98a9
KY
15418static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15419 {
15420 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15421 .name = "Channel Mode",
15422 .info = alc_ch_mode_info,
15423 .get = alc_ch_mode_get,
15424 .put = alc_ch_mode_put,
15425 },
15426 { } /* end */
15427};
15428
15429static struct hda_verb alc662_init_verbs[] = {
15430 /* ADC: mute amp left and right */
15431 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15432 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15433 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15434
cb53c626
TI
15435 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15436 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15437 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15438 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15439 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 15440
b60dd394
KY
15441 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15442 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15443 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15444 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15445 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15446 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15447
15448 /* Front Pin: output 0 (0x0c) */
15449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15450 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15451
15452 /* Rear Pin: output 1 (0x0d) */
15453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15455
15456 /* CLFE Pin: output 2 (0x0e) */
15457 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15458 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15459
15460 /* Mic (rear) pin: input vref at 80% */
15461 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15462 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15463 /* Front Mic pin: input vref at 80% */
15464 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15465 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15466 /* Line In pin: input */
15467 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15468 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15469 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15471 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15472 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15473 /* CD pin widget for input */
15474 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15475
15476 /* FIXME: use matrix-type input source selection */
15477 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15478 /* Input mixer */
15479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
15483
15484 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15485 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15486 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15487 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6dda9f4a
KY
15488
15489 /* always trun on EAPD */
15490 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15491 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15492
bc9f98a9
KY
15493 { }
15494};
15495
15496static struct hda_verb alc662_sue_init_verbs[] = {
15497 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15498 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
15499 {}
15500};
15501
15502static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15503 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15504 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15505 {}
bc9f98a9
KY
15506};
15507
8c427226
KY
15508/* Set Unsolicited Event*/
15509static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15510 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15511 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15512 {}
15513};
15514
bc9f98a9
KY
15515/*
15516 * generic initialization of ADC, input mixers and output mixers
15517 */
15518static struct hda_verb alc662_auto_init_verbs[] = {
15519 /*
15520 * Unmute ADC and set the default input to mic-in
15521 */
15522 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15523 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15524
15525 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15526 * mixer widget
15527 * Note: PASD motherboards uses the Line In 2 as the input for front
15528 * panel mic (mic 2)
15529 */
15530 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15531 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15532 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15533 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15534 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15535 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
15536
15537 /*
15538 * Set up output mixers (0x0c - 0x0f)
15539 */
15540 /* set vol=0 to output mixers */
15541 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15542 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15543 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15544
15545 /* set up input amps for analog loopback */
15546 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
15547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15548 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15553
15554
15555 /* FIXME: use matrix-type input source selection */
15556 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15557 /* Input mixer */
15558 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 15559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
15560 { }
15561};
15562
24fb9173
TI
15563/* additional verbs for ALC663 */
15564static struct hda_verb alc663_auto_init_verbs[] = {
15565 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15566 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15567 { }
15568};
15569
6dda9f4a 15570static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
15571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15572 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
15573 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15574 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
15575 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15578 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15579 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15580 {}
15581};
15582
15583static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15584 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15585 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15586 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15589 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15590 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15591 {}
15592};
15593
15594static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15595 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15596 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15597 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15598 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15601 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15602 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15603 {}
15604};
6dda9f4a 15605
f1d4e28b
KY
15606static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15607 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15609 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15610 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15611 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15612 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15613 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15614 {}
15615};
6dda9f4a 15616
f1d4e28b
KY
15617static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15618 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15619 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15620 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15621 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15622 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15625 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
15627 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15628 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
15629 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15630 {}
15631};
15632
15633static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15634 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15635 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15636 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15637 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15638 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15640 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15641 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15642 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15643 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15644 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15645 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
15646 {}
15647};
15648
15649static struct hda_verb alc663_g71v_init_verbs[] = {
15650 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15651 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15652 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15653
15654 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15655 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15656 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15657
15658 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15659 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15660 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15661 {}
15662};
15663
15664static struct hda_verb alc663_g50v_init_verbs[] = {
15665 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15666 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15667 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15668
15669 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15670 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15671 {}
15672};
15673
f1d4e28b
KY
15674static struct hda_verb alc662_ecs_init_verbs[] = {
15675 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15677 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15678 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15679 {}
15680};
15681
f1d4e28b
KY
15682static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15683 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15684 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15685 { } /* end */
15686};
15687
bc9f98a9
KY
15688static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15689{
15690 unsigned int present;
f12ab1e0 15691 unsigned char bits;
bc9f98a9
KY
15692
15693 present = snd_hda_codec_read(codec, 0x14, 0,
15694 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15695 bits = present ? HDA_AMP_MUTE : 0;
15696 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15697 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15698}
15699
15700static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15701{
15702 unsigned int present;
f12ab1e0 15703 unsigned char bits;
bc9f98a9
KY
15704
15705 present = snd_hda_codec_read(codec, 0x1b, 0,
15706 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15707 bits = present ? HDA_AMP_MUTE : 0;
15708 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15709 HDA_AMP_MUTE, bits);
15710 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15711 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15712}
15713
15714static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15715 unsigned int res)
15716{
15717 if ((res >> 26) == ALC880_HP_EVENT)
15718 alc662_lenovo_101e_all_automute(codec);
15719 if ((res >> 26) == ALC880_FRONT_EVENT)
15720 alc662_lenovo_101e_ispeaker_automute(codec);
15721}
15722
291702f0
KY
15723static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15724{
15725 unsigned int present;
15726
15727 present = snd_hda_codec_read(codec, 0x18, 0,
15728 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15729 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15730 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15731 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15732 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15733 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15734 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15735 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15736 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15737}
15738
15739/* unsolicited event for HP jack sensing */
15740static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15741 unsigned int res)
15742{
15743 if ((res >> 26) == ALC880_HP_EVENT)
15744 alc262_hippo1_automute( codec );
15745
15746 if ((res >> 26) == ALC880_MIC_EVENT)
15747 alc662_eeepc_mic_automute(codec);
15748}
15749
15750static void alc662_eeepc_inithook(struct hda_codec *codec)
15751{
15752 alc262_hippo1_automute( codec );
15753 alc662_eeepc_mic_automute(codec);
15754}
15755
8c427226
KY
15756static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15757{
15758 unsigned int mute;
15759 unsigned int present;
15760
15761 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15762 present = snd_hda_codec_read(codec, 0x14, 0,
15763 AC_VERB_GET_PIN_SENSE, 0);
15764 present = (present & 0x80000000) != 0;
15765 if (present) {
15766 /* mute internal speaker */
15767 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
ea1fb29a 15768 HDA_AMP_MUTE, HDA_AMP_MUTE);
8c427226
KY
15769 } else {
15770 /* unmute internal speaker if necessary */
15771 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15772 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
ea1fb29a 15773 HDA_AMP_MUTE, mute);
8c427226
KY
15774 }
15775}
15776
15777/* unsolicited event for HP jack sensing */
15778static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15779 unsigned int res)
15780{
15781 if ((res >> 26) == ALC880_HP_EVENT)
15782 alc662_eeepc_ep20_automute(codec);
15783}
15784
15785static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15786{
15787 alc662_eeepc_ep20_automute(codec);
15788}
15789
6dda9f4a
KY
15790static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15791{
15792 unsigned int present;
15793 unsigned char bits;
15794
15795 present = snd_hda_codec_read(codec, 0x21, 0,
f1d4e28b
KY
15796 AC_VERB_GET_PIN_SENSE, 0)
15797 & AC_PINSENSE_PRESENCE;
6dda9f4a 15798 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
15799 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15800 AMP_IN_MUTE(0), bits);
15801 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15802 AMP_IN_MUTE(0), bits);
15803}
15804
15805static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15806{
15807 unsigned int present;
15808 unsigned char bits;
15809
15810 present = snd_hda_codec_read(codec, 0x21, 0,
15811 AC_VERB_GET_PIN_SENSE, 0)
15812 & AC_PINSENSE_PRESENCE;
15813 bits = present ? HDA_AMP_MUTE : 0;
15814 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15815 AMP_IN_MUTE(0), bits);
15816 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15817 AMP_IN_MUTE(0), bits);
15818 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15819 AMP_IN_MUTE(0), bits);
15820 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15821 AMP_IN_MUTE(0), bits);
15822}
15823
15824static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15825{
15826 unsigned int present;
15827 unsigned char bits;
15828
15829 present = snd_hda_codec_read(codec, 0x15, 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 alc662_f5z_speaker_automute(struct hda_codec *codec)
15844{
15845 unsigned int present;
15846 unsigned char bits;
15847
15848 present = snd_hda_codec_read(codec, 0x1b, 0,
15849 AC_VERB_GET_PIN_SENSE, 0)
15850 & AC_PINSENSE_PRESENCE;
15851 bits = present ? 0 : PIN_OUT;
15852 snd_hda_codec_write(codec, 0x14, 0,
15853 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15854}
15855
15856static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15857{
15858 unsigned int present1, present2;
15859
15860 present1 = snd_hda_codec_read(codec, 0x21, 0,
15861 AC_VERB_GET_PIN_SENSE, 0)
15862 & AC_PINSENSE_PRESENCE;
15863 present2 = snd_hda_codec_read(codec, 0x15, 0,
15864 AC_VERB_GET_PIN_SENSE, 0)
15865 & AC_PINSENSE_PRESENCE;
15866
15867 if (present1 || present2) {
15868 snd_hda_codec_write_cache(codec, 0x14, 0,
15869 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15870 } else {
15871 snd_hda_codec_write_cache(codec, 0x14, 0,
15872 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15873 }
15874}
15875
15876static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15877{
15878 unsigned int present1, present2;
15879
15880 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15881 AC_VERB_GET_PIN_SENSE, 0)
15882 & AC_PINSENSE_PRESENCE;
15883 present2 = snd_hda_codec_read(codec, 0x15, 0,
15884 AC_VERB_GET_PIN_SENSE, 0)
15885 & AC_PINSENSE_PRESENCE;
15886
15887 if (present1 || present2) {
15888 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15889 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15890 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15891 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15892 } else {
15893 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15894 AMP_IN_MUTE(0), 0);
15895 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15896 AMP_IN_MUTE(0), 0);
15897 }
6dda9f4a
KY
15898}
15899
15900static void alc663_m51va_mic_automute(struct hda_codec *codec)
15901{
15902 unsigned int present;
15903
15904 present = snd_hda_codec_read(codec, 0x18, 0,
ea1fb29a
KY
15905 AC_VERB_GET_PIN_SENSE, 0)
15906 & AC_PINSENSE_PRESENCE;
6dda9f4a 15907 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15908 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 15909 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15910 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 15911 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15912 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a 15913 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15914 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a
KY
15915}
15916
15917static void alc663_m51va_unsol_event(struct hda_codec *codec,
15918 unsigned int res)
15919{
15920 switch (res >> 26) {
15921 case ALC880_HP_EVENT:
15922 alc663_m51va_speaker_automute(codec);
15923 break;
15924 case ALC880_MIC_EVENT:
15925 alc663_m51va_mic_automute(codec);
15926 break;
15927 }
15928}
15929
15930static void alc663_m51va_inithook(struct hda_codec *codec)
15931{
15932 alc663_m51va_speaker_automute(codec);
15933 alc663_m51va_mic_automute(codec);
15934}
15935
f1d4e28b
KY
15936/* ***************** Mode1 ******************************/
15937static void alc663_mode1_unsol_event(struct hda_codec *codec,
15938 unsigned int res)
15939{
15940 switch (res >> 26) {
15941 case ALC880_HP_EVENT:
15942 alc663_m51va_speaker_automute(codec);
15943 break;
15944 case ALC880_MIC_EVENT:
15945 alc662_eeepc_mic_automute(codec);
15946 break;
15947 }
15948}
15949
15950static void alc663_mode1_inithook(struct hda_codec *codec)
15951{
15952 alc663_m51va_speaker_automute(codec);
15953 alc662_eeepc_mic_automute(codec);
15954}
15955/* ***************** Mode2 ******************************/
15956static void alc662_mode2_unsol_event(struct hda_codec *codec,
15957 unsigned int res)
15958{
15959 switch (res >> 26) {
15960 case ALC880_HP_EVENT:
15961 alc662_f5z_speaker_automute(codec);
15962 break;
15963 case ALC880_MIC_EVENT:
15964 alc662_eeepc_mic_automute(codec);
15965 break;
15966 }
15967}
15968
15969static void alc662_mode2_inithook(struct hda_codec *codec)
15970{
15971 alc662_f5z_speaker_automute(codec);
15972 alc662_eeepc_mic_automute(codec);
15973}
15974/* ***************** Mode3 ******************************/
15975static void alc663_mode3_unsol_event(struct hda_codec *codec,
15976 unsigned int res)
15977{
15978 switch (res >> 26) {
15979 case ALC880_HP_EVENT:
15980 alc663_two_hp_m1_speaker_automute(codec);
15981 break;
15982 case ALC880_MIC_EVENT:
15983 alc662_eeepc_mic_automute(codec);
15984 break;
15985 }
15986}
15987
15988static void alc663_mode3_inithook(struct hda_codec *codec)
15989{
15990 alc663_two_hp_m1_speaker_automute(codec);
15991 alc662_eeepc_mic_automute(codec);
15992}
15993/* ***************** Mode4 ******************************/
15994static void alc663_mode4_unsol_event(struct hda_codec *codec,
15995 unsigned int res)
15996{
15997 switch (res >> 26) {
15998 case ALC880_HP_EVENT:
15999 alc663_21jd_two_speaker_automute(codec);
16000 break;
16001 case ALC880_MIC_EVENT:
16002 alc662_eeepc_mic_automute(codec);
16003 break;
16004 }
16005}
16006
16007static void alc663_mode4_inithook(struct hda_codec *codec)
16008{
16009 alc663_21jd_two_speaker_automute(codec);
16010 alc662_eeepc_mic_automute(codec);
16011}
16012/* ***************** Mode5 ******************************/
16013static void alc663_mode5_unsol_event(struct hda_codec *codec,
16014 unsigned int res)
16015{
16016 switch (res >> 26) {
16017 case ALC880_HP_EVENT:
16018 alc663_15jd_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_mode5_inithook(struct hda_codec *codec)
16027{
16028 alc663_15jd_two_speaker_automute(codec);
16029 alc662_eeepc_mic_automute(codec);
16030}
16031/* ***************** Mode6 ******************************/
16032static void alc663_mode6_unsol_event(struct hda_codec *codec,
16033 unsigned int res)
16034{
16035 switch (res >> 26) {
16036 case ALC880_HP_EVENT:
16037 alc663_two_hp_m2_speaker_automute(codec);
16038 break;
16039 case ALC880_MIC_EVENT:
16040 alc662_eeepc_mic_automute(codec);
16041 break;
16042 }
16043}
16044
16045static void alc663_mode6_inithook(struct hda_codec *codec)
16046{
16047 alc663_two_hp_m2_speaker_automute(codec);
16048 alc662_eeepc_mic_automute(codec);
16049}
16050
6dda9f4a
KY
16051static void alc663_g71v_hp_automute(struct hda_codec *codec)
16052{
16053 unsigned int present;
16054 unsigned char bits;
16055
16056 present = snd_hda_codec_read(codec, 0x21, 0,
16057 AC_VERB_GET_PIN_SENSE, 0)
16058 & AC_PINSENSE_PRESENCE;
16059 bits = present ? HDA_AMP_MUTE : 0;
16060 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16061 HDA_AMP_MUTE, bits);
16062 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16063 HDA_AMP_MUTE, bits);
16064}
16065
16066static void alc663_g71v_front_automute(struct hda_codec *codec)
16067{
16068 unsigned int present;
16069 unsigned char bits;
16070
16071 present = snd_hda_codec_read(codec, 0x15, 0,
16072 AC_VERB_GET_PIN_SENSE, 0)
16073 & AC_PINSENSE_PRESENCE;
16074 bits = present ? HDA_AMP_MUTE : 0;
16075 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16076 HDA_AMP_MUTE, bits);
16077}
16078
16079static void alc663_g71v_unsol_event(struct hda_codec *codec,
16080 unsigned int res)
16081{
16082 switch (res >> 26) {
16083 case ALC880_HP_EVENT:
16084 alc663_g71v_hp_automute(codec);
16085 break;
16086 case ALC880_FRONT_EVENT:
16087 alc663_g71v_front_automute(codec);
16088 break;
16089 case ALC880_MIC_EVENT:
16090 alc662_eeepc_mic_automute(codec);
16091 break;
16092 }
16093}
16094
16095static void alc663_g71v_inithook(struct hda_codec *codec)
16096{
16097 alc663_g71v_front_automute(codec);
16098 alc663_g71v_hp_automute(codec);
16099 alc662_eeepc_mic_automute(codec);
16100}
16101
16102static void alc663_g50v_unsol_event(struct hda_codec *codec,
16103 unsigned int res)
16104{
16105 switch (res >> 26) {
16106 case ALC880_HP_EVENT:
16107 alc663_m51va_speaker_automute(codec);
16108 break;
16109 case ALC880_MIC_EVENT:
16110 alc662_eeepc_mic_automute(codec);
16111 break;
16112 }
16113}
16114
16115static void alc663_g50v_inithook(struct hda_codec *codec)
16116{
16117 alc663_m51va_speaker_automute(codec);
16118 alc662_eeepc_mic_automute(codec);
16119}
16120
f1d4e28b
KY
16121/* bind hp and internal speaker mute (with plug check) */
16122static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16123 struct snd_ctl_elem_value *ucontrol)
16124{
16125 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16126 long *valp = ucontrol->value.integer.value;
16127 int change;
16128
16129 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16130 HDA_AMP_MUTE,
16131 valp[0] ? 0 : HDA_AMP_MUTE);
16132 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16133 HDA_AMP_MUTE,
16134 valp[1] ? 0 : HDA_AMP_MUTE);
16135 if (change)
16136 alc262_hippo1_automute(codec);
16137 return change;
16138}
16139
16140static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16141 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16142 {
16143 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16144 .name = "Master Playback Switch",
16145 .info = snd_hda_mixer_amp_switch_info,
16146 .get = snd_hda_mixer_amp_switch_get,
16147 .put = alc662_ecs_master_sw_put,
16148 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16149 },
16150
16151 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16152 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16153 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16154
16155 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16156 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16157 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16158 { } /* end */
16159};
16160
cb53c626
TI
16161#ifdef CONFIG_SND_HDA_POWER_SAVE
16162#define alc662_loopbacks alc880_loopbacks
16163#endif
16164
bc9f98a9
KY
16165
16166/* pcm configuration: identiacal with ALC880 */
16167#define alc662_pcm_analog_playback alc880_pcm_analog_playback
16168#define alc662_pcm_analog_capture alc880_pcm_analog_capture
16169#define alc662_pcm_digital_playback alc880_pcm_digital_playback
16170#define alc662_pcm_digital_capture alc880_pcm_digital_capture
16171
16172/*
16173 * configuration and preset
16174 */
16175static const char *alc662_models[ALC662_MODEL_LAST] = {
16176 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16177 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16178 [ALC662_3ST_6ch] = "3stack-6ch",
16179 [ALC662_5ST_DIG] = "6stack-dig",
16180 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 16181 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 16182 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 16183 [ALC662_ECS] = "ecs",
6dda9f4a
KY
16184 [ALC663_ASUS_M51VA] = "m51va",
16185 [ALC663_ASUS_G71V] = "g71v",
16186 [ALC663_ASUS_H13] = "h13",
16187 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
16188 [ALC663_ASUS_MODE1] = "asus-mode1",
16189 [ALC662_ASUS_MODE2] = "asus-mode2",
16190 [ALC663_ASUS_MODE3] = "asus-mode3",
16191 [ALC663_ASUS_MODE4] = "asus-mode4",
16192 [ALC663_ASUS_MODE5] = "asus-mode5",
16193 [ALC663_ASUS_MODE6] = "asus-mode6",
bc9f98a9
KY
16194 [ALC662_AUTO] = "auto",
16195};
16196
16197static struct snd_pci_quirk alc662_cfg_tbl[] = {
6dda9f4a 16198 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
80ffe869 16199 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
3da23cac 16200 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
291702f0 16201 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
8c427226 16202 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
f1d4e28b
KY
16203 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16204 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
16205 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16206 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16207 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16208 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
16209 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16210 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16211 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
80ffe869 16212 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
f1d4e28b
KY
16213 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16214 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16215 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16216 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16217 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16218 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16219 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16220 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16221 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16222 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16223 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16224 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16225 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16226 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16227 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16228 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16229 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16230 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16231 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16232 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16233 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16234 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
95fe5f2c
HRK
16235 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16236 ALC662_3ST_6ch_DIG),
ac3e3741 16237 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
f1d4e28b
KY
16238 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16239 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
cb55974c
HRK
16240 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16241 ALC662_3ST_6ch_DIG),
19c009aa 16242 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
238713d4 16243 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 16244 ALC662_3ST_6ch_DIG),
6dda9f4a
KY
16245 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
16246 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
16247 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
bc9f98a9
KY
16248 {}
16249};
16250
16251static struct alc_config_preset alc662_presets[] = {
16252 [ALC662_3ST_2ch_DIG] = {
f9e336f6 16253 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
16254 .init_verbs = { alc662_init_verbs },
16255 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16256 .dac_nids = alc662_dac_nids,
16257 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16258 .dig_in_nid = ALC662_DIGIN_NID,
16259 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16260 .channel_mode = alc662_3ST_2ch_modes,
16261 .input_mux = &alc662_capture_source,
16262 },
16263 [ALC662_3ST_6ch_DIG] = {
f9e336f6 16264 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16265 .init_verbs = { alc662_init_verbs },
16266 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16267 .dac_nids = alc662_dac_nids,
16268 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16269 .dig_in_nid = ALC662_DIGIN_NID,
16270 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16271 .channel_mode = alc662_3ST_6ch_modes,
16272 .need_dac_fix = 1,
16273 .input_mux = &alc662_capture_source,
f12ab1e0 16274 },
bc9f98a9 16275 [ALC662_3ST_6ch] = {
f9e336f6 16276 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16277 .init_verbs = { alc662_init_verbs },
16278 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16279 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16280 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16281 .channel_mode = alc662_3ST_6ch_modes,
16282 .need_dac_fix = 1,
16283 .input_mux = &alc662_capture_source,
f12ab1e0 16284 },
bc9f98a9 16285 [ALC662_5ST_DIG] = {
f9e336f6 16286 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16287 .init_verbs = { alc662_init_verbs },
16288 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16289 .dac_nids = alc662_dac_nids,
16290 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16291 .dig_in_nid = ALC662_DIGIN_NID,
16292 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16293 .channel_mode = alc662_5stack_modes,
16294 .input_mux = &alc662_capture_source,
16295 },
16296 [ALC662_LENOVO_101E] = {
f9e336f6 16297 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
16298 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16299 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16300 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16301 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16302 .channel_mode = alc662_3ST_2ch_modes,
16303 .input_mux = &alc662_lenovo_101e_capture_source,
16304 .unsol_event = alc662_lenovo_101e_unsol_event,
16305 .init_hook = alc662_lenovo_101e_all_automute,
16306 },
291702f0 16307 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 16308 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
16309 .init_verbs = { alc662_init_verbs,
16310 alc662_eeepc_sue_init_verbs },
16311 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16312 .dac_nids = alc662_dac_nids,
291702f0
KY
16313 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16314 .channel_mode = alc662_3ST_2ch_modes,
16315 .input_mux = &alc662_eeepc_capture_source,
16316 .unsol_event = alc662_eeepc_unsol_event,
16317 .init_hook = alc662_eeepc_inithook,
16318 },
8c427226 16319 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 16320 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
16321 alc662_chmode_mixer },
16322 .init_verbs = { alc662_init_verbs,
16323 alc662_eeepc_ep20_sue_init_verbs },
16324 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16325 .dac_nids = alc662_dac_nids,
8c427226
KY
16326 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16327 .channel_mode = alc662_3ST_6ch_modes,
16328 .input_mux = &alc662_lenovo_101e_capture_source,
16329 .unsol_event = alc662_eeepc_ep20_unsol_event,
16330 .init_hook = alc662_eeepc_ep20_inithook,
16331 },
f1d4e28b 16332 [ALC662_ECS] = {
f9e336f6 16333 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
16334 .init_verbs = { alc662_init_verbs,
16335 alc662_ecs_init_verbs },
16336 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16337 .dac_nids = alc662_dac_nids,
16338 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16339 .channel_mode = alc662_3ST_2ch_modes,
16340 .input_mux = &alc662_eeepc_capture_source,
16341 .unsol_event = alc662_eeepc_unsol_event,
16342 .init_hook = alc662_eeepc_inithook,
16343 },
6dda9f4a 16344 [ALC663_ASUS_M51VA] = {
f9e336f6 16345 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16346 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16347 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16348 .dac_nids = alc662_dac_nids,
16349 .dig_out_nid = ALC662_DIGOUT_NID,
16350 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16351 .channel_mode = alc662_3ST_2ch_modes,
16352 .input_mux = &alc663_m51va_capture_source,
16353 .unsol_event = alc663_m51va_unsol_event,
16354 .init_hook = alc663_m51va_inithook,
16355 },
16356 [ALC663_ASUS_G71V] = {
f9e336f6 16357 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
16358 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16359 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16360 .dac_nids = alc662_dac_nids,
16361 .dig_out_nid = ALC662_DIGOUT_NID,
16362 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16363 .channel_mode = alc662_3ST_2ch_modes,
16364 .input_mux = &alc662_eeepc_capture_source,
16365 .unsol_event = alc663_g71v_unsol_event,
16366 .init_hook = alc663_g71v_inithook,
16367 },
16368 [ALC663_ASUS_H13] = {
f9e336f6 16369 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16370 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16371 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16372 .dac_nids = alc662_dac_nids,
16373 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16374 .channel_mode = alc662_3ST_2ch_modes,
16375 .input_mux = &alc663_m51va_capture_source,
16376 .unsol_event = alc663_m51va_unsol_event,
16377 .init_hook = alc663_m51va_inithook,
16378 },
16379 [ALC663_ASUS_G50V] = {
f9e336f6 16380 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
16381 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16382 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16383 .dac_nids = alc662_dac_nids,
16384 .dig_out_nid = ALC662_DIGOUT_NID,
16385 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16386 .channel_mode = alc662_3ST_6ch_modes,
16387 .input_mux = &alc663_capture_source,
16388 .unsol_event = alc663_g50v_unsol_event,
16389 .init_hook = alc663_g50v_inithook,
16390 },
f1d4e28b 16391 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
16392 .mixers = { alc663_m51va_mixer },
16393 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16394 .init_verbs = { alc662_init_verbs,
16395 alc663_21jd_amic_init_verbs },
16396 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16397 .hp_nid = 0x03,
16398 .dac_nids = alc662_dac_nids,
16399 .dig_out_nid = ALC662_DIGOUT_NID,
16400 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16401 .channel_mode = alc662_3ST_2ch_modes,
16402 .input_mux = &alc662_eeepc_capture_source,
16403 .unsol_event = alc663_mode1_unsol_event,
16404 .init_hook = alc663_mode1_inithook,
16405 },
16406 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
16407 .mixers = { alc662_1bjd_mixer },
16408 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16409 .init_verbs = { alc662_init_verbs,
16410 alc662_1bjd_amic_init_verbs },
16411 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16412 .dac_nids = alc662_dac_nids,
16413 .dig_out_nid = ALC662_DIGOUT_NID,
16414 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16415 .channel_mode = alc662_3ST_2ch_modes,
16416 .input_mux = &alc662_eeepc_capture_source,
16417 .unsol_event = alc662_mode2_unsol_event,
16418 .init_hook = alc662_mode2_inithook,
16419 },
16420 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
16421 .mixers = { alc663_two_hp_m1_mixer },
16422 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16423 .init_verbs = { alc662_init_verbs,
16424 alc663_two_hp_amic_m1_init_verbs },
16425 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16426 .hp_nid = 0x03,
16427 .dac_nids = alc662_dac_nids,
16428 .dig_out_nid = ALC662_DIGOUT_NID,
16429 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16430 .channel_mode = alc662_3ST_2ch_modes,
16431 .input_mux = &alc662_eeepc_capture_source,
16432 .unsol_event = alc663_mode3_unsol_event,
16433 .init_hook = alc663_mode3_inithook,
16434 },
16435 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
16436 .mixers = { alc663_asus_21jd_clfe_mixer },
16437 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16438 .init_verbs = { alc662_init_verbs,
16439 alc663_21jd_amic_init_verbs},
16440 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16441 .hp_nid = 0x03,
16442 .dac_nids = alc662_dac_nids,
16443 .dig_out_nid = ALC662_DIGOUT_NID,
16444 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16445 .channel_mode = alc662_3ST_2ch_modes,
16446 .input_mux = &alc662_eeepc_capture_source,
16447 .unsol_event = alc663_mode4_unsol_event,
16448 .init_hook = alc663_mode4_inithook,
16449 },
16450 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
16451 .mixers = { alc663_asus_15jd_clfe_mixer },
16452 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16453 .init_verbs = { alc662_init_verbs,
16454 alc663_15jd_amic_init_verbs },
16455 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16456 .hp_nid = 0x03,
16457 .dac_nids = alc662_dac_nids,
16458 .dig_out_nid = ALC662_DIGOUT_NID,
16459 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16460 .channel_mode = alc662_3ST_2ch_modes,
16461 .input_mux = &alc662_eeepc_capture_source,
16462 .unsol_event = alc663_mode5_unsol_event,
16463 .init_hook = alc663_mode5_inithook,
16464 },
16465 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
16466 .mixers = { alc663_two_hp_m2_mixer },
16467 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16468 .init_verbs = { alc662_init_verbs,
16469 alc663_two_hp_amic_m2_init_verbs },
16470 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16471 .hp_nid = 0x03,
16472 .dac_nids = alc662_dac_nids,
16473 .dig_out_nid = ALC662_DIGOUT_NID,
16474 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16475 .channel_mode = alc662_3ST_2ch_modes,
16476 .input_mux = &alc662_eeepc_capture_source,
16477 .unsol_event = alc663_mode6_unsol_event,
16478 .init_hook = alc663_mode6_inithook,
16479 },
bc9f98a9
KY
16480};
16481
16482
16483/*
16484 * BIOS auto configuration
16485 */
16486
16487/* add playback controls from the parsed DAC table */
16488static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16489 const struct auto_pin_cfg *cfg)
16490{
16491 char name[32];
16492 static const char *chname[4] = {
16493 "Front", "Surround", NULL /*CLFE*/, "Side"
16494 };
16495 hda_nid_t nid;
16496 int i, err;
16497
16498 for (i = 0; i < cfg->line_outs; i++) {
16499 if (!spec->multiout.dac_nids[i])
16500 continue;
b60dd394 16501 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
16502 if (i == 2) {
16503 /* Center/LFE */
16504 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16505 "Center Playback Volume",
f12ab1e0
TI
16506 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16507 HDA_OUTPUT));
bc9f98a9
KY
16508 if (err < 0)
16509 return err;
16510 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16511 "LFE Playback Volume",
f12ab1e0
TI
16512 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16513 HDA_OUTPUT));
bc9f98a9
KY
16514 if (err < 0)
16515 return err;
b69ce01a 16516 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16517 "Center Playback Switch",
b69ce01a 16518 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
f12ab1e0 16519 HDA_INPUT));
bc9f98a9
KY
16520 if (err < 0)
16521 return err;
b69ce01a 16522 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16523 "LFE Playback Switch",
b69ce01a 16524 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
f12ab1e0 16525 HDA_INPUT));
bc9f98a9
KY
16526 if (err < 0)
16527 return err;
16528 } else {
16529 sprintf(name, "%s Playback Volume", chname[i]);
16530 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
16531 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16532 HDA_OUTPUT));
bc9f98a9
KY
16533 if (err < 0)
16534 return err;
16535 sprintf(name, "%s Playback Switch", chname[i]);
b69ce01a
HRK
16536 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16537 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16538 3, 0, HDA_INPUT));
bc9f98a9
KY
16539 if (err < 0)
16540 return err;
16541 }
16542 }
16543 return 0;
16544}
16545
16546/* add playback controls for speaker and HP outputs */
16547static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16548 const char *pfx)
16549{
16550 hda_nid_t nid;
16551 int err;
16552 char name[32];
16553
16554 if (!pin)
16555 return 0;
16556
24fb9173
TI
16557 if (pin == 0x17) {
16558 /* ALC663 has a mono output pin on 0x17 */
16559 sprintf(name, "%s Playback Switch", pfx);
16560 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16561 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16562 return err;
16563 }
16564
bc9f98a9
KY
16565 if (alc880_is_fixed_pin(pin)) {
16566 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
939778ae 16567 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
bc9f98a9
KY
16568 /* specify the DAC as the extra output */
16569 if (!spec->multiout.hp_nid)
16570 spec->multiout.hp_nid = nid;
16571 else
16572 spec->multiout.extra_out_nid[0] = nid;
16573 /* control HP volume/switch on the output mixer amp */
16574 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16575 sprintf(name, "%s Playback Volume", pfx);
16576 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16577 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16578 if (err < 0)
16579 return err;
16580 sprintf(name, "%s Playback Switch", pfx);
16581 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16582 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16583 if (err < 0)
16584 return err;
16585 } else if (alc880_is_multi_pin(pin)) {
16586 /* set manual connection */
16587 /* we have only a switch on HP-out PIN */
16588 sprintf(name, "%s Playback Switch", pfx);
16589 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16590 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16591 if (err < 0)
16592 return err;
16593 }
16594 return 0;
16595}
16596
16597/* create playback/capture controls for input pins */
16598static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16599 const struct auto_pin_cfg *cfg)
16600{
61b9b9b1 16601 struct hda_input_mux *imux = &spec->private_imux[0];
bc9f98a9
KY
16602 int i, err, idx;
16603
16604 for (i = 0; i < AUTO_PIN_LAST; i++) {
16605 if (alc880_is_input_pin(cfg->input_pins[i])) {
16606 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16607 err = new_analog_input(spec, cfg->input_pins[i],
16608 auto_pin_cfg_labels[i],
16609 idx, 0x0b);
16610 if (err < 0)
16611 return err;
16612 imux->items[imux->num_items].label =
16613 auto_pin_cfg_labels[i];
16614 imux->items[imux->num_items].index =
16615 alc880_input_pin_idx(cfg->input_pins[i]);
16616 imux->num_items++;
16617 }
16618 }
16619 return 0;
16620}
16621
16622static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16623 hda_nid_t nid, int pin_type,
16624 int dac_idx)
16625{
f6c7e546 16626 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
16627 /* need the manual connection? */
16628 if (alc880_is_multi_pin(nid)) {
16629 struct alc_spec *spec = codec->spec;
16630 int idx = alc880_multi_pin_idx(nid);
16631 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16632 AC_VERB_SET_CONNECT_SEL,
16633 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16634 }
16635}
16636
16637static void alc662_auto_init_multi_out(struct hda_codec *codec)
16638{
16639 struct alc_spec *spec = codec->spec;
16640 int i;
16641
8c427226 16642 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
16643 for (i = 0; i <= HDA_SIDE; i++) {
16644 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16645 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 16646 if (nid)
baba8ee9 16647 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
16648 i);
16649 }
16650}
16651
16652static void alc662_auto_init_hp_out(struct hda_codec *codec)
16653{
16654 struct alc_spec *spec = codec->spec;
16655 hda_nid_t pin;
16656
16657 pin = spec->autocfg.hp_pins[0];
16658 if (pin) /* connect to front */
16659 /* use dac 0 */
16660 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16661 pin = spec->autocfg.speaker_pins[0];
16662 if (pin)
16663 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
16664}
16665
16666#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16667#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16668
16669static void alc662_auto_init_analog_input(struct hda_codec *codec)
16670{
16671 struct alc_spec *spec = codec->spec;
16672 int i;
16673
16674 for (i = 0; i < AUTO_PIN_LAST; i++) {
16675 hda_nid_t nid = spec->autocfg.input_pins[i];
16676 if (alc662_is_input_pin(nid)) {
16677 snd_hda_codec_write(codec, nid, 0,
16678 AC_VERB_SET_PIN_WIDGET_CONTROL,
16679 (i <= AUTO_PIN_FRONT_MIC ?
16680 PIN_VREF80 : PIN_IN));
16681 if (nid != ALC662_PIN_CD_NID)
16682 snd_hda_codec_write(codec, nid, 0,
16683 AC_VERB_SET_AMP_GAIN_MUTE,
16684 AMP_OUT_MUTE);
16685 }
16686 }
16687}
16688
f511b01c
TI
16689#define alc662_auto_init_input_src alc882_auto_init_input_src
16690
bc9f98a9
KY
16691static int alc662_parse_auto_config(struct hda_codec *codec)
16692{
16693 struct alc_spec *spec = codec->spec;
16694 int err;
16695 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16696
16697 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16698 alc662_ignore);
16699 if (err < 0)
16700 return err;
16701 if (!spec->autocfg.line_outs)
16702 return 0; /* can't find valid BIOS pin config */
16703
f12ab1e0
TI
16704 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16705 if (err < 0)
16706 return err;
16707 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16708 if (err < 0)
16709 return err;
16710 err = alc662_auto_create_extra_out(spec,
16711 spec->autocfg.speaker_pins[0],
16712 "Speaker");
16713 if (err < 0)
16714 return err;
16715 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16716 "Headphone");
16717 if (err < 0)
16718 return err;
16719 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16720 if (err < 0)
bc9f98a9
KY
16721 return err;
16722
16723 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16724
16725 if (spec->autocfg.dig_out_pin)
16726 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16727
603c4019 16728 if (spec->kctls.list)
d88897ea 16729 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
16730
16731 spec->num_mux_defs = 1;
61b9b9b1 16732 spec->input_mux = &spec->private_imux[0];
ea1fb29a 16733
d88897ea 16734 add_verb(spec, alc662_auto_init_verbs);
24fb9173 16735 if (codec->vendor_id == 0x10ec0663)
d88897ea 16736 add_verb(spec, alc663_auto_init_verbs);
ee979a14
TI
16737
16738 err = alc_auto_add_mic_boost(codec);
16739 if (err < 0)
16740 return err;
16741
e044c39a 16742 store_pin_configs(codec);
8c87286f 16743 return 1;
bc9f98a9
KY
16744}
16745
16746/* additional initialization for auto-configuration model */
16747static void alc662_auto_init(struct hda_codec *codec)
16748{
f6c7e546 16749 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
16750 alc662_auto_init_multi_out(codec);
16751 alc662_auto_init_hp_out(codec);
16752 alc662_auto_init_analog_input(codec);
f511b01c 16753 alc662_auto_init_input_src(codec);
f6c7e546 16754 if (spec->unsol_event)
7fb0d78f 16755 alc_inithook(codec);
bc9f98a9
KY
16756}
16757
16758static int patch_alc662(struct hda_codec *codec)
16759{
16760 struct alc_spec *spec;
16761 int err, board_config;
16762
16763 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16764 if (!spec)
16765 return -ENOMEM;
16766
16767 codec->spec = spec;
16768
2c3bf9ab
TI
16769 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16770
bc9f98a9
KY
16771 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16772 alc662_models,
16773 alc662_cfg_tbl);
16774 if (board_config < 0) {
16775 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16776 "trying auto-probe from BIOS...\n");
16777 board_config = ALC662_AUTO;
16778 }
16779
16780 if (board_config == ALC662_AUTO) {
16781 /* automatic parse from the BIOS config */
16782 err = alc662_parse_auto_config(codec);
16783 if (err < 0) {
16784 alc_free(codec);
16785 return err;
8c87286f 16786 } else if (!err) {
bc9f98a9
KY
16787 printk(KERN_INFO
16788 "hda_codec: Cannot set up configuration "
16789 "from BIOS. Using base mode...\n");
16790 board_config = ALC662_3ST_2ch_DIG;
16791 }
16792 }
16793
680cd536
KK
16794 err = snd_hda_attach_beep_device(codec, 0x1);
16795 if (err < 0) {
16796 alc_free(codec);
16797 return err;
16798 }
16799
bc9f98a9
KY
16800 if (board_config != ALC662_AUTO)
16801 setup_preset(spec, &alc662_presets[board_config]);
16802
6dda9f4a
KY
16803 if (codec->vendor_id == 0x10ec0663) {
16804 spec->stream_name_analog = "ALC663 Analog";
16805 spec->stream_name_digital = "ALC663 Digital";
01afd41f
KY
16806 } else if (codec->vendor_id == 0x10ec0272) {
16807 spec->stream_name_analog = "ALC272 Analog";
16808 spec->stream_name_digital = "ALC272 Digital";
6dda9f4a
KY
16809 } else {
16810 spec->stream_name_analog = "ALC662 Analog";
16811 spec->stream_name_digital = "ALC662 Digital";
16812 }
16813
bc9f98a9
KY
16814 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16815 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16816
bc9f98a9
KY
16817 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16818 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16819
e1406348
TI
16820 spec->adc_nids = alc662_adc_nids;
16821 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16822 spec->capsrc_nids = alc662_capsrc_nids;
61b9b9b1 16823 spec->capture_style = CAPT_MIX;
bc9f98a9 16824
f9e336f6
TI
16825 if (!spec->cap_mixer)
16826 set_capture_mixer(spec);
16827
2134ea4f
TI
16828 spec->vmaster_nid = 0x02;
16829
bc9f98a9
KY
16830 codec->patch_ops = alc_patch_ops;
16831 if (board_config == ALC662_AUTO)
16832 spec->init_hook = alc662_auto_init;
cb53c626
TI
16833#ifdef CONFIG_SND_HDA_POWER_SAVE
16834 if (!spec->loopback.amplist)
16835 spec->loopback.amplist = alc662_loopbacks;
16836#endif
daead538 16837 codec->proc_widget_hook = print_realtek_coef;
bc9f98a9
KY
16838
16839 return 0;
16840}
16841
1da177e4
LT
16842/*
16843 * patch entries
16844 */
1289e9e8 16845static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 16846 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 16847 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 16848 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 16849 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 16850 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
01afd41f 16851 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
f32610ed 16852 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 16853 .patch = patch_alc861 },
f32610ed
JS
16854 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16855 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16856 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
16857 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16858 .patch = patch_alc883 },
16859 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16860 .patch = patch_alc662 },
6dda9f4a 16861 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 16862 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 16863 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 16864 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
669faba2
CM
16865 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16866 .patch = patch_alc882 }, /* should be patch_alc883() in future */
cb308f97 16867 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7943a8ab 16868 .patch = patch_alc882 }, /* should be patch_alc883() in future */
df694daa 16869 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
a385a529 16870 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
4442608d
KY
16871 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16872 .patch = patch_alc883 },
3fea2cb0 16873 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 16874 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
16875 {} /* terminator */
16876};
1289e9e8
TI
16877
16878MODULE_ALIAS("snd-hda-codec-id:10ec*");
16879
16880MODULE_LICENSE("GPL");
16881MODULE_DESCRIPTION("Realtek HD-audio codec");
16882
16883static struct hda_codec_preset_list realtek_list = {
16884 .preset = snd_hda_preset_realtek,
16885 .owner = THIS_MODULE,
16886};
16887
16888static int __init patch_realtek_init(void)
16889{
16890 return snd_hda_add_codec_preset(&realtek_list);
16891}
16892
16893static void __exit patch_realtek_exit(void)
16894{
16895 snd_hda_delete_codec_preset(&realtek_list);
16896}
16897
16898module_init(patch_realtek_init)
16899module_exit(patch_realtek_exit)