]> git.ipfire.org Git - thirdparty/linux.git/blame_incremental - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix Cxt5047 test mode
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
... / ...
CommitLineData
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
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
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"
33#include "hda_beep.h"
34
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
39
40/* ALC880 board config type */
41enum {
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
47 ALC880_Z71V,
48 ALC880_6ST,
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
54 ALC880_ASUS_DIG2,
55 ALC880_FUJITSU,
56 ALC880_UNIWILL_DIG,
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
61 ALC880_LG,
62 ALC880_LG_LW,
63 ALC880_MEDION_RIM,
64#ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66#endif
67 ALC880_AUTO,
68 ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73 ALC260_BASIC,
74 ALC260_HP,
75 ALC260_HP_DC7600,
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
78 ALC260_ACER,
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
81 ALC260_FAVORIT100,
82#ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84#endif
85 ALC260_AUTO,
86 ALC260_MODEL_LAST /* last tag */
87};
88
89/* ALC262 models */
90enum {
91 ALC262_BASIC,
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
94 ALC262_FUJITSU,
95 ALC262_HP_BPC,
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
98 ALC262_HP_TC_T5735,
99 ALC262_HP_RP5700,
100 ALC262_BENQ_ED8,
101 ALC262_SONY_ASSAMD,
102 ALC262_BENQ_T31,
103 ALC262_ULTRA,
104 ALC262_LENOVO_3000,
105 ALC262_NEC,
106 ALC262_TOSHIBA_S06,
107 ALC262_TOSHIBA_RX1,
108 ALC262_TYAN,
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
111};
112
113/* ALC268 models */
114enum {
115 ALC267_QUANTA_IL1,
116 ALC268_3ST,
117 ALC268_TOSHIBA,
118 ALC268_ACER,
119 ALC268_ACER_DMIC,
120 ALC268_ACER_ASPIRE_ONE,
121 ALC268_DELL,
122 ALC268_ZEPTO,
123#ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125#endif
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
128};
129
130/* ALC269 models */
131enum {
132 ALC269_BASIC,
133 ALC269_QUANTA_FL1,
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
136 ALC269_FUJITSU,
137 ALC269_LIFEBOOK,
138 ALC269_AUTO,
139 ALC269_MODEL_LAST /* last tag */
140};
141
142/* ALC861 models */
143enum {
144 ALC861_3ST,
145 ALC660_3ST,
146 ALC861_3ST_DIG,
147 ALC861_6ST_DIG,
148 ALC861_UNIWILL_M31,
149 ALC861_TOSHIBA,
150 ALC861_ASUS,
151 ALC861_ASUS_LAPTOP,
152 ALC861_AUTO,
153 ALC861_MODEL_LAST,
154};
155
156/* ALC861-VD models */
157enum {
158 ALC660VD_3ST,
159 ALC660VD_3ST_DIG,
160 ALC660VD_ASUS_V1S,
161 ALC861VD_3ST,
162 ALC861VD_3ST_DIG,
163 ALC861VD_6ST_DIG,
164 ALC861VD_LENOVO,
165 ALC861VD_DALLAS,
166 ALC861VD_HP,
167 ALC861VD_AUTO,
168 ALC861VD_MODEL_LAST,
169};
170
171/* ALC662 models */
172enum {
173 ALC662_3ST_2ch_DIG,
174 ALC662_3ST_6ch_DIG,
175 ALC662_3ST_6ch,
176 ALC662_5ST_DIG,
177 ALC662_LENOVO_101E,
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
180 ALC663_ASUS_M51VA,
181 ALC663_ASUS_G71V,
182 ALC663_ASUS_H13,
183 ALC663_ASUS_G50V,
184 ALC662_ECS,
185 ALC663_ASUS_MODE1,
186 ALC662_ASUS_MODE2,
187 ALC663_ASUS_MODE3,
188 ALC663_ASUS_MODE4,
189 ALC663_ASUS_MODE5,
190 ALC663_ASUS_MODE6,
191 ALC272_DELL,
192 ALC272_DELL_ZM1,
193 ALC272_SAMSUNG_NC10,
194 ALC662_AUTO,
195 ALC662_MODEL_LAST,
196};
197
198/* ALC882 models */
199enum {
200 ALC882_3ST_DIG,
201 ALC882_6ST_DIG,
202 ALC882_ARIMA,
203 ALC882_W2JC,
204 ALC882_TARGA,
205 ALC882_ASUS_A7J,
206 ALC882_ASUS_A7M,
207 ALC885_MACPRO,
208 ALC885_MBP3,
209 ALC885_MB5,
210 ALC885_IMAC24,
211 ALC883_3ST_2ch_DIG,
212 ALC883_3ST_6ch_DIG,
213 ALC883_3ST_6ch,
214 ALC883_6ST_DIG,
215 ALC883_TARGA_DIG,
216 ALC883_TARGA_2ch_DIG,
217 ALC883_TARGA_8ch_DIG,
218 ALC883_ACER,
219 ALC883_ACER_ASPIRE,
220 ALC888_ACER_ASPIRE_4930G,
221 ALC888_ACER_ASPIRE_6530G,
222 ALC888_ACER_ASPIRE_8930G,
223 ALC888_ACER_ASPIRE_7730G,
224 ALC883_MEDION,
225 ALC883_MEDION_MD2,
226 ALC883_LAPTOP_EAPD,
227 ALC883_LENOVO_101E_2ch,
228 ALC883_LENOVO_NB0763,
229 ALC888_LENOVO_MS7195_DIG,
230 ALC888_LENOVO_SKY,
231 ALC883_HAIER_W66,
232 ALC888_3ST_HP,
233 ALC888_6ST_DELL,
234 ALC883_MITAC,
235 ALC883_CLEVO_M540R,
236 ALC883_CLEVO_M720,
237 ALC883_FUJITSU_PI2515,
238 ALC888_FUJITSU_XA3530,
239 ALC883_3ST_6ch_INTEL,
240 ALC889A_INTEL,
241 ALC889_INTEL,
242 ALC888_ASUS_M90V,
243 ALC888_ASUS_EEE1601,
244 ALC889A_MB31,
245 ALC1200_ASUS_P5Q,
246 ALC883_SONY_VAIO_TT,
247 ALC882_AUTO,
248 ALC882_MODEL_LAST,
249};
250
251/* for GPIO Poll */
252#define GPIO_MASK 0x03
253
254/* extra amp-initialization sequence types */
255enum {
256 ALC_INIT_NONE,
257 ALC_INIT_DEFAULT,
258 ALC_INIT_GPIO1,
259 ALC_INIT_GPIO2,
260 ALC_INIT_GPIO3,
261};
262
263struct alc_mic_route {
264 hda_nid_t pin;
265 unsigned char mux_idx;
266 unsigned char amix_idx;
267};
268
269#define MUX_IDX_UNDEF ((unsigned char)-1)
270
271struct alc_spec {
272 /* codec parameterization */
273 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
274 unsigned int num_mixers;
275 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
276 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
277
278 const struct hda_verb *init_verbs[10]; /* initialization verbs
279 * don't forget NULL
280 * termination!
281 */
282 unsigned int num_init_verbs;
283
284 char stream_name_analog[32]; /* analog PCM stream */
285 struct hda_pcm_stream *stream_analog_playback;
286 struct hda_pcm_stream *stream_analog_capture;
287 struct hda_pcm_stream *stream_analog_alt_playback;
288 struct hda_pcm_stream *stream_analog_alt_capture;
289
290 char stream_name_digital[32]; /* digital PCM stream */
291 struct hda_pcm_stream *stream_digital_playback;
292 struct hda_pcm_stream *stream_digital_capture;
293
294 /* playback */
295 struct hda_multi_out multiout; /* playback set-up
296 * max_channels, dacs must be set
297 * dig_out_nid and hp_nid are optional
298 */
299 hda_nid_t alt_dac_nid;
300 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
301 int dig_out_type;
302
303 /* capture */
304 unsigned int num_adc_nids;
305 hda_nid_t *adc_nids;
306 hda_nid_t *capsrc_nids;
307 hda_nid_t dig_in_nid; /* digital-in NID; optional */
308
309 /* capture source */
310 unsigned int num_mux_defs;
311 const struct hda_input_mux *input_mux;
312 unsigned int cur_mux[3];
313 struct alc_mic_route ext_mic;
314 struct alc_mic_route int_mic;
315
316 /* channel model */
317 const struct hda_channel_mode *channel_mode;
318 int num_channel_mode;
319 int need_dac_fix;
320 int const_channel_count;
321 int ext_channel_count;
322
323 /* PCM information */
324 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
325
326 /* dynamic controls, init_verbs and input_mux */
327 struct auto_pin_cfg autocfg;
328 struct snd_array kctls;
329 struct hda_input_mux private_imux[3];
330 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
331 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
332 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
333
334 /* hooks */
335 void (*init_hook)(struct hda_codec *codec);
336 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
337
338 /* for pin sensing */
339 unsigned int sense_updated: 1;
340 unsigned int jack_present: 1;
341 unsigned int master_sw: 1;
342 unsigned int auto_mic:1;
343
344 /* other flags */
345 unsigned int no_analog :1; /* digital I/O only */
346 int init_amp;
347
348 /* for virtual master */
349 hda_nid_t vmaster_nid;
350#ifdef CONFIG_SND_HDA_POWER_SAVE
351 struct hda_loopback_check loopback;
352#endif
353
354 /* for PLL fix */
355 hda_nid_t pll_nid;
356 unsigned int pll_coef_idx, pll_coef_bit;
357};
358
359/*
360 * configuration template - to be copied to the spec instance
361 */
362struct alc_config_preset {
363 struct snd_kcontrol_new *mixers[5]; /* should be identical size
364 * with spec
365 */
366 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
367 const struct hda_verb *init_verbs[5];
368 unsigned int num_dacs;
369 hda_nid_t *dac_nids;
370 hda_nid_t dig_out_nid; /* optional */
371 hda_nid_t hp_nid; /* optional */
372 hda_nid_t *slave_dig_outs;
373 unsigned int num_adc_nids;
374 hda_nid_t *adc_nids;
375 hda_nid_t *capsrc_nids;
376 hda_nid_t dig_in_nid;
377 unsigned int num_channel_mode;
378 const struct hda_channel_mode *channel_mode;
379 int need_dac_fix;
380 int const_channel_count;
381 unsigned int num_mux_defs;
382 const struct hda_input_mux *input_mux;
383 void (*unsol_event)(struct hda_codec *, unsigned int);
384 void (*setup)(struct hda_codec *);
385 void (*init_hook)(struct hda_codec *);
386#ifdef CONFIG_SND_HDA_POWER_SAVE
387 struct hda_amp_list *loopbacks;
388#endif
389};
390
391
392/*
393 * input MUX handling
394 */
395static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_info *uinfo)
397{
398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
399 struct alc_spec *spec = codec->spec;
400 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
401 if (mux_idx >= spec->num_mux_defs)
402 mux_idx = 0;
403 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
404}
405
406static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
407 struct snd_ctl_elem_value *ucontrol)
408{
409 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
410 struct alc_spec *spec = codec->spec;
411 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
412
413 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
414 return 0;
415}
416
417static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
418 struct snd_ctl_elem_value *ucontrol)
419{
420 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
421 struct alc_spec *spec = codec->spec;
422 const struct hda_input_mux *imux;
423 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
424 unsigned int mux_idx;
425 hda_nid_t nid = spec->capsrc_nids ?
426 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
427 unsigned int type;
428
429 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
430 imux = &spec->input_mux[mux_idx];
431
432 type = get_wcaps_type(get_wcaps(codec, nid));
433 if (type == AC_WID_AUD_MIX) {
434 /* Matrix-mixer style (e.g. ALC882) */
435 unsigned int *cur_val = &spec->cur_mux[adc_idx];
436 unsigned int i, idx;
437
438 idx = ucontrol->value.enumerated.item[0];
439 if (idx >= imux->num_items)
440 idx = imux->num_items - 1;
441 if (*cur_val == idx)
442 return 0;
443 for (i = 0; i < imux->num_items; i++) {
444 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
445 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
446 imux->items[i].index,
447 HDA_AMP_MUTE, v);
448 }
449 *cur_val = idx;
450 return 1;
451 } else {
452 /* MUX style (e.g. ALC880) */
453 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
454 &spec->cur_mux[adc_idx]);
455 }
456}
457
458/*
459 * channel mode setting
460 */
461static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
462 struct snd_ctl_elem_info *uinfo)
463{
464 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
465 struct alc_spec *spec = codec->spec;
466 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
467 spec->num_channel_mode);
468}
469
470static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
472{
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 struct alc_spec *spec = codec->spec;
475 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
476 spec->num_channel_mode,
477 spec->ext_channel_count);
478}
479
480static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
481 struct snd_ctl_elem_value *ucontrol)
482{
483 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
484 struct alc_spec *spec = codec->spec;
485 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
486 spec->num_channel_mode,
487 &spec->ext_channel_count);
488 if (err >= 0 && !spec->const_channel_count) {
489 spec->multiout.max_channels = spec->ext_channel_count;
490 if (spec->need_dac_fix)
491 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
492 }
493 return err;
494}
495
496/*
497 * Control the mode of pin widget settings via the mixer. "pc" is used
498 * instead of "%" to avoid consequences of accidently treating the % as
499 * being part of a format specifier. Maximum allowed length of a value is
500 * 63 characters plus NULL terminator.
501 *
502 * Note: some retasking pin complexes seem to ignore requests for input
503 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
504 * are requested. Therefore order this list so that this behaviour will not
505 * cause problems when mixer clients move through the enum sequentially.
506 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
507 * March 2006.
508 */
509static char *alc_pin_mode_names[] = {
510 "Mic 50pc bias", "Mic 80pc bias",
511 "Line in", "Line out", "Headphone out",
512};
513static unsigned char alc_pin_mode_values[] = {
514 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
515};
516/* The control can present all 5 options, or it can limit the options based
517 * in the pin being assumed to be exclusively an input or an output pin. In
518 * addition, "input" pins may or may not process the mic bias option
519 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
520 * accept requests for bias as of chip versions up to March 2006) and/or
521 * wiring in the computer.
522 */
523#define ALC_PIN_DIR_IN 0x00
524#define ALC_PIN_DIR_OUT 0x01
525#define ALC_PIN_DIR_INOUT 0x02
526#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
527#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
528
529/* Info about the pin modes supported by the different pin direction modes.
530 * For each direction the minimum and maximum values are given.
531 */
532static signed char alc_pin_mode_dir_info[5][2] = {
533 { 0, 2 }, /* ALC_PIN_DIR_IN */
534 { 3, 4 }, /* ALC_PIN_DIR_OUT */
535 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
536 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
537 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
538};
539#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
540#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
541#define alc_pin_mode_n_items(_dir) \
542 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
543
544static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_info *uinfo)
546{
547 unsigned int item_num = uinfo->value.enumerated.item;
548 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
549
550 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
551 uinfo->count = 1;
552 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
553
554 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
555 item_num = alc_pin_mode_min(dir);
556 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
557 return 0;
558}
559
560static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
562{
563 unsigned int i;
564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565 hda_nid_t nid = kcontrol->private_value & 0xffff;
566 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
567 long *valp = ucontrol->value.integer.value;
568 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
569 AC_VERB_GET_PIN_WIDGET_CONTROL,
570 0x00);
571
572 /* Find enumerated value for current pinctl setting */
573 i = alc_pin_mode_min(dir);
574 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
575 i++;
576 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
577 return 0;
578}
579
580static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
582{
583 signed int change;
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
587 long val = *ucontrol->value.integer.value;
588 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
589 AC_VERB_GET_PIN_WIDGET_CONTROL,
590 0x00);
591
592 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
593 val = alc_pin_mode_min(dir);
594
595 change = pinctl != alc_pin_mode_values[val];
596 if (change) {
597 /* Set pin mode to that requested */
598 snd_hda_codec_write_cache(codec, nid, 0,
599 AC_VERB_SET_PIN_WIDGET_CONTROL,
600 alc_pin_mode_values[val]);
601
602 /* Also enable the retasking pin's input/output as required
603 * for the requested pin mode. Enum values of 2 or less are
604 * input modes.
605 *
606 * Dynamically switching the input/output buffers probably
607 * reduces noise slightly (particularly on input) so we'll
608 * do it. However, having both input and output buffers
609 * enabled simultaneously doesn't seem to be problematic if
610 * this turns out to be necessary in the future.
611 */
612 if (val <= 2) {
613 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
614 HDA_AMP_MUTE, HDA_AMP_MUTE);
615 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
616 HDA_AMP_MUTE, 0);
617 } else {
618 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
619 HDA_AMP_MUTE, HDA_AMP_MUTE);
620 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
621 HDA_AMP_MUTE, 0);
622 }
623 }
624 return change;
625}
626
627#define ALC_PIN_MODE(xname, nid, dir) \
628 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
629 .info = alc_pin_mode_info, \
630 .get = alc_pin_mode_get, \
631 .put = alc_pin_mode_put, \
632 .private_value = nid | (dir<<16) }
633
634/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
635 * together using a mask with more than one bit set. This control is
636 * currently used only by the ALC260 test model. At this stage they are not
637 * needed for any "production" models.
638 */
639#ifdef CONFIG_SND_DEBUG
640#define alc_gpio_data_info snd_ctl_boolean_mono_info
641
642static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
644{
645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646 hda_nid_t nid = kcontrol->private_value & 0xffff;
647 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
648 long *valp = ucontrol->value.integer.value;
649 unsigned int val = snd_hda_codec_read(codec, nid, 0,
650 AC_VERB_GET_GPIO_DATA, 0x00);
651
652 *valp = (val & mask) != 0;
653 return 0;
654}
655static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
656 struct snd_ctl_elem_value *ucontrol)
657{
658 signed int change;
659 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
660 hda_nid_t nid = kcontrol->private_value & 0xffff;
661 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
662 long val = *ucontrol->value.integer.value;
663 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
664 AC_VERB_GET_GPIO_DATA,
665 0x00);
666
667 /* Set/unset the masked GPIO bit(s) as needed */
668 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
669 if (val == 0)
670 gpio_data &= ~mask;
671 else
672 gpio_data |= mask;
673 snd_hda_codec_write_cache(codec, nid, 0,
674 AC_VERB_SET_GPIO_DATA, gpio_data);
675
676 return change;
677}
678#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
679 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
680 .info = alc_gpio_data_info, \
681 .get = alc_gpio_data_get, \
682 .put = alc_gpio_data_put, \
683 .private_value = nid | (mask<<16) }
684#endif /* CONFIG_SND_DEBUG */
685
686/* A switch control to allow the enabling of the digital IO pins on the
687 * ALC260. This is incredibly simplistic; the intention of this control is
688 * to provide something in the test model allowing digital outputs to be
689 * identified if present. If models are found which can utilise these
690 * outputs a more complete mixer control can be devised for those models if
691 * necessary.
692 */
693#ifdef CONFIG_SND_DEBUG
694#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
695
696static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
697 struct snd_ctl_elem_value *ucontrol)
698{
699 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
700 hda_nid_t nid = kcontrol->private_value & 0xffff;
701 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
702 long *valp = ucontrol->value.integer.value;
703 unsigned int val = snd_hda_codec_read(codec, nid, 0,
704 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
705
706 *valp = (val & mask) != 0;
707 return 0;
708}
709static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
710 struct snd_ctl_elem_value *ucontrol)
711{
712 signed int change;
713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
714 hda_nid_t nid = kcontrol->private_value & 0xffff;
715 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
716 long val = *ucontrol->value.integer.value;
717 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
718 AC_VERB_GET_DIGI_CONVERT_1,
719 0x00);
720
721 /* Set/unset the masked control bit(s) as needed */
722 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
723 if (val==0)
724 ctrl_data &= ~mask;
725 else
726 ctrl_data |= mask;
727 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
728 ctrl_data);
729
730 return change;
731}
732#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
733 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
734 .info = alc_spdif_ctrl_info, \
735 .get = alc_spdif_ctrl_get, \
736 .put = alc_spdif_ctrl_put, \
737 .private_value = nid | (mask<<16) }
738#endif /* CONFIG_SND_DEBUG */
739
740/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
741 * Again, this is only used in the ALC26x test models to help identify when
742 * the EAPD line must be asserted for features to work.
743 */
744#ifdef CONFIG_SND_DEBUG
745#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
746
747static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
748 struct snd_ctl_elem_value *ucontrol)
749{
750 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
751 hda_nid_t nid = kcontrol->private_value & 0xffff;
752 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
753 long *valp = ucontrol->value.integer.value;
754 unsigned int val = snd_hda_codec_read(codec, nid, 0,
755 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
756
757 *valp = (val & mask) != 0;
758 return 0;
759}
760
761static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
762 struct snd_ctl_elem_value *ucontrol)
763{
764 int change;
765 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
766 hda_nid_t nid = kcontrol->private_value & 0xffff;
767 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
768 long val = *ucontrol->value.integer.value;
769 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
770 AC_VERB_GET_EAPD_BTLENABLE,
771 0x00);
772
773 /* Set/unset the masked control bit(s) as needed */
774 change = (!val ? 0 : mask) != (ctrl_data & mask);
775 if (!val)
776 ctrl_data &= ~mask;
777 else
778 ctrl_data |= mask;
779 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
780 ctrl_data);
781
782 return change;
783}
784
785#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
786 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
787 .info = alc_eapd_ctrl_info, \
788 .get = alc_eapd_ctrl_get, \
789 .put = alc_eapd_ctrl_put, \
790 .private_value = nid | (mask<<16) }
791#endif /* CONFIG_SND_DEBUG */
792
793/*
794 * set up the input pin config (depending on the given auto-pin type)
795 */
796static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
797 int auto_pin_type)
798{
799 unsigned int val = PIN_IN;
800
801 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
802 unsigned int pincap;
803 pincap = snd_hda_query_pin_caps(codec, nid);
804 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
805 if (pincap & AC_PINCAP_VREF_80)
806 val = PIN_VREF80;
807 else if (pincap & AC_PINCAP_VREF_50)
808 val = PIN_VREF50;
809 else if (pincap & AC_PINCAP_VREF_100)
810 val = PIN_VREF100;
811 else if (pincap & AC_PINCAP_VREF_GRD)
812 val = PIN_VREFGRD;
813 }
814 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
815}
816
817/*
818 */
819static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
820{
821 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
822 return;
823 spec->mixers[spec->num_mixers++] = mix;
824}
825
826static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
827{
828 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
829 return;
830 spec->init_verbs[spec->num_init_verbs++] = verb;
831}
832
833#ifdef CONFIG_PROC_FS
834/*
835 * hook for proc
836 */
837static void print_realtek_coef(struct snd_info_buffer *buffer,
838 struct hda_codec *codec, hda_nid_t nid)
839{
840 int coeff;
841
842 if (nid != 0x20)
843 return;
844 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
845 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
846 coeff = snd_hda_codec_read(codec, nid, 0,
847 AC_VERB_GET_COEF_INDEX, 0);
848 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
849}
850#else
851#define print_realtek_coef NULL
852#endif
853
854/*
855 * set up from the preset table
856 */
857static void setup_preset(struct hda_codec *codec,
858 const struct alc_config_preset *preset)
859{
860 struct alc_spec *spec = codec->spec;
861 int i;
862
863 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
864 add_mixer(spec, preset->mixers[i]);
865 spec->cap_mixer = preset->cap_mixer;
866 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
867 i++)
868 add_verb(spec, preset->init_verbs[i]);
869
870 spec->channel_mode = preset->channel_mode;
871 spec->num_channel_mode = preset->num_channel_mode;
872 spec->need_dac_fix = preset->need_dac_fix;
873 spec->const_channel_count = preset->const_channel_count;
874
875 if (preset->const_channel_count)
876 spec->multiout.max_channels = preset->const_channel_count;
877 else
878 spec->multiout.max_channels = spec->channel_mode[0].channels;
879 spec->ext_channel_count = spec->channel_mode[0].channels;
880
881 spec->multiout.num_dacs = preset->num_dacs;
882 spec->multiout.dac_nids = preset->dac_nids;
883 spec->multiout.dig_out_nid = preset->dig_out_nid;
884 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
885 spec->multiout.hp_nid = preset->hp_nid;
886
887 spec->num_mux_defs = preset->num_mux_defs;
888 if (!spec->num_mux_defs)
889 spec->num_mux_defs = 1;
890 spec->input_mux = preset->input_mux;
891
892 spec->num_adc_nids = preset->num_adc_nids;
893 spec->adc_nids = preset->adc_nids;
894 spec->capsrc_nids = preset->capsrc_nids;
895 spec->dig_in_nid = preset->dig_in_nid;
896
897 spec->unsol_event = preset->unsol_event;
898 spec->init_hook = preset->init_hook;
899#ifdef CONFIG_SND_HDA_POWER_SAVE
900 spec->loopback.amplist = preset->loopbacks;
901#endif
902
903 if (preset->setup)
904 preset->setup(codec);
905}
906
907/* Enable GPIO mask and set output */
908static struct hda_verb alc_gpio1_init_verbs[] = {
909 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
910 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
911 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
912 { }
913};
914
915static struct hda_verb alc_gpio2_init_verbs[] = {
916 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
917 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
918 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
919 { }
920};
921
922static struct hda_verb alc_gpio3_init_verbs[] = {
923 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
924 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
925 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
926 { }
927};
928
929/*
930 * Fix hardware PLL issue
931 * On some codecs, the analog PLL gating control must be off while
932 * the default value is 1.
933 */
934static void alc_fix_pll(struct hda_codec *codec)
935{
936 struct alc_spec *spec = codec->spec;
937 unsigned int val;
938
939 if (!spec->pll_nid)
940 return;
941 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
942 spec->pll_coef_idx);
943 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
944 AC_VERB_GET_PROC_COEF, 0);
945 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
946 spec->pll_coef_idx);
947 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
948 val & ~(1 << spec->pll_coef_bit));
949}
950
951static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
952 unsigned int coef_idx, unsigned int coef_bit)
953{
954 struct alc_spec *spec = codec->spec;
955 spec->pll_nid = nid;
956 spec->pll_coef_idx = coef_idx;
957 spec->pll_coef_bit = coef_bit;
958 alc_fix_pll(codec);
959}
960
961static void alc_automute_pin(struct hda_codec *codec)
962{
963 struct alc_spec *spec = codec->spec;
964 unsigned int nid = spec->autocfg.hp_pins[0];
965 int i;
966
967 if (!nid)
968 return;
969 spec->jack_present = snd_hda_jack_detect(codec, nid);
970 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
971 nid = spec->autocfg.speaker_pins[i];
972 if (!nid)
973 break;
974 snd_hda_codec_write(codec, nid, 0,
975 AC_VERB_SET_PIN_WIDGET_CONTROL,
976 spec->jack_present ? 0 : PIN_OUT);
977 }
978}
979
980static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
981 hda_nid_t nid)
982{
983 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
984 int i, nums;
985
986 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
987 for (i = 0; i < nums; i++)
988 if (conn[i] == nid)
989 return i;
990 return -1;
991}
992
993static void alc_mic_automute(struct hda_codec *codec)
994{
995 struct alc_spec *spec = codec->spec;
996 struct alc_mic_route *dead, *alive;
997 unsigned int present, type;
998 hda_nid_t cap_nid;
999
1000 if (!spec->auto_mic)
1001 return;
1002 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1003 return;
1004 if (snd_BUG_ON(!spec->adc_nids))
1005 return;
1006
1007 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1008
1009 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1010 if (present) {
1011 alive = &spec->ext_mic;
1012 dead = &spec->int_mic;
1013 } else {
1014 alive = &spec->int_mic;
1015 dead = &spec->ext_mic;
1016 }
1017
1018 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1019 if (type == AC_WID_AUD_MIX) {
1020 /* Matrix-mixer style (e.g. ALC882) */
1021 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1022 alive->mux_idx,
1023 HDA_AMP_MUTE, 0);
1024 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1025 dead->mux_idx,
1026 HDA_AMP_MUTE, HDA_AMP_MUTE);
1027 } else {
1028 /* MUX style (e.g. ALC880) */
1029 snd_hda_codec_write_cache(codec, cap_nid, 0,
1030 AC_VERB_SET_CONNECT_SEL,
1031 alive->mux_idx);
1032 }
1033
1034 /* FIXME: analog mixer */
1035}
1036
1037/* unsolicited event for HP jack sensing */
1038static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1039{
1040 if (codec->vendor_id == 0x10ec0880)
1041 res >>= 28;
1042 else
1043 res >>= 26;
1044 switch (res) {
1045 case ALC880_HP_EVENT:
1046 alc_automute_pin(codec);
1047 break;
1048 case ALC880_MIC_EVENT:
1049 alc_mic_automute(codec);
1050 break;
1051 }
1052}
1053
1054static void alc_inithook(struct hda_codec *codec)
1055{
1056 alc_automute_pin(codec);
1057 alc_mic_automute(codec);
1058}
1059
1060/* additional initialization for ALC888 variants */
1061static void alc888_coef_init(struct hda_codec *codec)
1062{
1063 unsigned int tmp;
1064
1065 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1066 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1067 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1068 if ((tmp & 0xf0) == 0x20)
1069 /* alc888S-VC */
1070 snd_hda_codec_read(codec, 0x20, 0,
1071 AC_VERB_SET_PROC_COEF, 0x830);
1072 else
1073 /* alc888-VB */
1074 snd_hda_codec_read(codec, 0x20, 0,
1075 AC_VERB_SET_PROC_COEF, 0x3030);
1076}
1077
1078static void alc889_coef_init(struct hda_codec *codec)
1079{
1080 unsigned int tmp;
1081
1082 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1083 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1084 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1085 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1086}
1087
1088static void alc_auto_init_amp(struct hda_codec *codec, int type)
1089{
1090 unsigned int tmp;
1091
1092 switch (type) {
1093 case ALC_INIT_GPIO1:
1094 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1095 break;
1096 case ALC_INIT_GPIO2:
1097 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1098 break;
1099 case ALC_INIT_GPIO3:
1100 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1101 break;
1102 case ALC_INIT_DEFAULT:
1103 switch (codec->vendor_id) {
1104 case 0x10ec0260:
1105 snd_hda_codec_write(codec, 0x0f, 0,
1106 AC_VERB_SET_EAPD_BTLENABLE, 2);
1107 snd_hda_codec_write(codec, 0x10, 0,
1108 AC_VERB_SET_EAPD_BTLENABLE, 2);
1109 break;
1110 case 0x10ec0262:
1111 case 0x10ec0267:
1112 case 0x10ec0268:
1113 case 0x10ec0269:
1114 case 0x10ec0272:
1115 case 0x10ec0660:
1116 case 0x10ec0662:
1117 case 0x10ec0663:
1118 case 0x10ec0862:
1119 case 0x10ec0889:
1120 snd_hda_codec_write(codec, 0x14, 0,
1121 AC_VERB_SET_EAPD_BTLENABLE, 2);
1122 snd_hda_codec_write(codec, 0x15, 0,
1123 AC_VERB_SET_EAPD_BTLENABLE, 2);
1124 break;
1125 }
1126 switch (codec->vendor_id) {
1127 case 0x10ec0260:
1128 snd_hda_codec_write(codec, 0x1a, 0,
1129 AC_VERB_SET_COEF_INDEX, 7);
1130 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1131 AC_VERB_GET_PROC_COEF, 0);
1132 snd_hda_codec_write(codec, 0x1a, 0,
1133 AC_VERB_SET_COEF_INDEX, 7);
1134 snd_hda_codec_write(codec, 0x1a, 0,
1135 AC_VERB_SET_PROC_COEF,
1136 tmp | 0x2010);
1137 break;
1138 case 0x10ec0262:
1139 case 0x10ec0880:
1140 case 0x10ec0882:
1141 case 0x10ec0883:
1142 case 0x10ec0885:
1143 case 0x10ec0887:
1144 case 0x10ec0889:
1145 alc889_coef_init(codec);
1146 break;
1147 case 0x10ec0888:
1148 alc888_coef_init(codec);
1149 break;
1150 case 0x10ec0267:
1151 case 0x10ec0268:
1152 snd_hda_codec_write(codec, 0x20, 0,
1153 AC_VERB_SET_COEF_INDEX, 7);
1154 tmp = snd_hda_codec_read(codec, 0x20, 0,
1155 AC_VERB_GET_PROC_COEF, 0);
1156 snd_hda_codec_write(codec, 0x20, 0,
1157 AC_VERB_SET_COEF_INDEX, 7);
1158 snd_hda_codec_write(codec, 0x20, 0,
1159 AC_VERB_SET_PROC_COEF,
1160 tmp | 0x3000);
1161 break;
1162 }
1163 break;
1164 }
1165}
1166
1167static void alc_init_auto_hp(struct hda_codec *codec)
1168{
1169 struct alc_spec *spec = codec->spec;
1170
1171 if (!spec->autocfg.hp_pins[0])
1172 return;
1173
1174 if (!spec->autocfg.speaker_pins[0]) {
1175 if (spec->autocfg.line_out_pins[0] &&
1176 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1177 spec->autocfg.speaker_pins[0] =
1178 spec->autocfg.line_out_pins[0];
1179 else
1180 return;
1181 }
1182
1183 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1184 spec->autocfg.hp_pins[0]);
1185 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1186 AC_VERB_SET_UNSOLICITED_ENABLE,
1187 AC_USRSP_EN | ALC880_HP_EVENT);
1188 spec->unsol_event = alc_sku_unsol_event;
1189}
1190
1191static void alc_init_auto_mic(struct hda_codec *codec)
1192{
1193 struct alc_spec *spec = codec->spec;
1194 struct auto_pin_cfg *cfg = &spec->autocfg;
1195 hda_nid_t fixed, ext;
1196 int i;
1197
1198 /* there must be only two mic inputs exclusively */
1199 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1200 if (cfg->input_pins[i])
1201 return;
1202
1203 fixed = ext = 0;
1204 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1205 hda_nid_t nid = cfg->input_pins[i];
1206 unsigned int defcfg;
1207 if (!nid)
1208 return;
1209 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1210 switch (get_defcfg_connect(defcfg)) {
1211 case AC_JACK_PORT_FIXED:
1212 if (fixed)
1213 return; /* already occupied */
1214 fixed = nid;
1215 break;
1216 case AC_JACK_PORT_COMPLEX:
1217 if (ext)
1218 return; /* already occupied */
1219 ext = nid;
1220 break;
1221 default:
1222 return; /* invalid entry */
1223 }
1224 }
1225 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1226 return; /* no unsol support */
1227 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1228 ext, fixed);
1229 spec->ext_mic.pin = ext;
1230 spec->int_mic.pin = fixed;
1231 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1232 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1233 spec->auto_mic = 1;
1234 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1235 AC_VERB_SET_UNSOLICITED_ENABLE,
1236 AC_USRSP_EN | ALC880_MIC_EVENT);
1237 spec->unsol_event = alc_sku_unsol_event;
1238}
1239
1240/* check subsystem ID and set up device-specific initialization;
1241 * return 1 if initialized, 0 if invalid SSID
1242 */
1243/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1244 * 31 ~ 16 : Manufacture ID
1245 * 15 ~ 8 : SKU ID
1246 * 7 ~ 0 : Assembly ID
1247 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1248 */
1249static int alc_subsystem_id(struct hda_codec *codec,
1250 hda_nid_t porta, hda_nid_t porte,
1251 hda_nid_t portd)
1252{
1253 unsigned int ass, tmp, i;
1254 unsigned nid;
1255 struct alc_spec *spec = codec->spec;
1256
1257 ass = codec->subsystem_id & 0xffff;
1258 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1259 goto do_sku;
1260
1261 /* invalid SSID, check the special NID pin defcfg instead */
1262 /*
1263 * 31~30 : port connectivity
1264 * 29~21 : reserve
1265 * 20 : PCBEEP input
1266 * 19~16 : Check sum (15:1)
1267 * 15~1 : Custom
1268 * 0 : override
1269 */
1270 nid = 0x1d;
1271 if (codec->vendor_id == 0x10ec0260)
1272 nid = 0x17;
1273 ass = snd_hda_codec_get_pincfg(codec, nid);
1274 snd_printd("realtek: No valid SSID, "
1275 "checking pincfg 0x%08x for NID 0x%x\n",
1276 ass, nid);
1277 if (!(ass & 1) && !(ass & 0x100000))
1278 return 0;
1279 if ((ass >> 30) != 1) /* no physical connection */
1280 return 0;
1281
1282 /* check sum */
1283 tmp = 0;
1284 for (i = 1; i < 16; i++) {
1285 if ((ass >> i) & 1)
1286 tmp++;
1287 }
1288 if (((ass >> 16) & 0xf) != tmp)
1289 return 0;
1290do_sku:
1291 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1292 ass & 0xffff, codec->vendor_id);
1293 /*
1294 * 0 : override
1295 * 1 : Swap Jack
1296 * 2 : 0 --> Desktop, 1 --> Laptop
1297 * 3~5 : External Amplifier control
1298 * 7~6 : Reserved
1299 */
1300 tmp = (ass & 0x38) >> 3; /* external Amp control */
1301 switch (tmp) {
1302 case 1:
1303 spec->init_amp = ALC_INIT_GPIO1;
1304 break;
1305 case 3:
1306 spec->init_amp = ALC_INIT_GPIO2;
1307 break;
1308 case 7:
1309 spec->init_amp = ALC_INIT_GPIO3;
1310 break;
1311 case 5:
1312 spec->init_amp = ALC_INIT_DEFAULT;
1313 break;
1314 }
1315
1316 /* is laptop or Desktop and enable the function "Mute internal speaker
1317 * when the external headphone out jack is plugged"
1318 */
1319 if (!(ass & 0x8000))
1320 return 1;
1321 /*
1322 * 10~8 : Jack location
1323 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1324 * 14~13: Resvered
1325 * 15 : 1 --> enable the function "Mute internal speaker
1326 * when the external headphone out jack is plugged"
1327 */
1328 if (!spec->autocfg.hp_pins[0]) {
1329 hda_nid_t nid;
1330 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1331 if (tmp == 0)
1332 nid = porta;
1333 else if (tmp == 1)
1334 nid = porte;
1335 else if (tmp == 2)
1336 nid = portd;
1337 else
1338 return 1;
1339 for (i = 0; i < spec->autocfg.line_outs; i++)
1340 if (spec->autocfg.line_out_pins[i] == nid)
1341 return 1;
1342 spec->autocfg.hp_pins[0] = nid;
1343 }
1344
1345 alc_init_auto_hp(codec);
1346 alc_init_auto_mic(codec);
1347 return 1;
1348}
1349
1350static void alc_ssid_check(struct hda_codec *codec,
1351 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1352{
1353 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1354 struct alc_spec *spec = codec->spec;
1355 snd_printd("realtek: "
1356 "Enable default setup for auto mode as fallback\n");
1357 spec->init_amp = ALC_INIT_DEFAULT;
1358 alc_init_auto_hp(codec);
1359 alc_init_auto_mic(codec);
1360 }
1361}
1362
1363/*
1364 * Fix-up pin default configurations and add default verbs
1365 */
1366
1367struct alc_pincfg {
1368 hda_nid_t nid;
1369 u32 val;
1370};
1371
1372struct alc_fixup {
1373 const struct alc_pincfg *pins;
1374 const struct hda_verb *verbs;
1375};
1376
1377static void alc_pick_fixup(struct hda_codec *codec,
1378 const struct snd_pci_quirk *quirk,
1379 const struct alc_fixup *fix)
1380{
1381 const struct alc_pincfg *cfg;
1382
1383 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1384 if (!quirk)
1385 return;
1386
1387 fix += quirk->value;
1388 cfg = fix->pins;
1389 if (cfg) {
1390 for (; cfg->nid; cfg++)
1391 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1392 }
1393 if (fix->verbs)
1394 add_verb(codec->spec, fix->verbs);
1395}
1396
1397/*
1398 * ALC888
1399 */
1400
1401/*
1402 * 2ch mode
1403 */
1404static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1405/* Mic-in jack as mic in */
1406 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1407 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1408/* Line-in jack as Line in */
1409 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1410 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1411/* Line-Out as Front */
1412 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1413 { } /* end */
1414};
1415
1416/*
1417 * 4ch mode
1418 */
1419static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1420/* Mic-in jack as mic in */
1421 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1422 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1423/* Line-in jack as Surround */
1424 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1425 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1426/* Line-Out as Front */
1427 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1428 { } /* end */
1429};
1430
1431/*
1432 * 6ch mode
1433 */
1434static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1435/* Mic-in jack as CLFE */
1436 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1437 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1438/* Line-in jack as Surround */
1439 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1440 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1441/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1442 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1443 { } /* end */
1444};
1445
1446/*
1447 * 8ch mode
1448 */
1449static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1450/* Mic-in jack as CLFE */
1451 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1452 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1453/* Line-in jack as Surround */
1454 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1455 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1456/* Line-Out as Side */
1457 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1458 { } /* end */
1459};
1460
1461static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1462 { 2, alc888_4ST_ch2_intel_init },
1463 { 4, alc888_4ST_ch4_intel_init },
1464 { 6, alc888_4ST_ch6_intel_init },
1465 { 8, alc888_4ST_ch8_intel_init },
1466};
1467
1468/*
1469 * ALC888 Fujitsu Siemens Amillo xa3530
1470 */
1471
1472static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1473/* Front Mic: set to PIN_IN (empty by default) */
1474 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1475/* Connect Internal HP to Front */
1476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1478 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1479/* Connect Bass HP to Front */
1480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1483/* Connect Line-Out side jack (SPDIF) to Side */
1484 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1485 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1486 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1487/* Connect Mic jack to CLFE */
1488 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1489 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1490 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1491/* Connect Line-in jack to Surround */
1492 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1493 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1494 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1495/* Connect HP out jack to Front */
1496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1499/* Enable unsolicited event for HP jack and Line-out jack */
1500 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1501 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1502 {}
1503};
1504
1505static void alc_automute_amp(struct hda_codec *codec)
1506{
1507 struct alc_spec *spec = codec->spec;
1508 unsigned int mute;
1509 hda_nid_t nid;
1510 int i;
1511
1512 spec->jack_present = 0;
1513 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1514 nid = spec->autocfg.hp_pins[i];
1515 if (!nid)
1516 break;
1517 if (snd_hda_jack_detect(codec, nid)) {
1518 spec->jack_present = 1;
1519 break;
1520 }
1521 }
1522
1523 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1524 /* Toggle internal speakers muting */
1525 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1526 nid = spec->autocfg.speaker_pins[i];
1527 if (!nid)
1528 break;
1529 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1530 HDA_AMP_MUTE, mute);
1531 }
1532}
1533
1534static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1535 unsigned int res)
1536{
1537 if (codec->vendor_id == 0x10ec0880)
1538 res >>= 28;
1539 else
1540 res >>= 26;
1541 if (res == ALC880_HP_EVENT)
1542 alc_automute_amp(codec);
1543}
1544
1545static void alc889_automute_setup(struct hda_codec *codec)
1546{
1547 struct alc_spec *spec = codec->spec;
1548
1549 spec->autocfg.hp_pins[0] = 0x15;
1550 spec->autocfg.speaker_pins[0] = 0x14;
1551 spec->autocfg.speaker_pins[1] = 0x16;
1552 spec->autocfg.speaker_pins[2] = 0x17;
1553 spec->autocfg.speaker_pins[3] = 0x19;
1554 spec->autocfg.speaker_pins[4] = 0x1a;
1555}
1556
1557static void alc889_intel_init_hook(struct hda_codec *codec)
1558{
1559 alc889_coef_init(codec);
1560 alc_automute_amp(codec);
1561}
1562
1563static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1564{
1565 struct alc_spec *spec = codec->spec;
1566
1567 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1568 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1569 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1570 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1571}
1572
1573/*
1574 * ALC888 Acer Aspire 4930G model
1575 */
1576
1577static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1578/* Front Mic: set to PIN_IN (empty by default) */
1579 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1580/* Unselect Front Mic by default in input mixer 3 */
1581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1582/* Enable unsolicited event for HP jack */
1583 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1584/* Connect Internal HP to front */
1585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1587 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1588/* Connect HP out to front */
1589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1592 { }
1593};
1594
1595/*
1596 * ALC888 Acer Aspire 6530G model
1597 */
1598
1599static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1600/* Bias voltage on for external mic port */
1601 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1602/* Front Mic: set to PIN_IN (empty by default) */
1603 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1604/* Unselect Front Mic by default in input mixer 3 */
1605 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1606/* Enable unsolicited event for HP jack */
1607 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1608/* Enable speaker output */
1609 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1610 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1611/* Enable headphone output */
1612 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1614 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1615 { }
1616};
1617
1618/*
1619 * ALC889 Acer Aspire 8930G model
1620 */
1621
1622static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1623/* Front Mic: set to PIN_IN (empty by default) */
1624 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1625/* Unselect Front Mic by default in input mixer 3 */
1626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1627/* Enable unsolicited event for HP jack */
1628 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1629/* Connect Internal Front to Front */
1630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1631 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1632 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1633/* Connect Internal Rear to Rear */
1634 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1635 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1636 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1637/* Connect Internal CLFE to CLFE */
1638 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1639 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1640 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1641/* Connect HP out to Front */
1642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1645/* Enable all DACs */
1646/* DAC DISABLE/MUTE 1? */
1647/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1648 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1649 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1650/* DAC DISABLE/MUTE 2? */
1651/* some bit here disables the other DACs. Init=0x4900 */
1652 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1653 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1654/* Enable amplifiers */
1655 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1656 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1657/* DMIC fix
1658 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1659 * which makes the stereo useless. However, either the mic or the ALC889
1660 * makes the signal become a difference/sum signal instead of standard
1661 * stereo, which is annoying. So instead we flip this bit which makes the
1662 * codec replicate the sum signal to both channels, turning it into a
1663 * normal mono mic.
1664 */
1665/* DMIC_CONTROL? Init value = 0x0001 */
1666 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1667 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1668 { }
1669};
1670
1671static struct hda_input_mux alc888_2_capture_sources[2] = {
1672 /* Front mic only available on one ADC */
1673 {
1674 .num_items = 4,
1675 .items = {
1676 { "Mic", 0x0 },
1677 { "Line", 0x2 },
1678 { "CD", 0x4 },
1679 { "Front Mic", 0xb },
1680 },
1681 },
1682 {
1683 .num_items = 3,
1684 .items = {
1685 { "Mic", 0x0 },
1686 { "Line", 0x2 },
1687 { "CD", 0x4 },
1688 },
1689 }
1690};
1691
1692static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1693 /* Interal mic only available on one ADC */
1694 {
1695 .num_items = 5,
1696 .items = {
1697 { "Ext Mic", 0x0 },
1698 { "Line In", 0x2 },
1699 { "CD", 0x4 },
1700 { "Input Mix", 0xa },
1701 { "Int Mic", 0xb },
1702 },
1703 },
1704 {
1705 .num_items = 4,
1706 .items = {
1707 { "Ext Mic", 0x0 },
1708 { "Line In", 0x2 },
1709 { "CD", 0x4 },
1710 { "Input Mix", 0xa },
1711 },
1712 }
1713};
1714
1715static struct hda_input_mux alc889_capture_sources[3] = {
1716 /* Digital mic only available on first "ADC" */
1717 {
1718 .num_items = 5,
1719 .items = {
1720 { "Mic", 0x0 },
1721 { "Line", 0x2 },
1722 { "CD", 0x4 },
1723 { "Front Mic", 0xb },
1724 { "Input Mix", 0xa },
1725 },
1726 },
1727 {
1728 .num_items = 4,
1729 .items = {
1730 { "Mic", 0x0 },
1731 { "Line", 0x2 },
1732 { "CD", 0x4 },
1733 { "Input Mix", 0xa },
1734 },
1735 },
1736 {
1737 .num_items = 4,
1738 .items = {
1739 { "Mic", 0x0 },
1740 { "Line", 0x2 },
1741 { "CD", 0x4 },
1742 { "Input Mix", 0xa },
1743 },
1744 }
1745};
1746
1747static struct snd_kcontrol_new alc888_base_mixer[] = {
1748 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1749 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1750 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1751 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1752 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1753 HDA_OUTPUT),
1754 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1755 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1756 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1757 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1758 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1759 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1760 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1761 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1762 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1764 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1766 { } /* end */
1767};
1768
1769static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1770{
1771 struct alc_spec *spec = codec->spec;
1772
1773 spec->autocfg.hp_pins[0] = 0x15;
1774 spec->autocfg.speaker_pins[0] = 0x14;
1775 spec->autocfg.speaker_pins[1] = 0x16;
1776 spec->autocfg.speaker_pins[2] = 0x17;
1777}
1778
1779static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1780{
1781 struct alc_spec *spec = codec->spec;
1782
1783 spec->autocfg.hp_pins[0] = 0x15;
1784 spec->autocfg.speaker_pins[0] = 0x14;
1785 spec->autocfg.speaker_pins[1] = 0x16;
1786 spec->autocfg.speaker_pins[2] = 0x17;
1787}
1788
1789static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1790{
1791 struct alc_spec *spec = codec->spec;
1792
1793 spec->autocfg.hp_pins[0] = 0x15;
1794 spec->autocfg.speaker_pins[0] = 0x14;
1795 spec->autocfg.speaker_pins[1] = 0x16;
1796 spec->autocfg.speaker_pins[2] = 0x1b;
1797}
1798
1799/*
1800 * ALC880 3-stack model
1801 *
1802 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1803 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1804 * F-Mic = 0x1b, HP = 0x19
1805 */
1806
1807static hda_nid_t alc880_dac_nids[4] = {
1808 /* front, rear, clfe, rear_surr */
1809 0x02, 0x05, 0x04, 0x03
1810};
1811
1812static hda_nid_t alc880_adc_nids[3] = {
1813 /* ADC0-2 */
1814 0x07, 0x08, 0x09,
1815};
1816
1817/* The datasheet says the node 0x07 is connected from inputs,
1818 * but it shows zero connection in the real implementation on some devices.
1819 * Note: this is a 915GAV bug, fixed on 915GLV
1820 */
1821static hda_nid_t alc880_adc_nids_alt[2] = {
1822 /* ADC1-2 */
1823 0x08, 0x09,
1824};
1825
1826#define ALC880_DIGOUT_NID 0x06
1827#define ALC880_DIGIN_NID 0x0a
1828
1829static struct hda_input_mux alc880_capture_source = {
1830 .num_items = 4,
1831 .items = {
1832 { "Mic", 0x0 },
1833 { "Front Mic", 0x3 },
1834 { "Line", 0x2 },
1835 { "CD", 0x4 },
1836 },
1837};
1838
1839/* channel source setting (2/6 channel selection for 3-stack) */
1840/* 2ch mode */
1841static struct hda_verb alc880_threestack_ch2_init[] = {
1842 /* set line-in to input, mute it */
1843 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1844 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1845 /* set mic-in to input vref 80%, mute it */
1846 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1847 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1848 { } /* end */
1849};
1850
1851/* 6ch mode */
1852static struct hda_verb alc880_threestack_ch6_init[] = {
1853 /* set line-in to output, unmute it */
1854 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1855 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1856 /* set mic-in to output, unmute it */
1857 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1858 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1859 { } /* end */
1860};
1861
1862static struct hda_channel_mode alc880_threestack_modes[2] = {
1863 { 2, alc880_threestack_ch2_init },
1864 { 6, alc880_threestack_ch6_init },
1865};
1866
1867static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1868 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1869 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1870 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1871 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1872 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1873 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1874 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1875 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1876 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1877 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1878 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1879 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1882 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1883 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1884 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1885 {
1886 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1887 .name = "Channel Mode",
1888 .info = alc_ch_mode_info,
1889 .get = alc_ch_mode_get,
1890 .put = alc_ch_mode_put,
1891 },
1892 { } /* end */
1893};
1894
1895/* capture mixer elements */
1896static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1897 struct snd_ctl_elem_info *uinfo)
1898{
1899 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1900 struct alc_spec *spec = codec->spec;
1901 int err;
1902
1903 mutex_lock(&codec->control_mutex);
1904 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1905 HDA_INPUT);
1906 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1907 mutex_unlock(&codec->control_mutex);
1908 return err;
1909}
1910
1911static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1912 unsigned int size, unsigned int __user *tlv)
1913{
1914 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1915 struct alc_spec *spec = codec->spec;
1916 int err;
1917
1918 mutex_lock(&codec->control_mutex);
1919 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1920 HDA_INPUT);
1921 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1922 mutex_unlock(&codec->control_mutex);
1923 return err;
1924}
1925
1926typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol);
1928
1929static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1930 struct snd_ctl_elem_value *ucontrol,
1931 getput_call_t func)
1932{
1933 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1934 struct alc_spec *spec = codec->spec;
1935 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1936 int err;
1937
1938 mutex_lock(&codec->control_mutex);
1939 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1940 3, 0, HDA_INPUT);
1941 err = func(kcontrol, ucontrol);
1942 mutex_unlock(&codec->control_mutex);
1943 return err;
1944}
1945
1946static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1947 struct snd_ctl_elem_value *ucontrol)
1948{
1949 return alc_cap_getput_caller(kcontrol, ucontrol,
1950 snd_hda_mixer_amp_volume_get);
1951}
1952
1953static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1954 struct snd_ctl_elem_value *ucontrol)
1955{
1956 return alc_cap_getput_caller(kcontrol, ucontrol,
1957 snd_hda_mixer_amp_volume_put);
1958}
1959
1960/* capture mixer elements */
1961#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1962
1963static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1964 struct snd_ctl_elem_value *ucontrol)
1965{
1966 return alc_cap_getput_caller(kcontrol, ucontrol,
1967 snd_hda_mixer_amp_switch_get);
1968}
1969
1970static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1971 struct snd_ctl_elem_value *ucontrol)
1972{
1973 return alc_cap_getput_caller(kcontrol, ucontrol,
1974 snd_hda_mixer_amp_switch_put);
1975}
1976
1977#define _DEFINE_CAPMIX(num) \
1978 { \
1979 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1980 .name = "Capture Switch", \
1981 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1982 .count = num, \
1983 .info = alc_cap_sw_info, \
1984 .get = alc_cap_sw_get, \
1985 .put = alc_cap_sw_put, \
1986 }, \
1987 { \
1988 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1989 .name = "Capture Volume", \
1990 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1991 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1992 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1993 .count = num, \
1994 .info = alc_cap_vol_info, \
1995 .get = alc_cap_vol_get, \
1996 .put = alc_cap_vol_put, \
1997 .tlv = { .c = alc_cap_vol_tlv }, \
1998 }
1999
2000#define _DEFINE_CAPSRC(num) \
2001 { \
2002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2003 /* .name = "Capture Source", */ \
2004 .name = "Input Source", \
2005 .count = num, \
2006 .info = alc_mux_enum_info, \
2007 .get = alc_mux_enum_get, \
2008 .put = alc_mux_enum_put, \
2009 }
2010
2011#define DEFINE_CAPMIX(num) \
2012static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2013 _DEFINE_CAPMIX(num), \
2014 _DEFINE_CAPSRC(num), \
2015 { } /* end */ \
2016}
2017
2018#define DEFINE_CAPMIX_NOSRC(num) \
2019static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2020 _DEFINE_CAPMIX(num), \
2021 { } /* end */ \
2022}
2023
2024/* up to three ADCs */
2025DEFINE_CAPMIX(1);
2026DEFINE_CAPMIX(2);
2027DEFINE_CAPMIX(3);
2028DEFINE_CAPMIX_NOSRC(1);
2029DEFINE_CAPMIX_NOSRC(2);
2030DEFINE_CAPMIX_NOSRC(3);
2031
2032/*
2033 * ALC880 5-stack model
2034 *
2035 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2036 * Side = 0x02 (0xd)
2037 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2038 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2039 */
2040
2041/* additional mixers to alc880_three_stack_mixer */
2042static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2043 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2044 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2045 { } /* end */
2046};
2047
2048/* channel source setting (6/8 channel selection for 5-stack) */
2049/* 6ch mode */
2050static struct hda_verb alc880_fivestack_ch6_init[] = {
2051 /* set line-in to input, mute it */
2052 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2053 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2054 { } /* end */
2055};
2056
2057/* 8ch mode */
2058static struct hda_verb alc880_fivestack_ch8_init[] = {
2059 /* set line-in to output, unmute it */
2060 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2061 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2062 { } /* end */
2063};
2064
2065static struct hda_channel_mode alc880_fivestack_modes[2] = {
2066 { 6, alc880_fivestack_ch6_init },
2067 { 8, alc880_fivestack_ch8_init },
2068};
2069
2070
2071/*
2072 * ALC880 6-stack model
2073 *
2074 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2075 * Side = 0x05 (0x0f)
2076 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2077 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2078 */
2079
2080static hda_nid_t alc880_6st_dac_nids[4] = {
2081 /* front, rear, clfe, rear_surr */
2082 0x02, 0x03, 0x04, 0x05
2083};
2084
2085static struct hda_input_mux alc880_6stack_capture_source = {
2086 .num_items = 4,
2087 .items = {
2088 { "Mic", 0x0 },
2089 { "Front Mic", 0x1 },
2090 { "Line", 0x2 },
2091 { "CD", 0x4 },
2092 },
2093};
2094
2095/* fixed 8-channels */
2096static struct hda_channel_mode alc880_sixstack_modes[1] = {
2097 { 8, NULL },
2098};
2099
2100static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2102 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2103 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2104 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2105 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2106 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2107 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2108 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2110 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2111 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2112 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2114 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2117 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2118 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2119 {
2120 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2121 .name = "Channel Mode",
2122 .info = alc_ch_mode_info,
2123 .get = alc_ch_mode_get,
2124 .put = alc_ch_mode_put,
2125 },
2126 { } /* end */
2127};
2128
2129
2130/*
2131 * ALC880 W810 model
2132 *
2133 * W810 has rear IO for:
2134 * Front (DAC 02)
2135 * Surround (DAC 03)
2136 * Center/LFE (DAC 04)
2137 * Digital out (06)
2138 *
2139 * The system also has a pair of internal speakers, and a headphone jack.
2140 * These are both connected to Line2 on the codec, hence to DAC 02.
2141 *
2142 * There is a variable resistor to control the speaker or headphone
2143 * volume. This is a hardware-only device without a software API.
2144 *
2145 * Plugging headphones in will disable the internal speakers. This is
2146 * implemented in hardware, not via the driver using jack sense. In
2147 * a similar fashion, plugging into the rear socket marked "front" will
2148 * disable both the speakers and headphones.
2149 *
2150 * For input, there's a microphone jack, and an "audio in" jack.
2151 * These may not do anything useful with this driver yet, because I
2152 * haven't setup any initialization verbs for these yet...
2153 */
2154
2155static hda_nid_t alc880_w810_dac_nids[3] = {
2156 /* front, rear/surround, clfe */
2157 0x02, 0x03, 0x04
2158};
2159
2160/* fixed 6 channels */
2161static struct hda_channel_mode alc880_w810_modes[1] = {
2162 { 6, NULL }
2163};
2164
2165/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2166static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2167 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2168 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2169 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2170 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2171 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2172 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2173 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2174 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2175 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2176 { } /* end */
2177};
2178
2179
2180/*
2181 * Z710V model
2182 *
2183 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2184 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2185 * Line = 0x1a
2186 */
2187
2188static hda_nid_t alc880_z71v_dac_nids[1] = {
2189 0x02
2190};
2191#define ALC880_Z71V_HP_DAC 0x03
2192
2193/* fixed 2 channels */
2194static struct hda_channel_mode alc880_2_jack_modes[1] = {
2195 { 2, NULL }
2196};
2197
2198static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2199 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2200 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2201 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2202 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2203 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2204 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2205 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2207 { } /* end */
2208};
2209
2210
2211/*
2212 * ALC880 F1734 model
2213 *
2214 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2215 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2216 */
2217
2218static hda_nid_t alc880_f1734_dac_nids[1] = {
2219 0x03
2220};
2221#define ALC880_F1734_HP_DAC 0x02
2222
2223static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2224 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2225 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2226 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2228 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2229 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2231 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2232 { } /* end */
2233};
2234
2235static struct hda_input_mux alc880_f1734_capture_source = {
2236 .num_items = 2,
2237 .items = {
2238 { "Mic", 0x1 },
2239 { "CD", 0x4 },
2240 },
2241};
2242
2243
2244/*
2245 * ALC880 ASUS model
2246 *
2247 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2248 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2249 * Mic = 0x18, Line = 0x1a
2250 */
2251
2252#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2253#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2254
2255static struct snd_kcontrol_new alc880_asus_mixer[] = {
2256 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2257 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2258 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2259 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2260 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2261 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2262 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2263 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2264 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2265 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2266 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2267 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2268 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2269 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2270 {
2271 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2272 .name = "Channel Mode",
2273 .info = alc_ch_mode_info,
2274 .get = alc_ch_mode_get,
2275 .put = alc_ch_mode_put,
2276 },
2277 { } /* end */
2278};
2279
2280/*
2281 * ALC880 ASUS W1V model
2282 *
2283 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2284 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2285 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2286 */
2287
2288/* additional mixers to alc880_asus_mixer */
2289static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2290 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2291 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2292 { } /* end */
2293};
2294
2295/* TCL S700 */
2296static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2297 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2298 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2301 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2303 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2304 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2305 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2306 { } /* end */
2307};
2308
2309/* Uniwill */
2310static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2311 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2312 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2313 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2314 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2315 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2316 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2317 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2318 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2319 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2320 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2321 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2322 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2325 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2326 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2327 {
2328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2329 .name = "Channel Mode",
2330 .info = alc_ch_mode_info,
2331 .get = alc_ch_mode_get,
2332 .put = alc_ch_mode_put,
2333 },
2334 { } /* end */
2335};
2336
2337static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2338 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2339 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2340 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2341 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2342 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2343 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2344 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2345 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2346 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2347 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2348 { } /* end */
2349};
2350
2351static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2352 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2353 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2354 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2355 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2358 { } /* end */
2359};
2360
2361/*
2362 * virtual master controls
2363 */
2364
2365/*
2366 * slave controls for virtual master
2367 */
2368static const char *alc_slave_vols[] = {
2369 "Front Playback Volume",
2370 "Surround Playback Volume",
2371 "Center Playback Volume",
2372 "LFE Playback Volume",
2373 "Side Playback Volume",
2374 "Headphone Playback Volume",
2375 "Speaker Playback Volume",
2376 "Mono Playback Volume",
2377 "Line-Out Playback Volume",
2378 "PCM Playback Volume",
2379 NULL,
2380};
2381
2382static const char *alc_slave_sws[] = {
2383 "Front Playback Switch",
2384 "Surround Playback Switch",
2385 "Center Playback Switch",
2386 "LFE Playback Switch",
2387 "Side Playback Switch",
2388 "Headphone Playback Switch",
2389 "Speaker Playback Switch",
2390 "Mono Playback Switch",
2391 "IEC958 Playback Switch",
2392 NULL,
2393};
2394
2395/*
2396 * build control elements
2397 */
2398
2399static void alc_free_kctls(struct hda_codec *codec);
2400
2401#ifdef CONFIG_SND_HDA_INPUT_BEEP
2402/* additional beep mixers; the actual parameters are overwritten at build */
2403static struct snd_kcontrol_new alc_beep_mixer[] = {
2404 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2405 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2406 { } /* end */
2407};
2408#endif
2409
2410static int alc_build_controls(struct hda_codec *codec)
2411{
2412 struct alc_spec *spec = codec->spec;
2413 int err;
2414 int i;
2415
2416 for (i = 0; i < spec->num_mixers; i++) {
2417 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2418 if (err < 0)
2419 return err;
2420 }
2421 if (spec->cap_mixer) {
2422 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2423 if (err < 0)
2424 return err;
2425 }
2426 if (spec->multiout.dig_out_nid) {
2427 err = snd_hda_create_spdif_out_ctls(codec,
2428 spec->multiout.dig_out_nid);
2429 if (err < 0)
2430 return err;
2431 if (!spec->no_analog) {
2432 err = snd_hda_create_spdif_share_sw(codec,
2433 &spec->multiout);
2434 if (err < 0)
2435 return err;
2436 spec->multiout.share_spdif = 1;
2437 }
2438 }
2439 if (spec->dig_in_nid) {
2440 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2441 if (err < 0)
2442 return err;
2443 }
2444
2445#ifdef CONFIG_SND_HDA_INPUT_BEEP
2446 /* create beep controls if needed */
2447 if (spec->beep_amp) {
2448 struct snd_kcontrol_new *knew;
2449 for (knew = alc_beep_mixer; knew->name; knew++) {
2450 struct snd_kcontrol *kctl;
2451 kctl = snd_ctl_new1(knew, codec);
2452 if (!kctl)
2453 return -ENOMEM;
2454 kctl->private_value = spec->beep_amp;
2455 err = snd_hda_ctl_add(codec,
2456 get_amp_nid_(spec->beep_amp), kctl);
2457 if (err < 0)
2458 return err;
2459 }
2460 }
2461#endif
2462
2463 /* if we have no master control, let's create it */
2464 if (!spec->no_analog &&
2465 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2466 unsigned int vmaster_tlv[4];
2467 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2468 HDA_OUTPUT, vmaster_tlv);
2469 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2470 vmaster_tlv, alc_slave_vols);
2471 if (err < 0)
2472 return err;
2473 }
2474 if (!spec->no_analog &&
2475 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2476 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2477 NULL, alc_slave_sws);
2478 if (err < 0)
2479 return err;
2480 }
2481
2482 alc_free_kctls(codec); /* no longer needed */
2483 return 0;
2484}
2485
2486
2487/*
2488 * initialize the codec volumes, etc
2489 */
2490
2491/*
2492 * generic initialization of ADC, input mixers and output mixers
2493 */
2494static struct hda_verb alc880_volume_init_verbs[] = {
2495 /*
2496 * Unmute ADC0-2 and set the default input to mic-in
2497 */
2498 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2500 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2501 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2502 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2503 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2504
2505 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2506 * mixer widget
2507 * Note: PASD motherboards uses the Line In 2 as the input for front
2508 * panel mic (mic 2)
2509 */
2510 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2511 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2512 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2513 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2514 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2516 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2518
2519 /*
2520 * Set up output mixers (0x0c - 0x0f)
2521 */
2522 /* set vol=0 to output mixers */
2523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2524 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2525 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2526 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2527 /* set up input amps for analog loopback */
2528 /* Amp Indices: DAC = 0, mixer = 1 */
2529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2530 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2531 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2533 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2534 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2535 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2536 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2537
2538 { }
2539};
2540
2541/*
2542 * 3-stack pin configuration:
2543 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2544 */
2545static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2546 /*
2547 * preset connection lists of input pins
2548 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2549 */
2550 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2551 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2552 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2553
2554 /*
2555 * Set pin mode and muting
2556 */
2557 /* set front pin widgets 0x14 for output */
2558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2559 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2560 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2561 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2562 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2563 /* Mic2 (as headphone out) for HP output */
2564 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2565 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2566 /* Line In pin widget for input */
2567 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2568 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2569 /* Line2 (as front mic) pin widget for input and vref at 80% */
2570 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2571 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2572 /* CD pin widget for input */
2573 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2574
2575 { }
2576};
2577
2578/*
2579 * 5-stack pin configuration:
2580 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2581 * line-in/side = 0x1a, f-mic = 0x1b
2582 */
2583static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2584 /*
2585 * preset connection lists of input pins
2586 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2587 */
2588 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2589 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2590
2591 /*
2592 * Set pin mode and muting
2593 */
2594 /* set pin widgets 0x14-0x17 for output */
2595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2596 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2597 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2598 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2599 /* unmute pins for output (no gain on this amp) */
2600 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2601 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2602 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2603 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2604
2605 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2606 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2607 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2608 /* Mic2 (as headphone out) for HP output */
2609 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2610 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2611 /* Line In pin widget for input */
2612 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2613 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2614 /* Line2 (as front mic) pin widget for input and vref at 80% */
2615 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2616 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2617 /* CD pin widget for input */
2618 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2619
2620 { }
2621};
2622
2623/*
2624 * W810 pin configuration:
2625 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2626 */
2627static struct hda_verb alc880_pin_w810_init_verbs[] = {
2628 /* hphone/speaker input selector: front DAC */
2629 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2630
2631 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2632 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2633 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2635 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2637
2638 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2639 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2640
2641 { }
2642};
2643
2644/*
2645 * Z71V pin configuration:
2646 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2647 */
2648static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2649 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2650 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2652 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2653
2654 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2655 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2657 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2658
2659 { }
2660};
2661
2662/*
2663 * 6-stack pin configuration:
2664 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2665 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2666 */
2667static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2668 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2669
2670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2671 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2672 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2673 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2674 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2675 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2676 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2677 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2678
2679 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2680 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2681 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2682 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2683 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2684 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2685 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2686 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2687 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2688
2689 { }
2690};
2691
2692/*
2693 * Uniwill pin configuration:
2694 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2695 * line = 0x1a
2696 */
2697static struct hda_verb alc880_uniwill_init_verbs[] = {
2698 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2699
2700 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2701 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2702 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2704 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2705 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2706 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2707 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2714
2715 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2716 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2717 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2718 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2720 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2721 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2722 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2723 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2724
2725 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2726 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2727
2728 { }
2729};
2730
2731/*
2732* Uniwill P53
2733* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2734 */
2735static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2736 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2737
2738 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2742 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2743 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2750
2751 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2752 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2753 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2754 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2755 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2756 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2757
2758 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2759 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2760
2761 { }
2762};
2763
2764static struct hda_verb alc880_beep_init_verbs[] = {
2765 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2766 { }
2767};
2768
2769/* auto-toggle front mic */
2770static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2771{
2772 unsigned int present;
2773 unsigned char bits;
2774
2775 present = snd_hda_jack_detect(codec, 0x18);
2776 bits = present ? HDA_AMP_MUTE : 0;
2777 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2778}
2779
2780static void alc880_uniwill_setup(struct hda_codec *codec)
2781{
2782 struct alc_spec *spec = codec->spec;
2783
2784 spec->autocfg.hp_pins[0] = 0x14;
2785 spec->autocfg.speaker_pins[0] = 0x15;
2786 spec->autocfg.speaker_pins[0] = 0x16;
2787}
2788
2789static void alc880_uniwill_init_hook(struct hda_codec *codec)
2790{
2791 alc_automute_amp(codec);
2792 alc880_uniwill_mic_automute(codec);
2793}
2794
2795static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2796 unsigned int res)
2797{
2798 /* Looks like the unsol event is incompatible with the standard
2799 * definition. 4bit tag is placed at 28 bit!
2800 */
2801 switch (res >> 28) {
2802 case ALC880_MIC_EVENT:
2803 alc880_uniwill_mic_automute(codec);
2804 break;
2805 default:
2806 alc_automute_amp_unsol_event(codec, res);
2807 break;
2808 }
2809}
2810
2811static void alc880_uniwill_p53_setup(struct hda_codec *codec)
2812{
2813 struct alc_spec *spec = codec->spec;
2814
2815 spec->autocfg.hp_pins[0] = 0x14;
2816 spec->autocfg.speaker_pins[0] = 0x15;
2817}
2818
2819static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2820{
2821 unsigned int present;
2822
2823 present = snd_hda_codec_read(codec, 0x21, 0,
2824 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2825 present &= HDA_AMP_VOLMASK;
2826 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2827 HDA_AMP_VOLMASK, present);
2828 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2829 HDA_AMP_VOLMASK, present);
2830}
2831
2832static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2833 unsigned int res)
2834{
2835 /* Looks like the unsol event is incompatible with the standard
2836 * definition. 4bit tag is placed at 28 bit!
2837 */
2838 if ((res >> 28) == ALC880_DCVOL_EVENT)
2839 alc880_uniwill_p53_dcvol_automute(codec);
2840 else
2841 alc_automute_amp_unsol_event(codec, res);
2842}
2843
2844/*
2845 * F1734 pin configuration:
2846 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2847 */
2848static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2849 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2850 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2851 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2852 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2853 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2854
2855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2859
2860 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2861 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2862 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2863 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2864 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2865 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2866 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2867 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2868 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2869
2870 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2871 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2872
2873 { }
2874};
2875
2876/*
2877 * ASUS pin configuration:
2878 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2879 */
2880static struct hda_verb alc880_pin_asus_init_verbs[] = {
2881 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2882 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2883 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2884 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2885
2886 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2887 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2888 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2889 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2890 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2892 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2893 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2894
2895 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2897 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2898 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2899 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2900 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2901 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2902 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2903 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2904
2905 { }
2906};
2907
2908/* Enable GPIO mask and set output */
2909#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2910#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2911#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
2912
2913/* Clevo m520g init */
2914static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2915 /* headphone output */
2916 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2917 /* line-out */
2918 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2919 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2920 /* Line-in */
2921 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2922 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2923 /* CD */
2924 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2925 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2926 /* Mic1 (rear panel) */
2927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2928 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2929 /* Mic2 (front panel) */
2930 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2931 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2932 /* headphone */
2933 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2934 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2935 /* change to EAPD mode */
2936 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2937 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2938
2939 { }
2940};
2941
2942static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2943 /* change to EAPD mode */
2944 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2945 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2946
2947 /* Headphone output */
2948 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2949 /* Front output*/
2950 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2951 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2952
2953 /* Line In pin widget for input */
2954 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2955 /* CD pin widget for input */
2956 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2957 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2958 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2959
2960 /* change to EAPD mode */
2961 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2962 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2963
2964 { }
2965};
2966
2967/*
2968 * LG m1 express dual
2969 *
2970 * Pin assignment:
2971 * Rear Line-In/Out (blue): 0x14
2972 * Build-in Mic-In: 0x15
2973 * Speaker-out: 0x17
2974 * HP-Out (green): 0x1b
2975 * Mic-In/Out (red): 0x19
2976 * SPDIF-Out: 0x1e
2977 */
2978
2979/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2980static hda_nid_t alc880_lg_dac_nids[3] = {
2981 0x05, 0x02, 0x03
2982};
2983
2984/* seems analog CD is not working */
2985static struct hda_input_mux alc880_lg_capture_source = {
2986 .num_items = 3,
2987 .items = {
2988 { "Mic", 0x1 },
2989 { "Line", 0x5 },
2990 { "Internal Mic", 0x6 },
2991 },
2992};
2993
2994/* 2,4,6 channel modes */
2995static struct hda_verb alc880_lg_ch2_init[] = {
2996 /* set line-in and mic-in to input */
2997 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2998 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2999 { }
3000};
3001
3002static struct hda_verb alc880_lg_ch4_init[] = {
3003 /* set line-in to out and mic-in to input */
3004 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3005 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3006 { }
3007};
3008
3009static struct hda_verb alc880_lg_ch6_init[] = {
3010 /* set line-in and mic-in to output */
3011 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3012 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3013 { }
3014};
3015
3016static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3017 { 2, alc880_lg_ch2_init },
3018 { 4, alc880_lg_ch4_init },
3019 { 6, alc880_lg_ch6_init },
3020};
3021
3022static struct snd_kcontrol_new alc880_lg_mixer[] = {
3023 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3024 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3025 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3026 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3027 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3028 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3029 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3030 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3032 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3034 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3035 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3036 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3037 {
3038 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3039 .name = "Channel Mode",
3040 .info = alc_ch_mode_info,
3041 .get = alc_ch_mode_get,
3042 .put = alc_ch_mode_put,
3043 },
3044 { } /* end */
3045};
3046
3047static struct hda_verb alc880_lg_init_verbs[] = {
3048 /* set capture source to mic-in */
3049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3050 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3051 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3052 /* mute all amp mixer inputs */
3053 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3054 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3055 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3056 /* line-in to input */
3057 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3059 /* built-in mic */
3060 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3061 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3062 /* speaker-out */
3063 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3064 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3065 /* mic-in to input */
3066 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3067 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3068 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3069 /* HP-out */
3070 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3071 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3072 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3073 /* jack sense */
3074 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3075 { }
3076};
3077
3078/* toggle speaker-output according to the hp-jack state */
3079static void alc880_lg_setup(struct hda_codec *codec)
3080{
3081 struct alc_spec *spec = codec->spec;
3082
3083 spec->autocfg.hp_pins[0] = 0x1b;
3084 spec->autocfg.speaker_pins[0] = 0x17;
3085}
3086
3087/*
3088 * LG LW20
3089 *
3090 * Pin assignment:
3091 * Speaker-out: 0x14
3092 * Mic-In: 0x18
3093 * Built-in Mic-In: 0x19
3094 * Line-In: 0x1b
3095 * HP-Out: 0x1a
3096 * SPDIF-Out: 0x1e
3097 */
3098
3099static struct hda_input_mux alc880_lg_lw_capture_source = {
3100 .num_items = 3,
3101 .items = {
3102 { "Mic", 0x0 },
3103 { "Internal Mic", 0x1 },
3104 { "Line In", 0x2 },
3105 },
3106};
3107
3108#define alc880_lg_lw_modes alc880_threestack_modes
3109
3110static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3111 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3112 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3113 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3114 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3115 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3116 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3117 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3118 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3119 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3120 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3122 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3123 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3124 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3125 {
3126 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3127 .name = "Channel Mode",
3128 .info = alc_ch_mode_info,
3129 .get = alc_ch_mode_get,
3130 .put = alc_ch_mode_put,
3131 },
3132 { } /* end */
3133};
3134
3135static struct hda_verb alc880_lg_lw_init_verbs[] = {
3136 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3137 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3138 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3139
3140 /* set capture source to mic-in */
3141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3142 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3143 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3144 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3145 /* speaker-out */
3146 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3147 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3148 /* HP-out */
3149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3150 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3151 /* mic-in to input */
3152 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3153 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3154 /* built-in mic */
3155 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3156 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3157 /* jack sense */
3158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3159 { }
3160};
3161
3162/* toggle speaker-output according to the hp-jack state */
3163static void alc880_lg_lw_setup(struct hda_codec *codec)
3164{
3165 struct alc_spec *spec = codec->spec;
3166
3167 spec->autocfg.hp_pins[0] = 0x1b;
3168 spec->autocfg.speaker_pins[0] = 0x14;
3169}
3170
3171static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3172 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3173 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3175 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3176 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3177 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3178 { } /* end */
3179};
3180
3181static struct hda_input_mux alc880_medion_rim_capture_source = {
3182 .num_items = 2,
3183 .items = {
3184 { "Mic", 0x0 },
3185 { "Internal Mic", 0x1 },
3186 },
3187};
3188
3189static struct hda_verb alc880_medion_rim_init_verbs[] = {
3190 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3191
3192 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3193 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3194
3195 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3196 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3197 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3198 /* Mic2 (as headphone out) for HP output */
3199 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3200 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3201 /* Internal Speaker */
3202 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3203 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3204
3205 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3206 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3207
3208 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3209 { }
3210};
3211
3212/* toggle speaker-output according to the hp-jack state */
3213static void alc880_medion_rim_automute(struct hda_codec *codec)
3214{
3215 struct alc_spec *spec = codec->spec;
3216 alc_automute_amp(codec);
3217 /* toggle EAPD */
3218 if (spec->jack_present)
3219 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3220 else
3221 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3222}
3223
3224static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3225 unsigned int res)
3226{
3227 /* Looks like the unsol event is incompatible with the standard
3228 * definition. 4bit tag is placed at 28 bit!
3229 */
3230 if ((res >> 28) == ALC880_HP_EVENT)
3231 alc880_medion_rim_automute(codec);
3232}
3233
3234static void alc880_medion_rim_setup(struct hda_codec *codec)
3235{
3236 struct alc_spec *spec = codec->spec;
3237
3238 spec->autocfg.hp_pins[0] = 0x14;
3239 spec->autocfg.speaker_pins[0] = 0x1b;
3240}
3241
3242#ifdef CONFIG_SND_HDA_POWER_SAVE
3243static struct hda_amp_list alc880_loopbacks[] = {
3244 { 0x0b, HDA_INPUT, 0 },
3245 { 0x0b, HDA_INPUT, 1 },
3246 { 0x0b, HDA_INPUT, 2 },
3247 { 0x0b, HDA_INPUT, 3 },
3248 { 0x0b, HDA_INPUT, 4 },
3249 { } /* end */
3250};
3251
3252static struct hda_amp_list alc880_lg_loopbacks[] = {
3253 { 0x0b, HDA_INPUT, 1 },
3254 { 0x0b, HDA_INPUT, 6 },
3255 { 0x0b, HDA_INPUT, 7 },
3256 { } /* end */
3257};
3258#endif
3259
3260/*
3261 * Common callbacks
3262 */
3263
3264static int alc_init(struct hda_codec *codec)
3265{
3266 struct alc_spec *spec = codec->spec;
3267 unsigned int i;
3268
3269 alc_fix_pll(codec);
3270 alc_auto_init_amp(codec, spec->init_amp);
3271
3272 for (i = 0; i < spec->num_init_verbs; i++)
3273 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3274
3275 if (spec->init_hook)
3276 spec->init_hook(codec);
3277
3278 return 0;
3279}
3280
3281static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3282{
3283 struct alc_spec *spec = codec->spec;
3284
3285 if (spec->unsol_event)
3286 spec->unsol_event(codec, res);
3287}
3288
3289#ifdef CONFIG_SND_HDA_POWER_SAVE
3290static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3291{
3292 struct alc_spec *spec = codec->spec;
3293 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3294}
3295#endif
3296
3297/*
3298 * Analog playback callbacks
3299 */
3300static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3301 struct hda_codec *codec,
3302 struct snd_pcm_substream *substream)
3303{
3304 struct alc_spec *spec = codec->spec;
3305 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3306 hinfo);
3307}
3308
3309static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3310 struct hda_codec *codec,
3311 unsigned int stream_tag,
3312 unsigned int format,
3313 struct snd_pcm_substream *substream)
3314{
3315 struct alc_spec *spec = codec->spec;
3316 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3317 stream_tag, format, substream);
3318}
3319
3320static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3321 struct hda_codec *codec,
3322 struct snd_pcm_substream *substream)
3323{
3324 struct alc_spec *spec = codec->spec;
3325 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3326}
3327
3328/*
3329 * Digital out
3330 */
3331static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3332 struct hda_codec *codec,
3333 struct snd_pcm_substream *substream)
3334{
3335 struct alc_spec *spec = codec->spec;
3336 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3337}
3338
3339static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3340 struct hda_codec *codec,
3341 unsigned int stream_tag,
3342 unsigned int format,
3343 struct snd_pcm_substream *substream)
3344{
3345 struct alc_spec *spec = codec->spec;
3346 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3347 stream_tag, format, substream);
3348}
3349
3350static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3351 struct hda_codec *codec,
3352 struct snd_pcm_substream *substream)
3353{
3354 struct alc_spec *spec = codec->spec;
3355 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3356}
3357
3358static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3359 struct hda_codec *codec,
3360 struct snd_pcm_substream *substream)
3361{
3362 struct alc_spec *spec = codec->spec;
3363 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3364}
3365
3366/*
3367 * Analog capture
3368 */
3369static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3370 struct hda_codec *codec,
3371 unsigned int stream_tag,
3372 unsigned int format,
3373 struct snd_pcm_substream *substream)
3374{
3375 struct alc_spec *spec = codec->spec;
3376
3377 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3378 stream_tag, 0, format);
3379 return 0;
3380}
3381
3382static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3383 struct hda_codec *codec,
3384 struct snd_pcm_substream *substream)
3385{
3386 struct alc_spec *spec = codec->spec;
3387
3388 snd_hda_codec_cleanup_stream(codec,
3389 spec->adc_nids[substream->number + 1]);
3390 return 0;
3391}
3392
3393
3394/*
3395 */
3396static struct hda_pcm_stream alc880_pcm_analog_playback = {
3397 .substreams = 1,
3398 .channels_min = 2,
3399 .channels_max = 8,
3400 /* NID is set in alc_build_pcms */
3401 .ops = {
3402 .open = alc880_playback_pcm_open,
3403 .prepare = alc880_playback_pcm_prepare,
3404 .cleanup = alc880_playback_pcm_cleanup
3405 },
3406};
3407
3408static struct hda_pcm_stream alc880_pcm_analog_capture = {
3409 .substreams = 1,
3410 .channels_min = 2,
3411 .channels_max = 2,
3412 /* NID is set in alc_build_pcms */
3413};
3414
3415static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3416 .substreams = 1,
3417 .channels_min = 2,
3418 .channels_max = 2,
3419 /* NID is set in alc_build_pcms */
3420};
3421
3422static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3423 .substreams = 2, /* can be overridden */
3424 .channels_min = 2,
3425 .channels_max = 2,
3426 /* NID is set in alc_build_pcms */
3427 .ops = {
3428 .prepare = alc880_alt_capture_pcm_prepare,
3429 .cleanup = alc880_alt_capture_pcm_cleanup
3430 },
3431};
3432
3433static struct hda_pcm_stream alc880_pcm_digital_playback = {
3434 .substreams = 1,
3435 .channels_min = 2,
3436 .channels_max = 2,
3437 /* NID is set in alc_build_pcms */
3438 .ops = {
3439 .open = alc880_dig_playback_pcm_open,
3440 .close = alc880_dig_playback_pcm_close,
3441 .prepare = alc880_dig_playback_pcm_prepare,
3442 .cleanup = alc880_dig_playback_pcm_cleanup
3443 },
3444};
3445
3446static struct hda_pcm_stream alc880_pcm_digital_capture = {
3447 .substreams = 1,
3448 .channels_min = 2,
3449 .channels_max = 2,
3450 /* NID is set in alc_build_pcms */
3451};
3452
3453/* Used by alc_build_pcms to flag that a PCM has no playback stream */
3454static struct hda_pcm_stream alc_pcm_null_stream = {
3455 .substreams = 0,
3456 .channels_min = 0,
3457 .channels_max = 0,
3458};
3459
3460static int alc_build_pcms(struct hda_codec *codec)
3461{
3462 struct alc_spec *spec = codec->spec;
3463 struct hda_pcm *info = spec->pcm_rec;
3464 int i;
3465
3466 codec->num_pcms = 1;
3467 codec->pcm_info = info;
3468
3469 if (spec->no_analog)
3470 goto skip_analog;
3471
3472 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3473 "%s Analog", codec->chip_name);
3474 info->name = spec->stream_name_analog;
3475
3476 if (spec->stream_analog_playback) {
3477 if (snd_BUG_ON(!spec->multiout.dac_nids))
3478 return -EINVAL;
3479 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3480 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3481 }
3482 if (spec->stream_analog_capture) {
3483 if (snd_BUG_ON(!spec->adc_nids))
3484 return -EINVAL;
3485 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3486 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3487 }
3488
3489 if (spec->channel_mode) {
3490 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3491 for (i = 0; i < spec->num_channel_mode; i++) {
3492 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3493 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3494 }
3495 }
3496 }
3497
3498 skip_analog:
3499 /* SPDIF for stream index #1 */
3500 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3501 snprintf(spec->stream_name_digital,
3502 sizeof(spec->stream_name_digital),
3503 "%s Digital", codec->chip_name);
3504 codec->num_pcms = 2;
3505 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3506 info = spec->pcm_rec + 1;
3507 info->name = spec->stream_name_digital;
3508 if (spec->dig_out_type)
3509 info->pcm_type = spec->dig_out_type;
3510 else
3511 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3512 if (spec->multiout.dig_out_nid &&
3513 spec->stream_digital_playback) {
3514 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3515 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3516 }
3517 if (spec->dig_in_nid &&
3518 spec->stream_digital_capture) {
3519 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3520 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3521 }
3522 /* FIXME: do we need this for all Realtek codec models? */
3523 codec->spdif_status_reset = 1;
3524 }
3525
3526 if (spec->no_analog)
3527 return 0;
3528
3529 /* If the use of more than one ADC is requested for the current
3530 * model, configure a second analog capture-only PCM.
3531 */
3532 /* Additional Analaog capture for index #2 */
3533 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3534 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3535 codec->num_pcms = 3;
3536 info = spec->pcm_rec + 2;
3537 info->name = spec->stream_name_analog;
3538 if (spec->alt_dac_nid) {
3539 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3540 *spec->stream_analog_alt_playback;
3541 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3542 spec->alt_dac_nid;
3543 } else {
3544 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3545 alc_pcm_null_stream;
3546 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3547 }
3548 if (spec->num_adc_nids > 1) {
3549 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3550 *spec->stream_analog_alt_capture;
3551 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3552 spec->adc_nids[1];
3553 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3554 spec->num_adc_nids - 1;
3555 } else {
3556 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3557 alc_pcm_null_stream;
3558 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3559 }
3560 }
3561
3562 return 0;
3563}
3564
3565static void alc_free_kctls(struct hda_codec *codec)
3566{
3567 struct alc_spec *spec = codec->spec;
3568
3569 if (spec->kctls.list) {
3570 struct snd_kcontrol_new *kctl = spec->kctls.list;
3571 int i;
3572 for (i = 0; i < spec->kctls.used; i++)
3573 kfree(kctl[i].name);
3574 }
3575 snd_array_free(&spec->kctls);
3576}
3577
3578static void alc_free(struct hda_codec *codec)
3579{
3580 struct alc_spec *spec = codec->spec;
3581
3582 if (!spec)
3583 return;
3584
3585 alc_free_kctls(codec);
3586 kfree(spec);
3587 snd_hda_detach_beep_device(codec);
3588}
3589
3590#ifdef SND_HDA_NEEDS_RESUME
3591static int alc_resume(struct hda_codec *codec)
3592{
3593 codec->patch_ops.init(codec);
3594 snd_hda_codec_resume_amp(codec);
3595 snd_hda_codec_resume_cache(codec);
3596 return 0;
3597}
3598#endif
3599
3600/*
3601 */
3602static struct hda_codec_ops alc_patch_ops = {
3603 .build_controls = alc_build_controls,
3604 .build_pcms = alc_build_pcms,
3605 .init = alc_init,
3606 .free = alc_free,
3607 .unsol_event = alc_unsol_event,
3608#ifdef SND_HDA_NEEDS_RESUME
3609 .resume = alc_resume,
3610#endif
3611#ifdef CONFIG_SND_HDA_POWER_SAVE
3612 .check_power_status = alc_check_power_status,
3613#endif
3614};
3615
3616
3617/*
3618 * Test configuration for debugging
3619 *
3620 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3621 * enum controls.
3622 */
3623#ifdef CONFIG_SND_DEBUG
3624static hda_nid_t alc880_test_dac_nids[4] = {
3625 0x02, 0x03, 0x04, 0x05
3626};
3627
3628static struct hda_input_mux alc880_test_capture_source = {
3629 .num_items = 7,
3630 .items = {
3631 { "In-1", 0x0 },
3632 { "In-2", 0x1 },
3633 { "In-3", 0x2 },
3634 { "In-4", 0x3 },
3635 { "CD", 0x4 },
3636 { "Front", 0x5 },
3637 { "Surround", 0x6 },
3638 },
3639};
3640
3641static struct hda_channel_mode alc880_test_modes[4] = {
3642 { 2, NULL },
3643 { 4, NULL },
3644 { 6, NULL },
3645 { 8, NULL },
3646};
3647
3648static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3649 struct snd_ctl_elem_info *uinfo)
3650{
3651 static char *texts[] = {
3652 "N/A", "Line Out", "HP Out",
3653 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3654 };
3655 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3656 uinfo->count = 1;
3657 uinfo->value.enumerated.items = 8;
3658 if (uinfo->value.enumerated.item >= 8)
3659 uinfo->value.enumerated.item = 7;
3660 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3661 return 0;
3662}
3663
3664static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3665 struct snd_ctl_elem_value *ucontrol)
3666{
3667 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3668 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3669 unsigned int pin_ctl, item = 0;
3670
3671 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3672 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3673 if (pin_ctl & AC_PINCTL_OUT_EN) {
3674 if (pin_ctl & AC_PINCTL_HP_EN)
3675 item = 2;
3676 else
3677 item = 1;
3678 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3679 switch (pin_ctl & AC_PINCTL_VREFEN) {
3680 case AC_PINCTL_VREF_HIZ: item = 3; break;
3681 case AC_PINCTL_VREF_50: item = 4; break;
3682 case AC_PINCTL_VREF_GRD: item = 5; break;
3683 case AC_PINCTL_VREF_80: item = 6; break;
3684 case AC_PINCTL_VREF_100: item = 7; break;
3685 }
3686 }
3687 ucontrol->value.enumerated.item[0] = item;
3688 return 0;
3689}
3690
3691static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3692 struct snd_ctl_elem_value *ucontrol)
3693{
3694 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3695 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3696 static unsigned int ctls[] = {
3697 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3698 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3699 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3700 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3701 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3702 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3703 };
3704 unsigned int old_ctl, new_ctl;
3705
3706 old_ctl = snd_hda_codec_read(codec, nid, 0,
3707 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3708 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3709 if (old_ctl != new_ctl) {
3710 int val;
3711 snd_hda_codec_write_cache(codec, nid, 0,
3712 AC_VERB_SET_PIN_WIDGET_CONTROL,
3713 new_ctl);
3714 val = ucontrol->value.enumerated.item[0] >= 3 ?
3715 HDA_AMP_MUTE : 0;
3716 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3717 HDA_AMP_MUTE, val);
3718 return 1;
3719 }
3720 return 0;
3721}
3722
3723static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3724 struct snd_ctl_elem_info *uinfo)
3725{
3726 static char *texts[] = {
3727 "Front", "Surround", "CLFE", "Side"
3728 };
3729 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3730 uinfo->count = 1;
3731 uinfo->value.enumerated.items = 4;
3732 if (uinfo->value.enumerated.item >= 4)
3733 uinfo->value.enumerated.item = 3;
3734 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3735 return 0;
3736}
3737
3738static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3739 struct snd_ctl_elem_value *ucontrol)
3740{
3741 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3742 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3743 unsigned int sel;
3744
3745 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3746 ucontrol->value.enumerated.item[0] = sel & 3;
3747 return 0;
3748}
3749
3750static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3751 struct snd_ctl_elem_value *ucontrol)
3752{
3753 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3754 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3755 unsigned int sel;
3756
3757 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3758 if (ucontrol->value.enumerated.item[0] != sel) {
3759 sel = ucontrol->value.enumerated.item[0] & 3;
3760 snd_hda_codec_write_cache(codec, nid, 0,
3761 AC_VERB_SET_CONNECT_SEL, sel);
3762 return 1;
3763 }
3764 return 0;
3765}
3766
3767#define PIN_CTL_TEST(xname,nid) { \
3768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3769 .name = xname, \
3770 .info = alc_test_pin_ctl_info, \
3771 .get = alc_test_pin_ctl_get, \
3772 .put = alc_test_pin_ctl_put, \
3773 .private_value = nid \
3774 }
3775
3776#define PIN_SRC_TEST(xname,nid) { \
3777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3778 .name = xname, \
3779 .info = alc_test_pin_src_info, \
3780 .get = alc_test_pin_src_get, \
3781 .put = alc_test_pin_src_put, \
3782 .private_value = nid \
3783 }
3784
3785static struct snd_kcontrol_new alc880_test_mixer[] = {
3786 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3787 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3788 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3789 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3790 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3791 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3792 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3793 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3794 PIN_CTL_TEST("Front Pin Mode", 0x14),
3795 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3796 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3797 PIN_CTL_TEST("Side Pin Mode", 0x17),
3798 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3799 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3800 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3801 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3802 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3803 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3804 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3805 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3806 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3807 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3808 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3809 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3810 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3811 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3812 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3813 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3814 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3815 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3816 {
3817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3818 .name = "Channel Mode",
3819 .info = alc_ch_mode_info,
3820 .get = alc_ch_mode_get,
3821 .put = alc_ch_mode_put,
3822 },
3823 { } /* end */
3824};
3825
3826static struct hda_verb alc880_test_init_verbs[] = {
3827 /* Unmute inputs of 0x0c - 0x0f */
3828 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3830 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3831 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3832 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3833 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3834 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3835 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3836 /* Vol output for 0x0c-0x0f */
3837 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3838 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3839 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3840 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3841 /* Set output pins 0x14-0x17 */
3842 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3843 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3844 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3845 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3846 /* Unmute output pins 0x14-0x17 */
3847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3849 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3850 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3851 /* Set input pins 0x18-0x1c */
3852 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3853 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3855 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3856 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3857 /* Mute input pins 0x18-0x1b */
3858 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3860 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3861 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3862 /* ADC set up */
3863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3864 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3865 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3866 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3867 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3868 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3869 /* Analog input/passthru */
3870 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3871 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3872 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3873 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3874 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3875 { }
3876};
3877#endif
3878
3879/*
3880 */
3881
3882static const char *alc880_models[ALC880_MODEL_LAST] = {
3883 [ALC880_3ST] = "3stack",
3884 [ALC880_TCL_S700] = "tcl",
3885 [ALC880_3ST_DIG] = "3stack-digout",
3886 [ALC880_CLEVO] = "clevo",
3887 [ALC880_5ST] = "5stack",
3888 [ALC880_5ST_DIG] = "5stack-digout",
3889 [ALC880_W810] = "w810",
3890 [ALC880_Z71V] = "z71v",
3891 [ALC880_6ST] = "6stack",
3892 [ALC880_6ST_DIG] = "6stack-digout",
3893 [ALC880_ASUS] = "asus",
3894 [ALC880_ASUS_W1V] = "asus-w1v",
3895 [ALC880_ASUS_DIG] = "asus-dig",
3896 [ALC880_ASUS_DIG2] = "asus-dig2",
3897 [ALC880_UNIWILL_DIG] = "uniwill",
3898 [ALC880_UNIWILL_P53] = "uniwill-p53",
3899 [ALC880_FUJITSU] = "fujitsu",
3900 [ALC880_F1734] = "F1734",
3901 [ALC880_LG] = "lg",
3902 [ALC880_LG_LW] = "lg-lw",
3903 [ALC880_MEDION_RIM] = "medion",
3904#ifdef CONFIG_SND_DEBUG
3905 [ALC880_TEST] = "test",
3906#endif
3907 [ALC880_AUTO] = "auto",
3908};
3909
3910static struct snd_pci_quirk alc880_cfg_tbl[] = {
3911 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3912 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3913 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3914 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3915 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3916 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3917 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3918 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3919 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3920 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3921 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3922 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3923 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3924 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3925 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3926 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3927 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3928 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3929 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3930 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3931 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3932 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3933 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3934 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3935 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3936 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3937 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3938 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3939 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3940 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3941 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3942 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3943 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3944 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3945 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3946 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3947 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3948 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3949 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3950 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3951 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3952 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3953 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3954 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3955 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3956 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3957 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3958 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3959 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3960 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3961 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3962 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3963 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3964 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3965 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3966 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3967 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3968 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3969 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3970 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3971 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3972 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3973 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3974 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3975 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3976 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3977 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3978 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3979 /* default Intel */
3980 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3981 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3982 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3983 {}
3984};
3985
3986/*
3987 * ALC880 codec presets
3988 */
3989static struct alc_config_preset alc880_presets[] = {
3990 [ALC880_3ST] = {
3991 .mixers = { alc880_three_stack_mixer },
3992 .init_verbs = { alc880_volume_init_verbs,
3993 alc880_pin_3stack_init_verbs },
3994 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3995 .dac_nids = alc880_dac_nids,
3996 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3997 .channel_mode = alc880_threestack_modes,
3998 .need_dac_fix = 1,
3999 .input_mux = &alc880_capture_source,
4000 },
4001 [ALC880_3ST_DIG] = {
4002 .mixers = { alc880_three_stack_mixer },
4003 .init_verbs = { alc880_volume_init_verbs,
4004 alc880_pin_3stack_init_verbs },
4005 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4006 .dac_nids = alc880_dac_nids,
4007 .dig_out_nid = ALC880_DIGOUT_NID,
4008 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4009 .channel_mode = alc880_threestack_modes,
4010 .need_dac_fix = 1,
4011 .input_mux = &alc880_capture_source,
4012 },
4013 [ALC880_TCL_S700] = {
4014 .mixers = { alc880_tcl_s700_mixer },
4015 .init_verbs = { alc880_volume_init_verbs,
4016 alc880_pin_tcl_S700_init_verbs,
4017 alc880_gpio2_init_verbs },
4018 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4019 .dac_nids = alc880_dac_nids,
4020 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4021 .num_adc_nids = 1, /* single ADC */
4022 .hp_nid = 0x03,
4023 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4024 .channel_mode = alc880_2_jack_modes,
4025 .input_mux = &alc880_capture_source,
4026 },
4027 [ALC880_5ST] = {
4028 .mixers = { alc880_three_stack_mixer,
4029 alc880_five_stack_mixer},
4030 .init_verbs = { alc880_volume_init_verbs,
4031 alc880_pin_5stack_init_verbs },
4032 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4033 .dac_nids = alc880_dac_nids,
4034 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4035 .channel_mode = alc880_fivestack_modes,
4036 .input_mux = &alc880_capture_source,
4037 },
4038 [ALC880_5ST_DIG] = {
4039 .mixers = { alc880_three_stack_mixer,
4040 alc880_five_stack_mixer },
4041 .init_verbs = { alc880_volume_init_verbs,
4042 alc880_pin_5stack_init_verbs },
4043 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4044 .dac_nids = alc880_dac_nids,
4045 .dig_out_nid = ALC880_DIGOUT_NID,
4046 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4047 .channel_mode = alc880_fivestack_modes,
4048 .input_mux = &alc880_capture_source,
4049 },
4050 [ALC880_6ST] = {
4051 .mixers = { alc880_six_stack_mixer },
4052 .init_verbs = { alc880_volume_init_verbs,
4053 alc880_pin_6stack_init_verbs },
4054 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4055 .dac_nids = alc880_6st_dac_nids,
4056 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4057 .channel_mode = alc880_sixstack_modes,
4058 .input_mux = &alc880_6stack_capture_source,
4059 },
4060 [ALC880_6ST_DIG] = {
4061 .mixers = { alc880_six_stack_mixer },
4062 .init_verbs = { alc880_volume_init_verbs,
4063 alc880_pin_6stack_init_verbs },
4064 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4065 .dac_nids = alc880_6st_dac_nids,
4066 .dig_out_nid = ALC880_DIGOUT_NID,
4067 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4068 .channel_mode = alc880_sixstack_modes,
4069 .input_mux = &alc880_6stack_capture_source,
4070 },
4071 [ALC880_W810] = {
4072 .mixers = { alc880_w810_base_mixer },
4073 .init_verbs = { alc880_volume_init_verbs,
4074 alc880_pin_w810_init_verbs,
4075 alc880_gpio2_init_verbs },
4076 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4077 .dac_nids = alc880_w810_dac_nids,
4078 .dig_out_nid = ALC880_DIGOUT_NID,
4079 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4080 .channel_mode = alc880_w810_modes,
4081 .input_mux = &alc880_capture_source,
4082 },
4083 [ALC880_Z71V] = {
4084 .mixers = { alc880_z71v_mixer },
4085 .init_verbs = { alc880_volume_init_verbs,
4086 alc880_pin_z71v_init_verbs },
4087 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4088 .dac_nids = alc880_z71v_dac_nids,
4089 .dig_out_nid = ALC880_DIGOUT_NID,
4090 .hp_nid = 0x03,
4091 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4092 .channel_mode = alc880_2_jack_modes,
4093 .input_mux = &alc880_capture_source,
4094 },
4095 [ALC880_F1734] = {
4096 .mixers = { alc880_f1734_mixer },
4097 .init_verbs = { alc880_volume_init_verbs,
4098 alc880_pin_f1734_init_verbs },
4099 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4100 .dac_nids = alc880_f1734_dac_nids,
4101 .hp_nid = 0x02,
4102 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4103 .channel_mode = alc880_2_jack_modes,
4104 .input_mux = &alc880_f1734_capture_source,
4105 .unsol_event = alc880_uniwill_p53_unsol_event,
4106 .setup = alc880_uniwill_p53_setup,
4107 .init_hook = alc_automute_amp,
4108 },
4109 [ALC880_ASUS] = {
4110 .mixers = { alc880_asus_mixer },
4111 .init_verbs = { alc880_volume_init_verbs,
4112 alc880_pin_asus_init_verbs,
4113 alc880_gpio1_init_verbs },
4114 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4115 .dac_nids = alc880_asus_dac_nids,
4116 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4117 .channel_mode = alc880_asus_modes,
4118 .need_dac_fix = 1,
4119 .input_mux = &alc880_capture_source,
4120 },
4121 [ALC880_ASUS_DIG] = {
4122 .mixers = { alc880_asus_mixer },
4123 .init_verbs = { alc880_volume_init_verbs,
4124 alc880_pin_asus_init_verbs,
4125 alc880_gpio1_init_verbs },
4126 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4127 .dac_nids = alc880_asus_dac_nids,
4128 .dig_out_nid = ALC880_DIGOUT_NID,
4129 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4130 .channel_mode = alc880_asus_modes,
4131 .need_dac_fix = 1,
4132 .input_mux = &alc880_capture_source,
4133 },
4134 [ALC880_ASUS_DIG2] = {
4135 .mixers = { alc880_asus_mixer },
4136 .init_verbs = { alc880_volume_init_verbs,
4137 alc880_pin_asus_init_verbs,
4138 alc880_gpio2_init_verbs }, /* use GPIO2 */
4139 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4140 .dac_nids = alc880_asus_dac_nids,
4141 .dig_out_nid = ALC880_DIGOUT_NID,
4142 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4143 .channel_mode = alc880_asus_modes,
4144 .need_dac_fix = 1,
4145 .input_mux = &alc880_capture_source,
4146 },
4147 [ALC880_ASUS_W1V] = {
4148 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4149 .init_verbs = { alc880_volume_init_verbs,
4150 alc880_pin_asus_init_verbs,
4151 alc880_gpio1_init_verbs },
4152 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4153 .dac_nids = alc880_asus_dac_nids,
4154 .dig_out_nid = ALC880_DIGOUT_NID,
4155 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4156 .channel_mode = alc880_asus_modes,
4157 .need_dac_fix = 1,
4158 .input_mux = &alc880_capture_source,
4159 },
4160 [ALC880_UNIWILL_DIG] = {
4161 .mixers = { alc880_asus_mixer },
4162 .init_verbs = { alc880_volume_init_verbs,
4163 alc880_pin_asus_init_verbs },
4164 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4165 .dac_nids = alc880_asus_dac_nids,
4166 .dig_out_nid = ALC880_DIGOUT_NID,
4167 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4168 .channel_mode = alc880_asus_modes,
4169 .need_dac_fix = 1,
4170 .input_mux = &alc880_capture_source,
4171 },
4172 [ALC880_UNIWILL] = {
4173 .mixers = { alc880_uniwill_mixer },
4174 .init_verbs = { alc880_volume_init_verbs,
4175 alc880_uniwill_init_verbs },
4176 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4177 .dac_nids = alc880_asus_dac_nids,
4178 .dig_out_nid = ALC880_DIGOUT_NID,
4179 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4180 .channel_mode = alc880_threestack_modes,
4181 .need_dac_fix = 1,
4182 .input_mux = &alc880_capture_source,
4183 .unsol_event = alc880_uniwill_unsol_event,
4184 .setup = alc880_uniwill_setup,
4185 .init_hook = alc880_uniwill_init_hook,
4186 },
4187 [ALC880_UNIWILL_P53] = {
4188 .mixers = { alc880_uniwill_p53_mixer },
4189 .init_verbs = { alc880_volume_init_verbs,
4190 alc880_uniwill_p53_init_verbs },
4191 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4192 .dac_nids = alc880_asus_dac_nids,
4193 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4194 .channel_mode = alc880_threestack_modes,
4195 .input_mux = &alc880_capture_source,
4196 .unsol_event = alc880_uniwill_p53_unsol_event,
4197 .setup = alc880_uniwill_p53_setup,
4198 .init_hook = alc_automute_amp,
4199 },
4200 [ALC880_FUJITSU] = {
4201 .mixers = { alc880_fujitsu_mixer },
4202 .init_verbs = { alc880_volume_init_verbs,
4203 alc880_uniwill_p53_init_verbs,
4204 alc880_beep_init_verbs },
4205 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4206 .dac_nids = alc880_dac_nids,
4207 .dig_out_nid = ALC880_DIGOUT_NID,
4208 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4209 .channel_mode = alc880_2_jack_modes,
4210 .input_mux = &alc880_capture_source,
4211 .unsol_event = alc880_uniwill_p53_unsol_event,
4212 .setup = alc880_uniwill_p53_setup,
4213 .init_hook = alc_automute_amp,
4214 },
4215 [ALC880_CLEVO] = {
4216 .mixers = { alc880_three_stack_mixer },
4217 .init_verbs = { alc880_volume_init_verbs,
4218 alc880_pin_clevo_init_verbs },
4219 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4220 .dac_nids = alc880_dac_nids,
4221 .hp_nid = 0x03,
4222 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4223 .channel_mode = alc880_threestack_modes,
4224 .need_dac_fix = 1,
4225 .input_mux = &alc880_capture_source,
4226 },
4227 [ALC880_LG] = {
4228 .mixers = { alc880_lg_mixer },
4229 .init_verbs = { alc880_volume_init_verbs,
4230 alc880_lg_init_verbs },
4231 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4232 .dac_nids = alc880_lg_dac_nids,
4233 .dig_out_nid = ALC880_DIGOUT_NID,
4234 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4235 .channel_mode = alc880_lg_ch_modes,
4236 .need_dac_fix = 1,
4237 .input_mux = &alc880_lg_capture_source,
4238 .unsol_event = alc_automute_amp_unsol_event,
4239 .setup = alc880_lg_setup,
4240 .init_hook = alc_automute_amp,
4241#ifdef CONFIG_SND_HDA_POWER_SAVE
4242 .loopbacks = alc880_lg_loopbacks,
4243#endif
4244 },
4245 [ALC880_LG_LW] = {
4246 .mixers = { alc880_lg_lw_mixer },
4247 .init_verbs = { alc880_volume_init_verbs,
4248 alc880_lg_lw_init_verbs },
4249 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4250 .dac_nids = alc880_dac_nids,
4251 .dig_out_nid = ALC880_DIGOUT_NID,
4252 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4253 .channel_mode = alc880_lg_lw_modes,
4254 .input_mux = &alc880_lg_lw_capture_source,
4255 .unsol_event = alc_automute_amp_unsol_event,
4256 .setup = alc880_lg_lw_setup,
4257 .init_hook = alc_automute_amp,
4258 },
4259 [ALC880_MEDION_RIM] = {
4260 .mixers = { alc880_medion_rim_mixer },
4261 .init_verbs = { alc880_volume_init_verbs,
4262 alc880_medion_rim_init_verbs,
4263 alc_gpio2_init_verbs },
4264 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4265 .dac_nids = alc880_dac_nids,
4266 .dig_out_nid = ALC880_DIGOUT_NID,
4267 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4268 .channel_mode = alc880_2_jack_modes,
4269 .input_mux = &alc880_medion_rim_capture_source,
4270 .unsol_event = alc880_medion_rim_unsol_event,
4271 .setup = alc880_medion_rim_setup,
4272 .init_hook = alc880_medion_rim_automute,
4273 },
4274#ifdef CONFIG_SND_DEBUG
4275 [ALC880_TEST] = {
4276 .mixers = { alc880_test_mixer },
4277 .init_verbs = { alc880_test_init_verbs },
4278 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4279 .dac_nids = alc880_test_dac_nids,
4280 .dig_out_nid = ALC880_DIGOUT_NID,
4281 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4282 .channel_mode = alc880_test_modes,
4283 .input_mux = &alc880_test_capture_source,
4284 },
4285#endif
4286};
4287
4288/*
4289 * Automatic parse of I/O pins from the BIOS configuration
4290 */
4291
4292enum {
4293 ALC_CTL_WIDGET_VOL,
4294 ALC_CTL_WIDGET_MUTE,
4295 ALC_CTL_BIND_MUTE,
4296};
4297static struct snd_kcontrol_new alc880_control_templates[] = {
4298 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4299 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4300 HDA_BIND_MUTE(NULL, 0, 0, 0),
4301};
4302
4303/* add dynamic controls */
4304static int add_control(struct alc_spec *spec, int type, const char *name,
4305 unsigned long val)
4306{
4307 struct snd_kcontrol_new *knew;
4308
4309 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4310 knew = snd_array_new(&spec->kctls);
4311 if (!knew)
4312 return -ENOMEM;
4313 *knew = alc880_control_templates[type];
4314 knew->name = kstrdup(name, GFP_KERNEL);
4315 if (!knew->name)
4316 return -ENOMEM;
4317 if (get_amp_nid_(val))
4318 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val);
4319 knew->private_value = val;
4320 return 0;
4321}
4322
4323static int add_control_with_pfx(struct alc_spec *spec, int type,
4324 const char *pfx, const char *dir,
4325 const char *sfx, unsigned long val)
4326{
4327 char name[32];
4328 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4329 return add_control(spec, type, name, val);
4330}
4331
4332#define add_pb_vol_ctrl(spec, type, pfx, val) \
4333 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4334#define add_pb_sw_ctrl(spec, type, pfx, val) \
4335 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4336
4337#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4338#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4339#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4340#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4341#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4342#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4343#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4344#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4345#define ALC880_PIN_CD_NID 0x1c
4346
4347/* fill in the dac_nids table from the parsed pin configuration */
4348static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4349 const struct auto_pin_cfg *cfg)
4350{
4351 hda_nid_t nid;
4352 int assigned[4];
4353 int i, j;
4354
4355 memset(assigned, 0, sizeof(assigned));
4356 spec->multiout.dac_nids = spec->private_dac_nids;
4357
4358 /* check the pins hardwired to audio widget */
4359 for (i = 0; i < cfg->line_outs; i++) {
4360 nid = cfg->line_out_pins[i];
4361 if (alc880_is_fixed_pin(nid)) {
4362 int idx = alc880_fixed_pin_idx(nid);
4363 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4364 assigned[idx] = 1;
4365 }
4366 }
4367 /* left pins can be connect to any audio widget */
4368 for (i = 0; i < cfg->line_outs; i++) {
4369 nid = cfg->line_out_pins[i];
4370 if (alc880_is_fixed_pin(nid))
4371 continue;
4372 /* search for an empty channel */
4373 for (j = 0; j < cfg->line_outs; j++) {
4374 if (!assigned[j]) {
4375 spec->multiout.dac_nids[i] =
4376 alc880_idx_to_dac(j);
4377 assigned[j] = 1;
4378 break;
4379 }
4380 }
4381 }
4382 spec->multiout.num_dacs = cfg->line_outs;
4383 return 0;
4384}
4385
4386/* add playback controls from the parsed DAC table */
4387static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4388 const struct auto_pin_cfg *cfg)
4389{
4390 static const char *chname[4] = {
4391 "Front", "Surround", NULL /*CLFE*/, "Side"
4392 };
4393 hda_nid_t nid;
4394 int i, err;
4395
4396 for (i = 0; i < cfg->line_outs; i++) {
4397 if (!spec->multiout.dac_nids[i])
4398 continue;
4399 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4400 if (i == 2) {
4401 /* Center/LFE */
4402 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4403 "Center",
4404 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4405 HDA_OUTPUT));
4406 if (err < 0)
4407 return err;
4408 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4409 "LFE",
4410 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4411 HDA_OUTPUT));
4412 if (err < 0)
4413 return err;
4414 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4415 "Center",
4416 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4417 HDA_INPUT));
4418 if (err < 0)
4419 return err;
4420 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4421 "LFE",
4422 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4423 HDA_INPUT));
4424 if (err < 0)
4425 return err;
4426 } else {
4427 const char *pfx;
4428 if (cfg->line_outs == 1 &&
4429 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4430 pfx = "Speaker";
4431 else
4432 pfx = chname[i];
4433 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4434 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4435 HDA_OUTPUT));
4436 if (err < 0)
4437 return err;
4438 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4439 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4440 HDA_INPUT));
4441 if (err < 0)
4442 return err;
4443 }
4444 }
4445 return 0;
4446}
4447
4448/* add playback controls for speaker and HP outputs */
4449static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4450 const char *pfx)
4451{
4452 hda_nid_t nid;
4453 int err;
4454
4455 if (!pin)
4456 return 0;
4457
4458 if (alc880_is_fixed_pin(pin)) {
4459 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4460 /* specify the DAC as the extra output */
4461 if (!spec->multiout.hp_nid)
4462 spec->multiout.hp_nid = nid;
4463 else
4464 spec->multiout.extra_out_nid[0] = nid;
4465 /* control HP volume/switch on the output mixer amp */
4466 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4467 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4468 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4469 if (err < 0)
4470 return err;
4471 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4472 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4473 if (err < 0)
4474 return err;
4475 } else if (alc880_is_multi_pin(pin)) {
4476 /* set manual connection */
4477 /* we have only a switch on HP-out PIN */
4478 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
4479 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4480 if (err < 0)
4481 return err;
4482 }
4483 return 0;
4484}
4485
4486/* create input playback/capture controls for the given pin */
4487static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4488 const char *ctlname,
4489 int idx, hda_nid_t mix_nid)
4490{
4491 int err;
4492
4493 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
4494 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4495 if (err < 0)
4496 return err;
4497 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
4498 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4499 if (err < 0)
4500 return err;
4501 return 0;
4502}
4503
4504static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4505{
4506 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4507 return (pincap & AC_PINCAP_IN) != 0;
4508}
4509
4510/* create playback/capture controls for input pins */
4511static int alc_auto_create_input_ctls(struct hda_codec *codec,
4512 const struct auto_pin_cfg *cfg,
4513 hda_nid_t mixer,
4514 hda_nid_t cap1, hda_nid_t cap2)
4515{
4516 struct alc_spec *spec = codec->spec;
4517 struct hda_input_mux *imux = &spec->private_imux[0];
4518 int i, err, idx;
4519
4520 for (i = 0; i < AUTO_PIN_LAST; i++) {
4521 hda_nid_t pin;
4522
4523 pin = cfg->input_pins[i];
4524 if (!alc_is_input_pin(codec, pin))
4525 continue;
4526
4527 if (mixer) {
4528 idx = get_connection_index(codec, mixer, pin);
4529 if (idx >= 0) {
4530 err = new_analog_input(spec, pin,
4531 auto_pin_cfg_labels[i],
4532 idx, mixer);
4533 if (err < 0)
4534 return err;
4535 }
4536 }
4537
4538 if (!cap1)
4539 continue;
4540 idx = get_connection_index(codec, cap1, pin);
4541 if (idx < 0 && cap2)
4542 idx = get_connection_index(codec, cap2, pin);
4543 if (idx >= 0) {
4544 imux->items[imux->num_items].label =
4545 auto_pin_cfg_labels[i];
4546 imux->items[imux->num_items].index = idx;
4547 imux->num_items++;
4548 }
4549 }
4550 return 0;
4551}
4552
4553static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4554 const struct auto_pin_cfg *cfg)
4555{
4556 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4557}
4558
4559static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4560 unsigned int pin_type)
4561{
4562 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4563 pin_type);
4564 /* unmute pin */
4565 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4566 AMP_OUT_UNMUTE);
4567}
4568
4569static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4570 hda_nid_t nid, int pin_type,
4571 int dac_idx)
4572{
4573 alc_set_pin_output(codec, nid, pin_type);
4574 /* need the manual connection? */
4575 if (alc880_is_multi_pin(nid)) {
4576 struct alc_spec *spec = codec->spec;
4577 int idx = alc880_multi_pin_idx(nid);
4578 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4579 AC_VERB_SET_CONNECT_SEL,
4580 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4581 }
4582}
4583
4584static int get_pin_type(int line_out_type)
4585{
4586 if (line_out_type == AUTO_PIN_HP_OUT)
4587 return PIN_HP;
4588 else
4589 return PIN_OUT;
4590}
4591
4592static void alc880_auto_init_multi_out(struct hda_codec *codec)
4593{
4594 struct alc_spec *spec = codec->spec;
4595 int i;
4596
4597 for (i = 0; i < spec->autocfg.line_outs; i++) {
4598 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4599 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4600 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4601 }
4602}
4603
4604static void alc880_auto_init_extra_out(struct hda_codec *codec)
4605{
4606 struct alc_spec *spec = codec->spec;
4607 hda_nid_t pin;
4608
4609 pin = spec->autocfg.speaker_pins[0];
4610 if (pin) /* connect to front */
4611 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4612 pin = spec->autocfg.hp_pins[0];
4613 if (pin) /* connect to front */
4614 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4615}
4616
4617static void alc880_auto_init_analog_input(struct hda_codec *codec)
4618{
4619 struct alc_spec *spec = codec->spec;
4620 int i;
4621
4622 for (i = 0; i < AUTO_PIN_LAST; i++) {
4623 hda_nid_t nid = spec->autocfg.input_pins[i];
4624 if (alc_is_input_pin(codec, nid)) {
4625 alc_set_input_pin(codec, nid, i);
4626 if (nid != ALC880_PIN_CD_NID &&
4627 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4628 snd_hda_codec_write(codec, nid, 0,
4629 AC_VERB_SET_AMP_GAIN_MUTE,
4630 AMP_OUT_MUTE);
4631 }
4632 }
4633}
4634
4635/* parse the BIOS configuration and set up the alc_spec */
4636/* return 1 if successful, 0 if the proper config is not found,
4637 * or a negative error code
4638 */
4639static int alc880_parse_auto_config(struct hda_codec *codec)
4640{
4641 struct alc_spec *spec = codec->spec;
4642 int i, err;
4643 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4644
4645 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4646 alc880_ignore);
4647 if (err < 0)
4648 return err;
4649 if (!spec->autocfg.line_outs)
4650 return 0; /* can't find valid BIOS pin config */
4651
4652 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4653 if (err < 0)
4654 return err;
4655 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4656 if (err < 0)
4657 return err;
4658 err = alc880_auto_create_extra_out(spec,
4659 spec->autocfg.speaker_pins[0],
4660 "Speaker");
4661 if (err < 0)
4662 return err;
4663 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4664 "Headphone");
4665 if (err < 0)
4666 return err;
4667 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4668 if (err < 0)
4669 return err;
4670
4671 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4672
4673 /* check multiple SPDIF-out (for recent codecs) */
4674 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4675 hda_nid_t dig_nid;
4676 err = snd_hda_get_connections(codec,
4677 spec->autocfg.dig_out_pins[i],
4678 &dig_nid, 1);
4679 if (err < 0)
4680 continue;
4681 if (!i)
4682 spec->multiout.dig_out_nid = dig_nid;
4683 else {
4684 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4685 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4686 break;
4687 spec->slave_dig_outs[i - 1] = dig_nid;
4688 }
4689 }
4690 if (spec->autocfg.dig_in_pin)
4691 spec->dig_in_nid = ALC880_DIGIN_NID;
4692
4693 if (spec->kctls.list)
4694 add_mixer(spec, spec->kctls.list);
4695
4696 add_verb(spec, alc880_volume_init_verbs);
4697
4698 spec->num_mux_defs = 1;
4699 spec->input_mux = &spec->private_imux[0];
4700
4701 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4702
4703 return 1;
4704}
4705
4706/* additional initialization for auto-configuration model */
4707static void alc880_auto_init(struct hda_codec *codec)
4708{
4709 struct alc_spec *spec = codec->spec;
4710 alc880_auto_init_multi_out(codec);
4711 alc880_auto_init_extra_out(codec);
4712 alc880_auto_init_analog_input(codec);
4713 if (spec->unsol_event)
4714 alc_inithook(codec);
4715}
4716
4717/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4718 * one of two digital mic pins, e.g. on ALC272
4719 */
4720static void fixup_automic_adc(struct hda_codec *codec)
4721{
4722 struct alc_spec *spec = codec->spec;
4723 int i;
4724
4725 for (i = 0; i < spec->num_adc_nids; i++) {
4726 hda_nid_t cap = spec->capsrc_nids ?
4727 spec->capsrc_nids[i] : spec->adc_nids[i];
4728 int iidx, eidx;
4729
4730 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4731 if (iidx < 0)
4732 continue;
4733 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4734 if (eidx < 0)
4735 continue;
4736 spec->int_mic.mux_idx = iidx;
4737 spec->ext_mic.mux_idx = eidx;
4738 if (spec->capsrc_nids)
4739 spec->capsrc_nids += i;
4740 spec->adc_nids += i;
4741 spec->num_adc_nids = 1;
4742 return;
4743 }
4744 snd_printd(KERN_INFO "hda_codec: %s: "
4745 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
4746 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
4747 spec->auto_mic = 0; /* disable auto-mic to be sure */
4748}
4749
4750static void set_capture_mixer(struct hda_codec *codec)
4751{
4752 struct alc_spec *spec = codec->spec;
4753 static struct snd_kcontrol_new *caps[2][3] = {
4754 { alc_capture_mixer_nosrc1,
4755 alc_capture_mixer_nosrc2,
4756 alc_capture_mixer_nosrc3 },
4757 { alc_capture_mixer1,
4758 alc_capture_mixer2,
4759 alc_capture_mixer3 },
4760 };
4761 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4762 int mux;
4763 if (spec->auto_mic) {
4764 mux = 0;
4765 fixup_automic_adc(codec);
4766 } else if (spec->input_mux && spec->input_mux->num_items > 1)
4767 mux = 1;
4768 else
4769 mux = 0;
4770 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4771 }
4772}
4773
4774#ifdef CONFIG_SND_HDA_INPUT_BEEP
4775#define set_beep_amp(spec, nid, idx, dir) \
4776 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4777#else
4778#define set_beep_amp(spec, nid, idx, dir) /* NOP */
4779#endif
4780
4781/*
4782 * OK, here we have finally the patch for ALC880
4783 */
4784
4785static int patch_alc880(struct hda_codec *codec)
4786{
4787 struct alc_spec *spec;
4788 int board_config;
4789 int err;
4790
4791 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4792 if (spec == NULL)
4793 return -ENOMEM;
4794
4795 codec->spec = spec;
4796
4797 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4798 alc880_models,
4799 alc880_cfg_tbl);
4800 if (board_config < 0) {
4801 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4802 codec->chip_name);
4803 board_config = ALC880_AUTO;
4804 }
4805
4806 if (board_config == ALC880_AUTO) {
4807 /* automatic parse from the BIOS config */
4808 err = alc880_parse_auto_config(codec);
4809 if (err < 0) {
4810 alc_free(codec);
4811 return err;
4812 } else if (!err) {
4813 printk(KERN_INFO
4814 "hda_codec: Cannot set up configuration "
4815 "from BIOS. Using 3-stack mode...\n");
4816 board_config = ALC880_3ST;
4817 }
4818 }
4819
4820 err = snd_hda_attach_beep_device(codec, 0x1);
4821 if (err < 0) {
4822 alc_free(codec);
4823 return err;
4824 }
4825
4826 if (board_config != ALC880_AUTO)
4827 setup_preset(codec, &alc880_presets[board_config]);
4828
4829 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4830 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4831 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4832
4833 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4834 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4835
4836 if (!spec->adc_nids && spec->input_mux) {
4837 /* check whether NID 0x07 is valid */
4838 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4839 /* get type */
4840 wcap = get_wcaps_type(wcap);
4841 if (wcap != AC_WID_AUD_IN) {
4842 spec->adc_nids = alc880_adc_nids_alt;
4843 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4844 } else {
4845 spec->adc_nids = alc880_adc_nids;
4846 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4847 }
4848 }
4849 set_capture_mixer(codec);
4850 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4851
4852 spec->vmaster_nid = 0x0c;
4853
4854 codec->patch_ops = alc_patch_ops;
4855 if (board_config == ALC880_AUTO)
4856 spec->init_hook = alc880_auto_init;
4857#ifdef CONFIG_SND_HDA_POWER_SAVE
4858 if (!spec->loopback.amplist)
4859 spec->loopback.amplist = alc880_loopbacks;
4860#endif
4861 codec->proc_widget_hook = print_realtek_coef;
4862
4863 return 0;
4864}
4865
4866
4867/*
4868 * ALC260 support
4869 */
4870
4871static hda_nid_t alc260_dac_nids[1] = {
4872 /* front */
4873 0x02,
4874};
4875
4876static hda_nid_t alc260_adc_nids[1] = {
4877 /* ADC0 */
4878 0x04,
4879};
4880
4881static hda_nid_t alc260_adc_nids_alt[1] = {
4882 /* ADC1 */
4883 0x05,
4884};
4885
4886/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4887 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4888 */
4889static hda_nid_t alc260_dual_adc_nids[2] = {
4890 /* ADC0, ADC1 */
4891 0x04, 0x05
4892};
4893
4894#define ALC260_DIGOUT_NID 0x03
4895#define ALC260_DIGIN_NID 0x06
4896
4897static struct hda_input_mux alc260_capture_source = {
4898 .num_items = 4,
4899 .items = {
4900 { "Mic", 0x0 },
4901 { "Front Mic", 0x1 },
4902 { "Line", 0x2 },
4903 { "CD", 0x4 },
4904 },
4905};
4906
4907/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4908 * headphone jack and the internal CD lines since these are the only pins at
4909 * which audio can appear. For flexibility, also allow the option of
4910 * recording the mixer output on the second ADC (ADC0 doesn't have a
4911 * connection to the mixer output).
4912 */
4913static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4914 {
4915 .num_items = 3,
4916 .items = {
4917 { "Mic/Line", 0x0 },
4918 { "CD", 0x4 },
4919 { "Headphone", 0x2 },
4920 },
4921 },
4922 {
4923 .num_items = 4,
4924 .items = {
4925 { "Mic/Line", 0x0 },
4926 { "CD", 0x4 },
4927 { "Headphone", 0x2 },
4928 { "Mixer", 0x5 },
4929 },
4930 },
4931
4932};
4933
4934/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4935 * the Fujitsu S702x, but jacks are marked differently.
4936 */
4937static struct hda_input_mux alc260_acer_capture_sources[2] = {
4938 {
4939 .num_items = 4,
4940 .items = {
4941 { "Mic", 0x0 },
4942 { "Line", 0x2 },
4943 { "CD", 0x4 },
4944 { "Headphone", 0x5 },
4945 },
4946 },
4947 {
4948 .num_items = 5,
4949 .items = {
4950 { "Mic", 0x0 },
4951 { "Line", 0x2 },
4952 { "CD", 0x4 },
4953 { "Headphone", 0x6 },
4954 { "Mixer", 0x5 },
4955 },
4956 },
4957};
4958
4959/* Maxdata Favorit 100XS */
4960static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4961 {
4962 .num_items = 2,
4963 .items = {
4964 { "Line/Mic", 0x0 },
4965 { "CD", 0x4 },
4966 },
4967 },
4968 {
4969 .num_items = 3,
4970 .items = {
4971 { "Line/Mic", 0x0 },
4972 { "CD", 0x4 },
4973 { "Mixer", 0x5 },
4974 },
4975 },
4976};
4977
4978/*
4979 * This is just place-holder, so there's something for alc_build_pcms to look
4980 * at when it calculates the maximum number of channels. ALC260 has no mixer
4981 * element which allows changing the channel mode, so the verb list is
4982 * never used.
4983 */
4984static struct hda_channel_mode alc260_modes[1] = {
4985 { 2, NULL },
4986};
4987
4988
4989/* Mixer combinations
4990 *
4991 * basic: base_output + input + pc_beep + capture
4992 * HP: base_output + input + capture_alt
4993 * HP_3013: hp_3013 + input + capture
4994 * fujitsu: fujitsu + capture
4995 * acer: acer + capture
4996 */
4997
4998static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4999 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5000 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5001 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5002 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5003 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5004 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5005 { } /* end */
5006};
5007
5008static struct snd_kcontrol_new alc260_input_mixer[] = {
5009 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5010 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5011 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5012 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5013 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5014 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5015 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5016 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5017 { } /* end */
5018};
5019
5020/* update HP, line and mono out pins according to the master switch */
5021static void alc260_hp_master_update(struct hda_codec *codec,
5022 hda_nid_t hp, hda_nid_t line,
5023 hda_nid_t mono)
5024{
5025 struct alc_spec *spec = codec->spec;
5026 unsigned int val = spec->master_sw ? PIN_HP : 0;
5027 /* change HP and line-out pins */
5028 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5029 val);
5030 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5031 val);
5032 /* mono (speaker) depending on the HP jack sense */
5033 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5034 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5035 val);
5036}
5037
5038static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5039 struct snd_ctl_elem_value *ucontrol)
5040{
5041 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5042 struct alc_spec *spec = codec->spec;
5043 *ucontrol->value.integer.value = spec->master_sw;
5044 return 0;
5045}
5046
5047static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5048 struct snd_ctl_elem_value *ucontrol)
5049{
5050 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5051 struct alc_spec *spec = codec->spec;
5052 int val = !!*ucontrol->value.integer.value;
5053 hda_nid_t hp, line, mono;
5054
5055 if (val == spec->master_sw)
5056 return 0;
5057 spec->master_sw = val;
5058 hp = (kcontrol->private_value >> 16) & 0xff;
5059 line = (kcontrol->private_value >> 8) & 0xff;
5060 mono = kcontrol->private_value & 0xff;
5061 alc260_hp_master_update(codec, hp, line, mono);
5062 return 1;
5063}
5064
5065static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5066 {
5067 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5068 .name = "Master Playback Switch",
5069 .info = snd_ctl_boolean_mono_info,
5070 .get = alc260_hp_master_sw_get,
5071 .put = alc260_hp_master_sw_put,
5072 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5073 },
5074 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5075 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5076 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5077 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5078 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5079 HDA_OUTPUT),
5080 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5081 { } /* end */
5082};
5083
5084static struct hda_verb alc260_hp_unsol_verbs[] = {
5085 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5086 {},
5087};
5088
5089static void alc260_hp_automute(struct hda_codec *codec)
5090{
5091 struct alc_spec *spec = codec->spec;
5092
5093 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5094 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5095}
5096
5097static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5098{
5099 if ((res >> 26) == ALC880_HP_EVENT)
5100 alc260_hp_automute(codec);
5101}
5102
5103static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5104 {
5105 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5106 .name = "Master Playback Switch",
5107 .info = snd_ctl_boolean_mono_info,
5108 .get = alc260_hp_master_sw_get,
5109 .put = alc260_hp_master_sw_put,
5110 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5111 },
5112 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5113 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5114 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5115 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5116 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5117 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5118 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5119 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5120 { } /* end */
5121};
5122
5123static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5124 .ops = &snd_hda_bind_vol,
5125 .values = {
5126 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5127 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5128 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5129 0
5130 },
5131};
5132
5133static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5134 .ops = &snd_hda_bind_sw,
5135 .values = {
5136 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5137 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5138 0
5139 },
5140};
5141
5142static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5143 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5144 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5145 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5147 { } /* end */
5148};
5149
5150static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5151 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5152 {},
5153};
5154
5155static void alc260_hp_3013_automute(struct hda_codec *codec)
5156{
5157 struct alc_spec *spec = codec->spec;
5158
5159 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
5160 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5161}
5162
5163static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5164 unsigned int res)
5165{
5166 if ((res >> 26) == ALC880_HP_EVENT)
5167 alc260_hp_3013_automute(codec);
5168}
5169
5170static void alc260_hp_3012_automute(struct hda_codec *codec)
5171{
5172 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5173
5174 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5175 bits);
5176 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5177 bits);
5178 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5179 bits);
5180}
5181
5182static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5183 unsigned int res)
5184{
5185 if ((res >> 26) == ALC880_HP_EVENT)
5186 alc260_hp_3012_automute(codec);
5187}
5188
5189/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5190 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5191 */
5192static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5194 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5195 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5196 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5197 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5198 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5199 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5200 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5201 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5202 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5203 { } /* end */
5204};
5205
5206/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5207 * versions of the ALC260 don't act on requests to enable mic bias from NID
5208 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5209 * datasheet doesn't mention this restriction. At this stage it's not clear
5210 * whether this behaviour is intentional or is a hardware bug in chip
5211 * revisions available in early 2006. Therefore for now allow the
5212 * "Headphone Jack Mode" control to span all choices, but if it turns out
5213 * that the lack of mic bias for this NID is intentional we could change the
5214 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5215 *
5216 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5217 * don't appear to make the mic bias available from the "line" jack, even
5218 * though the NID used for this jack (0x14) can supply it. The theory is
5219 * that perhaps Acer have included blocking capacitors between the ALC260
5220 * and the output jack. If this turns out to be the case for all such
5221 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5222 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5223 *
5224 * The C20x Tablet series have a mono internal speaker which is controlled
5225 * via the chip's Mono sum widget and pin complex, so include the necessary
5226 * controls for such models. On models without a "mono speaker" the control
5227 * won't do anything.
5228 */
5229static struct snd_kcontrol_new alc260_acer_mixer[] = {
5230 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5231 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5232 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5233 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5234 HDA_OUTPUT),
5235 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5236 HDA_INPUT),
5237 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5238 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5240 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5241 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5242 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5243 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5244 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5245 { } /* end */
5246};
5247
5248/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5249 */
5250static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5251 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5252 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5253 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5254 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5255 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5256 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5257 { } /* end */
5258};
5259
5260/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5261 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5262 */
5263static struct snd_kcontrol_new alc260_will_mixer[] = {
5264 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5265 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5267 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5268 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5269 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5270 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5271 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5272 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5273 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5274 { } /* end */
5275};
5276
5277/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5278 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5279 */
5280static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5281 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5282 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5283 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5284 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5285 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5286 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5287 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5288 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5289 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5290 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5291 { } /* end */
5292};
5293
5294/*
5295 * initialization verbs
5296 */
5297static struct hda_verb alc260_init_verbs[] = {
5298 /* Line In pin widget for input */
5299 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5300 /* CD pin widget for input */
5301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5302 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5303 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5304 /* Mic2 (front panel) pin widget for input and vref at 80% */
5305 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5306 /* LINE-2 is used for line-out in rear */
5307 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5308 /* select line-out */
5309 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5310 /* LINE-OUT pin */
5311 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5312 /* enable HP */
5313 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5314 /* enable Mono */
5315 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5316 /* mute capture amp left and right */
5317 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5318 /* set connection select to line in (default select for this ADC) */
5319 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5320 /* mute capture amp left and right */
5321 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5322 /* set connection select to line in (default select for this ADC) */
5323 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5324 /* set vol=0 Line-Out mixer amp left and right */
5325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5326 /* unmute pin widget amp left and right (no gain on this amp) */
5327 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5328 /* set vol=0 HP mixer amp left and right */
5329 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5330 /* unmute pin widget amp left and right (no gain on this amp) */
5331 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5332 /* set vol=0 Mono mixer amp left and right */
5333 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5334 /* unmute pin widget amp left and right (no gain on this amp) */
5335 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5336 /* unmute LINE-2 out pin */
5337 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5338 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5339 * Line In 2 = 0x03
5340 */
5341 /* mute analog inputs */
5342 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5343 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5344 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5346 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5347 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5348 /* mute Front out path */
5349 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5350 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5351 /* mute Headphone out path */
5352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5353 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5354 /* mute Mono out path */
5355 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5356 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5357 { }
5358};
5359
5360#if 0 /* should be identical with alc260_init_verbs? */
5361static struct hda_verb alc260_hp_init_verbs[] = {
5362 /* Headphone and output */
5363 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5364 /* mono output */
5365 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5366 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5367 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5368 /* Mic2 (front panel) pin widget for input and vref at 80% */
5369 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5370 /* Line In pin widget for input */
5371 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5372 /* Line-2 pin widget for output */
5373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5374 /* CD pin widget for input */
5375 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5376 /* unmute amp left and right */
5377 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5378 /* set connection select to line in (default select for this ADC) */
5379 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5380 /* unmute Line-Out mixer amp left and right (volume = 0) */
5381 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5382 /* mute pin widget amp left and right (no gain on this amp) */
5383 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5384 /* unmute HP mixer amp left and right (volume = 0) */
5385 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5386 /* mute pin widget amp left and right (no gain on this amp) */
5387 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5388 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5389 * Line In 2 = 0x03
5390 */
5391 /* mute analog inputs */
5392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5393 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5394 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5395 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5397 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5398 /* Unmute Front out path */
5399 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5400 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5401 /* Unmute Headphone out path */
5402 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5403 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5404 /* Unmute Mono out path */
5405 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5406 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5407 { }
5408};
5409#endif
5410
5411static struct hda_verb alc260_hp_3013_init_verbs[] = {
5412 /* Line out and output */
5413 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5414 /* mono output */
5415 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5416 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5417 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5418 /* Mic2 (front panel) pin widget for input and vref at 80% */
5419 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5420 /* Line In pin widget for input */
5421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5422 /* Headphone pin widget for output */
5423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5424 /* CD pin widget for input */
5425 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5426 /* unmute amp left and right */
5427 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5428 /* set connection select to line in (default select for this ADC) */
5429 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5430 /* unmute Line-Out mixer amp left and right (volume = 0) */
5431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5432 /* mute pin widget amp left and right (no gain on this amp) */
5433 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5434 /* unmute HP mixer amp left and right (volume = 0) */
5435 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5436 /* mute pin widget amp left and right (no gain on this amp) */
5437 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5438 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5439 * Line In 2 = 0x03
5440 */
5441 /* mute analog inputs */
5442 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5443 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5444 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5445 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5447 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5448 /* Unmute Front out path */
5449 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5450 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5451 /* Unmute Headphone out path */
5452 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5453 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5454 /* Unmute Mono out path */
5455 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5456 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5457 { }
5458};
5459
5460/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5461 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5462 * audio = 0x16, internal speaker = 0x10.
5463 */
5464static struct hda_verb alc260_fujitsu_init_verbs[] = {
5465 /* Disable all GPIOs */
5466 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5467 /* Internal speaker is connected to headphone pin */
5468 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5469 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5470 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5471 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5473 /* Ensure all other unused pins are disabled and muted. */
5474 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5475 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5476 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5477 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5478 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5479 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5482
5483 /* Disable digital (SPDIF) pins */
5484 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5485 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5486
5487 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5488 * when acting as an output.
5489 */
5490 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5491
5492 /* Start with output sum widgets muted and their output gains at min */
5493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5498 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5500 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5501 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5502
5503 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5504 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5505 /* Unmute Line1 pin widget output buffer since it starts as an output.
5506 * If the pin mode is changed by the user the pin mode control will
5507 * take care of enabling the pin's input/output buffers as needed.
5508 * Therefore there's no need to enable the input buffer at this
5509 * stage.
5510 */
5511 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5512 /* Unmute input buffer of pin widget used for Line-in (no equiv
5513 * mixer ctrl)
5514 */
5515 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5516
5517 /* Mute capture amp left and right */
5518 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5519 /* Set ADC connection select to match default mixer setting - line
5520 * in (on mic1 pin)
5521 */
5522 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5523
5524 /* Do the same for the second ADC: mute capture input amp and
5525 * set ADC connection to line in (on mic1 pin)
5526 */
5527 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5528 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5529
5530 /* Mute all inputs to mixer widget (even unconnected ones) */
5531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5538 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5539
5540 { }
5541};
5542
5543/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5544 * similar laptops (adapted from Fujitsu init verbs).
5545 */
5546static struct hda_verb alc260_acer_init_verbs[] = {
5547 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5548 * the headphone jack. Turn this on and rely on the standard mute
5549 * methods whenever the user wants to turn these outputs off.
5550 */
5551 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5552 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5553 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5554 /* Internal speaker/Headphone jack is connected to Line-out pin */
5555 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5556 /* Internal microphone/Mic jack is connected to Mic1 pin */
5557 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5558 /* Line In jack is connected to Line1 pin */
5559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5560 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5561 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5562 /* Ensure all other unused pins are disabled and muted. */
5563 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5564 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5565 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5566 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5567 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5568 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5569 /* Disable digital (SPDIF) pins */
5570 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5571 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5572
5573 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5574 * bus when acting as outputs.
5575 */
5576 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5577 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5578
5579 /* Start with output sum widgets muted and their output gains at min */
5580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5581 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5582 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5584 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5585 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5587 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5588 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5589
5590 /* Unmute Line-out pin widget amp left and right
5591 * (no equiv mixer ctrl)
5592 */
5593 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5594 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5595 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5596 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5597 * inputs. If the pin mode is changed by the user the pin mode control
5598 * will take care of enabling the pin's input/output buffers as needed.
5599 * Therefore there's no need to enable the input buffer at this
5600 * stage.
5601 */
5602 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5603 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5604
5605 /* Mute capture amp left and right */
5606 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5607 /* Set ADC connection select to match default mixer setting - mic
5608 * (on mic1 pin)
5609 */
5610 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5611
5612 /* Do similar with the second ADC: mute capture input amp and
5613 * set ADC connection to mic to match ALSA's default state.
5614 */
5615 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5616 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5617
5618 /* Mute all inputs to mixer widget (even unconnected ones) */
5619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5627
5628 { }
5629};
5630
5631/* Initialisation sequence for Maxdata Favorit 100XS
5632 * (adapted from Acer init verbs).
5633 */
5634static struct hda_verb alc260_favorit100_init_verbs[] = {
5635 /* GPIO 0 enables the output jack.
5636 * Turn this on and rely on the standard mute
5637 * methods whenever the user wants to turn these outputs off.
5638 */
5639 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5640 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5641 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5642 /* Line/Mic input jack is connected to Mic1 pin */
5643 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5644 /* Ensure all other unused pins are disabled and muted. */
5645 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5646 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5647 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5648 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5649 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5650 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5652 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5655 /* Disable digital (SPDIF) pins */
5656 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5657 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5658
5659 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5660 * bus when acting as outputs.
5661 */
5662 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5663 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5664
5665 /* Start with output sum widgets muted and their output gains at min */
5666 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5668 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5669 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5670 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5671 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5672 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5673 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5674 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5675
5676 /* Unmute Line-out pin widget amp left and right
5677 * (no equiv mixer ctrl)
5678 */
5679 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5680 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5681 * inputs. If the pin mode is changed by the user the pin mode control
5682 * will take care of enabling the pin's input/output buffers as needed.
5683 * Therefore there's no need to enable the input buffer at this
5684 * stage.
5685 */
5686 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5687
5688 /* Mute capture amp left and right */
5689 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5690 /* Set ADC connection select to match default mixer setting - mic
5691 * (on mic1 pin)
5692 */
5693 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5694
5695 /* Do similar with the second ADC: mute capture input amp and
5696 * set ADC connection to mic to match ALSA's default state.
5697 */
5698 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5699 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5700
5701 /* Mute all inputs to mixer widget (even unconnected ones) */
5702 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5709 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5710
5711 { }
5712};
5713
5714static struct hda_verb alc260_will_verbs[] = {
5715 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5716 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5717 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5718 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5719 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5720 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5721 {}
5722};
5723
5724static struct hda_verb alc260_replacer_672v_verbs[] = {
5725 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5726 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5727 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5728
5729 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5730 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5731 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5732
5733 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5734 {}
5735};
5736
5737/* toggle speaker-output according to the hp-jack state */
5738static void alc260_replacer_672v_automute(struct hda_codec *codec)
5739{
5740 unsigned int present;
5741
5742 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5743 present = snd_hda_jack_detect(codec, 0x0f);
5744 if (present) {
5745 snd_hda_codec_write_cache(codec, 0x01, 0,
5746 AC_VERB_SET_GPIO_DATA, 1);
5747 snd_hda_codec_write_cache(codec, 0x0f, 0,
5748 AC_VERB_SET_PIN_WIDGET_CONTROL,
5749 PIN_HP);
5750 } else {
5751 snd_hda_codec_write_cache(codec, 0x01, 0,
5752 AC_VERB_SET_GPIO_DATA, 0);
5753 snd_hda_codec_write_cache(codec, 0x0f, 0,
5754 AC_VERB_SET_PIN_WIDGET_CONTROL,
5755 PIN_OUT);
5756 }
5757}
5758
5759static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5760 unsigned int res)
5761{
5762 if ((res >> 26) == ALC880_HP_EVENT)
5763 alc260_replacer_672v_automute(codec);
5764}
5765
5766static struct hda_verb alc260_hp_dc7600_verbs[] = {
5767 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5768 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5769 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5770 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5771 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5772 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5773 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5774 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5775 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5776 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5777 {}
5778};
5779
5780/* Test configuration for debugging, modelled after the ALC880 test
5781 * configuration.
5782 */
5783#ifdef CONFIG_SND_DEBUG
5784static hda_nid_t alc260_test_dac_nids[1] = {
5785 0x02,
5786};
5787static hda_nid_t alc260_test_adc_nids[2] = {
5788 0x04, 0x05,
5789};
5790/* For testing the ALC260, each input MUX needs its own definition since
5791 * the signal assignments are different. This assumes that the first ADC
5792 * is NID 0x04.
5793 */
5794static struct hda_input_mux alc260_test_capture_sources[2] = {
5795 {
5796 .num_items = 7,
5797 .items = {
5798 { "MIC1 pin", 0x0 },
5799 { "MIC2 pin", 0x1 },
5800 { "LINE1 pin", 0x2 },
5801 { "LINE2 pin", 0x3 },
5802 { "CD pin", 0x4 },
5803 { "LINE-OUT pin", 0x5 },
5804 { "HP-OUT pin", 0x6 },
5805 },
5806 },
5807 {
5808 .num_items = 8,
5809 .items = {
5810 { "MIC1 pin", 0x0 },
5811 { "MIC2 pin", 0x1 },
5812 { "LINE1 pin", 0x2 },
5813 { "LINE2 pin", 0x3 },
5814 { "CD pin", 0x4 },
5815 { "Mixer", 0x5 },
5816 { "LINE-OUT pin", 0x6 },
5817 { "HP-OUT pin", 0x7 },
5818 },
5819 },
5820};
5821static struct snd_kcontrol_new alc260_test_mixer[] = {
5822 /* Output driver widgets */
5823 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5824 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5825 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5826 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5827 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5828 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5829
5830 /* Modes for retasking pin widgets
5831 * Note: the ALC260 doesn't seem to act on requests to enable mic
5832 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5833 * mention this restriction. At this stage it's not clear whether
5834 * this behaviour is intentional or is a hardware bug in chip
5835 * revisions available at least up until early 2006. Therefore for
5836 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5837 * choices, but if it turns out that the lack of mic bias for these
5838 * NIDs is intentional we could change their modes from
5839 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5840 */
5841 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5842 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5843 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5844 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5845 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5846 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5847
5848 /* Loopback mixer controls */
5849 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5850 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5851 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5852 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5853 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5854 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5855 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5856 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5857 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5858 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5859 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5860 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5861 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5862 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5863
5864 /* Controls for GPIO pins, assuming they are configured as outputs */
5865 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5866 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5867 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5868 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5869
5870 /* Switches to allow the digital IO pins to be enabled. The datasheet
5871 * is ambigious as to which NID is which; testing on laptops which
5872 * make this output available should provide clarification.
5873 */
5874 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5875 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5876
5877 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5878 * this output to turn on an external amplifier.
5879 */
5880 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5881 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5882
5883 { } /* end */
5884};
5885static struct hda_verb alc260_test_init_verbs[] = {
5886 /* Enable all GPIOs as outputs with an initial value of 0 */
5887 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5888 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5889 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5890
5891 /* Enable retasking pins as output, initially without power amp */
5892 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5893 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5894 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5896 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5897 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5898
5899 /* Disable digital (SPDIF) pins initially, but users can enable
5900 * them via a mixer switch. In the case of SPDIF-out, this initverb
5901 * payload also sets the generation to 0, output to be in "consumer"
5902 * PCM format, copyright asserted, no pre-emphasis and no validity
5903 * control.
5904 */
5905 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5906 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5907
5908 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5909 * OUT1 sum bus when acting as an output.
5910 */
5911 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5912 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5913 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5914 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5915
5916 /* Start with output sum widgets muted and their output gains at min */
5917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5918 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5919 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5921 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5922 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5923 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5924 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5925 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5926
5927 /* Unmute retasking pin widget output buffers since the default
5928 * state appears to be output. As the pin mode is changed by the
5929 * user the pin mode control will take care of enabling the pin's
5930 * input/output buffers as needed.
5931 */
5932 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5933 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5934 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5935 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5936 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5937 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5938 /* Also unmute the mono-out pin widget */
5939 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5940
5941 /* Mute capture amp left and right */
5942 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5943 /* Set ADC connection select to match default mixer setting (mic1
5944 * pin)
5945 */
5946 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5947
5948 /* Do the same for the second ADC: mute capture input amp and
5949 * set ADC connection to mic1 pin
5950 */
5951 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5952 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5953
5954 /* Mute all inputs to mixer widget (even unconnected ones) */
5955 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5956 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5957 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5958 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5963
5964 { }
5965};
5966#endif
5967
5968#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5969#define alc260_pcm_analog_capture alc880_pcm_analog_capture
5970
5971#define alc260_pcm_digital_playback alc880_pcm_digital_playback
5972#define alc260_pcm_digital_capture alc880_pcm_digital_capture
5973
5974/*
5975 * for BIOS auto-configuration
5976 */
5977
5978static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5979 const char *pfx, int *vol_bits)
5980{
5981 hda_nid_t nid_vol;
5982 unsigned long vol_val, sw_val;
5983 int err;
5984
5985 if (nid >= 0x0f && nid < 0x11) {
5986 nid_vol = nid - 0x7;
5987 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5988 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5989 } else if (nid == 0x11) {
5990 nid_vol = nid - 0x7;
5991 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5992 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5993 } else if (nid >= 0x12 && nid <= 0x15) {
5994 nid_vol = 0x08;
5995 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5996 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5997 } else
5998 return 0; /* N/A */
5999
6000 if (!(*vol_bits & (1 << nid_vol))) {
6001 /* first control for the volume widget */
6002 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6003 if (err < 0)
6004 return err;
6005 *vol_bits |= (1 << nid_vol);
6006 }
6007 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6008 if (err < 0)
6009 return err;
6010 return 1;
6011}
6012
6013/* add playback controls from the parsed DAC table */
6014static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6015 const struct auto_pin_cfg *cfg)
6016{
6017 hda_nid_t nid;
6018 int err;
6019 int vols = 0;
6020
6021 spec->multiout.num_dacs = 1;
6022 spec->multiout.dac_nids = spec->private_dac_nids;
6023 spec->multiout.dac_nids[0] = 0x02;
6024
6025 nid = cfg->line_out_pins[0];
6026 if (nid) {
6027 const char *pfx;
6028 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6029 pfx = "Master";
6030 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6031 pfx = "Speaker";
6032 else
6033 pfx = "Front";
6034 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6035 if (err < 0)
6036 return err;
6037 }
6038
6039 nid = cfg->speaker_pins[0];
6040 if (nid) {
6041 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6042 if (err < 0)
6043 return err;
6044 }
6045
6046 nid = cfg->hp_pins[0];
6047 if (nid) {
6048 err = alc260_add_playback_controls(spec, nid, "Headphone",
6049 &vols);
6050 if (err < 0)
6051 return err;
6052 }
6053 return 0;
6054}
6055
6056/* create playback/capture controls for input pins */
6057static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6058 const struct auto_pin_cfg *cfg)
6059{
6060 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6061}
6062
6063static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6064 hda_nid_t nid, int pin_type,
6065 int sel_idx)
6066{
6067 alc_set_pin_output(codec, nid, pin_type);
6068 /* need the manual connection? */
6069 if (nid >= 0x12) {
6070 int idx = nid - 0x12;
6071 snd_hda_codec_write(codec, idx + 0x0b, 0,
6072 AC_VERB_SET_CONNECT_SEL, sel_idx);
6073 }
6074}
6075
6076static void alc260_auto_init_multi_out(struct hda_codec *codec)
6077{
6078 struct alc_spec *spec = codec->spec;
6079 hda_nid_t nid;
6080
6081 nid = spec->autocfg.line_out_pins[0];
6082 if (nid) {
6083 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6084 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6085 }
6086
6087 nid = spec->autocfg.speaker_pins[0];
6088 if (nid)
6089 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6090
6091 nid = spec->autocfg.hp_pins[0];
6092 if (nid)
6093 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6094}
6095
6096#define ALC260_PIN_CD_NID 0x16
6097static void alc260_auto_init_analog_input(struct hda_codec *codec)
6098{
6099 struct alc_spec *spec = codec->spec;
6100 int i;
6101
6102 for (i = 0; i < AUTO_PIN_LAST; i++) {
6103 hda_nid_t nid = spec->autocfg.input_pins[i];
6104 if (nid >= 0x12) {
6105 alc_set_input_pin(codec, nid, i);
6106 if (nid != ALC260_PIN_CD_NID &&
6107 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6108 snd_hda_codec_write(codec, nid, 0,
6109 AC_VERB_SET_AMP_GAIN_MUTE,
6110 AMP_OUT_MUTE);
6111 }
6112 }
6113}
6114
6115/*
6116 * generic initialization of ADC, input mixers and output mixers
6117 */
6118static struct hda_verb alc260_volume_init_verbs[] = {
6119 /*
6120 * Unmute ADC0-1 and set the default input to mic-in
6121 */
6122 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6123 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6124 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6125 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6126
6127 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6128 * mixer widget
6129 * Note: PASD motherboards uses the Line In 2 as the input for
6130 * front panel mic (mic 2)
6131 */
6132 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6133 /* mute analog inputs */
6134 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6139
6140 /*
6141 * Set up output mixers (0x08 - 0x0a)
6142 */
6143 /* set vol=0 to output mixers */
6144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6145 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6146 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6147 /* set up input amps for analog loopback */
6148 /* Amp Indices: DAC = 0, mixer = 1 */
6149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6150 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6154 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6155
6156 { }
6157};
6158
6159static int alc260_parse_auto_config(struct hda_codec *codec)
6160{
6161 struct alc_spec *spec = codec->spec;
6162 int err;
6163 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6164
6165 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6166 alc260_ignore);
6167 if (err < 0)
6168 return err;
6169 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6170 if (err < 0)
6171 return err;
6172 if (!spec->kctls.list)
6173 return 0; /* can't find valid BIOS pin config */
6174 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6175 if (err < 0)
6176 return err;
6177
6178 spec->multiout.max_channels = 2;
6179
6180 if (spec->autocfg.dig_outs)
6181 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6182 if (spec->kctls.list)
6183 add_mixer(spec, spec->kctls.list);
6184
6185 add_verb(spec, alc260_volume_init_verbs);
6186
6187 spec->num_mux_defs = 1;
6188 spec->input_mux = &spec->private_imux[0];
6189
6190 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6191
6192 return 1;
6193}
6194
6195/* additional initialization for auto-configuration model */
6196static void alc260_auto_init(struct hda_codec *codec)
6197{
6198 struct alc_spec *spec = codec->spec;
6199 alc260_auto_init_multi_out(codec);
6200 alc260_auto_init_analog_input(codec);
6201 if (spec->unsol_event)
6202 alc_inithook(codec);
6203}
6204
6205#ifdef CONFIG_SND_HDA_POWER_SAVE
6206static struct hda_amp_list alc260_loopbacks[] = {
6207 { 0x07, HDA_INPUT, 0 },
6208 { 0x07, HDA_INPUT, 1 },
6209 { 0x07, HDA_INPUT, 2 },
6210 { 0x07, HDA_INPUT, 3 },
6211 { 0x07, HDA_INPUT, 4 },
6212 { } /* end */
6213};
6214#endif
6215
6216/*
6217 * ALC260 configurations
6218 */
6219static const char *alc260_models[ALC260_MODEL_LAST] = {
6220 [ALC260_BASIC] = "basic",
6221 [ALC260_HP] = "hp",
6222 [ALC260_HP_3013] = "hp-3013",
6223 [ALC260_HP_DC7600] = "hp-dc7600",
6224 [ALC260_FUJITSU_S702X] = "fujitsu",
6225 [ALC260_ACER] = "acer",
6226 [ALC260_WILL] = "will",
6227 [ALC260_REPLACER_672V] = "replacer",
6228 [ALC260_FAVORIT100] = "favorit100",
6229#ifdef CONFIG_SND_DEBUG
6230 [ALC260_TEST] = "test",
6231#endif
6232 [ALC260_AUTO] = "auto",
6233};
6234
6235static struct snd_pci_quirk alc260_cfg_tbl[] = {
6236 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6237 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6238 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6239 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6240 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6241 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6242 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6243 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6244 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6245 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6246 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6247 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6248 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6249 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6250 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6251 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6252 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6253 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6254 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6255 {}
6256};
6257
6258static struct alc_config_preset alc260_presets[] = {
6259 [ALC260_BASIC] = {
6260 .mixers = { alc260_base_output_mixer,
6261 alc260_input_mixer },
6262 .init_verbs = { alc260_init_verbs },
6263 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6264 .dac_nids = alc260_dac_nids,
6265 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6266 .adc_nids = alc260_adc_nids,
6267 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6268 .channel_mode = alc260_modes,
6269 .input_mux = &alc260_capture_source,
6270 },
6271 [ALC260_HP] = {
6272 .mixers = { alc260_hp_output_mixer,
6273 alc260_input_mixer },
6274 .init_verbs = { alc260_init_verbs,
6275 alc260_hp_unsol_verbs },
6276 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6277 .dac_nids = alc260_dac_nids,
6278 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6279 .adc_nids = alc260_adc_nids_alt,
6280 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6281 .channel_mode = alc260_modes,
6282 .input_mux = &alc260_capture_source,
6283 .unsol_event = alc260_hp_unsol_event,
6284 .init_hook = alc260_hp_automute,
6285 },
6286 [ALC260_HP_DC7600] = {
6287 .mixers = { alc260_hp_dc7600_mixer,
6288 alc260_input_mixer },
6289 .init_verbs = { alc260_init_verbs,
6290 alc260_hp_dc7600_verbs },
6291 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6292 .dac_nids = alc260_dac_nids,
6293 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6294 .adc_nids = alc260_adc_nids_alt,
6295 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6296 .channel_mode = alc260_modes,
6297 .input_mux = &alc260_capture_source,
6298 .unsol_event = alc260_hp_3012_unsol_event,
6299 .init_hook = alc260_hp_3012_automute,
6300 },
6301 [ALC260_HP_3013] = {
6302 .mixers = { alc260_hp_3013_mixer,
6303 alc260_input_mixer },
6304 .init_verbs = { alc260_hp_3013_init_verbs,
6305 alc260_hp_3013_unsol_verbs },
6306 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6307 .dac_nids = alc260_dac_nids,
6308 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6309 .adc_nids = alc260_adc_nids_alt,
6310 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6311 .channel_mode = alc260_modes,
6312 .input_mux = &alc260_capture_source,
6313 .unsol_event = alc260_hp_3013_unsol_event,
6314 .init_hook = alc260_hp_3013_automute,
6315 },
6316 [ALC260_FUJITSU_S702X] = {
6317 .mixers = { alc260_fujitsu_mixer },
6318 .init_verbs = { alc260_fujitsu_init_verbs },
6319 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6320 .dac_nids = alc260_dac_nids,
6321 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6322 .adc_nids = alc260_dual_adc_nids,
6323 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6324 .channel_mode = alc260_modes,
6325 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6326 .input_mux = alc260_fujitsu_capture_sources,
6327 },
6328 [ALC260_ACER] = {
6329 .mixers = { alc260_acer_mixer },
6330 .init_verbs = { alc260_acer_init_verbs },
6331 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6332 .dac_nids = alc260_dac_nids,
6333 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6334 .adc_nids = alc260_dual_adc_nids,
6335 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6336 .channel_mode = alc260_modes,
6337 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6338 .input_mux = alc260_acer_capture_sources,
6339 },
6340 [ALC260_FAVORIT100] = {
6341 .mixers = { alc260_favorit100_mixer },
6342 .init_verbs = { alc260_favorit100_init_verbs },
6343 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6344 .dac_nids = alc260_dac_nids,
6345 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6346 .adc_nids = alc260_dual_adc_nids,
6347 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6348 .channel_mode = alc260_modes,
6349 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6350 .input_mux = alc260_favorit100_capture_sources,
6351 },
6352 [ALC260_WILL] = {
6353 .mixers = { alc260_will_mixer },
6354 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6355 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6356 .dac_nids = alc260_dac_nids,
6357 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6358 .adc_nids = alc260_adc_nids,
6359 .dig_out_nid = ALC260_DIGOUT_NID,
6360 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6361 .channel_mode = alc260_modes,
6362 .input_mux = &alc260_capture_source,
6363 },
6364 [ALC260_REPLACER_672V] = {
6365 .mixers = { alc260_replacer_672v_mixer },
6366 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6367 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6368 .dac_nids = alc260_dac_nids,
6369 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6370 .adc_nids = alc260_adc_nids,
6371 .dig_out_nid = ALC260_DIGOUT_NID,
6372 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6373 .channel_mode = alc260_modes,
6374 .input_mux = &alc260_capture_source,
6375 .unsol_event = alc260_replacer_672v_unsol_event,
6376 .init_hook = alc260_replacer_672v_automute,
6377 },
6378#ifdef CONFIG_SND_DEBUG
6379 [ALC260_TEST] = {
6380 .mixers = { alc260_test_mixer },
6381 .init_verbs = { alc260_test_init_verbs },
6382 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6383 .dac_nids = alc260_test_dac_nids,
6384 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6385 .adc_nids = alc260_test_adc_nids,
6386 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6387 .channel_mode = alc260_modes,
6388 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6389 .input_mux = alc260_test_capture_sources,
6390 },
6391#endif
6392};
6393
6394static int patch_alc260(struct hda_codec *codec)
6395{
6396 struct alc_spec *spec;
6397 int err, board_config;
6398
6399 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6400 if (spec == NULL)
6401 return -ENOMEM;
6402
6403 codec->spec = spec;
6404
6405 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6406 alc260_models,
6407 alc260_cfg_tbl);
6408 if (board_config < 0) {
6409 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6410 codec->chip_name);
6411 board_config = ALC260_AUTO;
6412 }
6413
6414 if (board_config == ALC260_AUTO) {
6415 /* automatic parse from the BIOS config */
6416 err = alc260_parse_auto_config(codec);
6417 if (err < 0) {
6418 alc_free(codec);
6419 return err;
6420 } else if (!err) {
6421 printk(KERN_INFO
6422 "hda_codec: Cannot set up configuration "
6423 "from BIOS. Using base mode...\n");
6424 board_config = ALC260_BASIC;
6425 }
6426 }
6427
6428 err = snd_hda_attach_beep_device(codec, 0x1);
6429 if (err < 0) {
6430 alc_free(codec);
6431 return err;
6432 }
6433
6434 if (board_config != ALC260_AUTO)
6435 setup_preset(codec, &alc260_presets[board_config]);
6436
6437 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6438 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6439
6440 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6441 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6442
6443 if (!spec->adc_nids && spec->input_mux) {
6444 /* check whether NID 0x04 is valid */
6445 unsigned int wcap = get_wcaps(codec, 0x04);
6446 wcap = get_wcaps_type(wcap);
6447 /* get type */
6448 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6449 spec->adc_nids = alc260_adc_nids_alt;
6450 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6451 } else {
6452 spec->adc_nids = alc260_adc_nids;
6453 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6454 }
6455 }
6456 set_capture_mixer(codec);
6457 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6458
6459 spec->vmaster_nid = 0x08;
6460
6461 codec->patch_ops = alc_patch_ops;
6462 if (board_config == ALC260_AUTO)
6463 spec->init_hook = alc260_auto_init;
6464#ifdef CONFIG_SND_HDA_POWER_SAVE
6465 if (!spec->loopback.amplist)
6466 spec->loopback.amplist = alc260_loopbacks;
6467#endif
6468 codec->proc_widget_hook = print_realtek_coef;
6469
6470 return 0;
6471}
6472
6473
6474/*
6475 * ALC882/883/885/888/889 support
6476 *
6477 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6478 * configuration. Each pin widget can choose any input DACs and a mixer.
6479 * Each ADC is connected from a mixer of all inputs. This makes possible
6480 * 6-channel independent captures.
6481 *
6482 * In addition, an independent DAC for the multi-playback (not used in this
6483 * driver yet).
6484 */
6485#define ALC882_DIGOUT_NID 0x06
6486#define ALC882_DIGIN_NID 0x0a
6487#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6488#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6489#define ALC1200_DIGOUT_NID 0x10
6490
6491
6492static struct hda_channel_mode alc882_ch_modes[1] = {
6493 { 8, NULL }
6494};
6495
6496/* DACs */
6497static hda_nid_t alc882_dac_nids[4] = {
6498 /* front, rear, clfe, rear_surr */
6499 0x02, 0x03, 0x04, 0x05
6500};
6501#define alc883_dac_nids alc882_dac_nids
6502
6503/* ADCs */
6504#define alc882_adc_nids alc880_adc_nids
6505#define alc882_adc_nids_alt alc880_adc_nids_alt
6506#define alc883_adc_nids alc882_adc_nids_alt
6507static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6508static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6509#define alc889_adc_nids alc880_adc_nids
6510
6511static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6512static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6513#define alc883_capsrc_nids alc882_capsrc_nids_alt
6514static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6515#define alc889_capsrc_nids alc882_capsrc_nids
6516
6517/* input MUX */
6518/* FIXME: should be a matrix-type input source selection */
6519
6520static struct hda_input_mux alc882_capture_source = {
6521 .num_items = 4,
6522 .items = {
6523 { "Mic", 0x0 },
6524 { "Front Mic", 0x1 },
6525 { "Line", 0x2 },
6526 { "CD", 0x4 },
6527 },
6528};
6529
6530#define alc883_capture_source alc882_capture_source
6531
6532static struct hda_input_mux alc889_capture_source = {
6533 .num_items = 3,
6534 .items = {
6535 { "Front Mic", 0x0 },
6536 { "Mic", 0x3 },
6537 { "Line", 0x2 },
6538 },
6539};
6540
6541static struct hda_input_mux mb5_capture_source = {
6542 .num_items = 3,
6543 .items = {
6544 { "Mic", 0x1 },
6545 { "Line", 0x2 },
6546 { "CD", 0x4 },
6547 },
6548};
6549
6550static struct hda_input_mux alc883_3stack_6ch_intel = {
6551 .num_items = 4,
6552 .items = {
6553 { "Mic", 0x1 },
6554 { "Front Mic", 0x0 },
6555 { "Line", 0x2 },
6556 { "CD", 0x4 },
6557 },
6558};
6559
6560static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6561 .num_items = 2,
6562 .items = {
6563 { "Mic", 0x1 },
6564 { "Line", 0x2 },
6565 },
6566};
6567
6568static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6569 .num_items = 4,
6570 .items = {
6571 { "Mic", 0x0 },
6572 { "iMic", 0x1 },
6573 { "Line", 0x2 },
6574 { "CD", 0x4 },
6575 },
6576};
6577
6578static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6579 .num_items = 2,
6580 .items = {
6581 { "Mic", 0x0 },
6582 { "Int Mic", 0x1 },
6583 },
6584};
6585
6586static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6587 .num_items = 3,
6588 .items = {
6589 { "Mic", 0x0 },
6590 { "Front Mic", 0x1 },
6591 { "Line", 0x4 },
6592 },
6593};
6594
6595static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6596 .num_items = 2,
6597 .items = {
6598 { "Mic", 0x0 },
6599 { "Line", 0x2 },
6600 },
6601};
6602
6603static struct hda_input_mux alc889A_mb31_capture_source = {
6604 .num_items = 2,
6605 .items = {
6606 { "Mic", 0x0 },
6607 /* Front Mic (0x01) unused */
6608 { "Line", 0x2 },
6609 /* Line 2 (0x03) unused */
6610 /* CD (0x04) unsused? */
6611 },
6612};
6613
6614/*
6615 * 2ch mode
6616 */
6617static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6618 { 2, NULL }
6619};
6620
6621/*
6622 * 2ch mode
6623 */
6624static struct hda_verb alc882_3ST_ch2_init[] = {
6625 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6626 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6627 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6628 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6629 { } /* end */
6630};
6631
6632/*
6633 * 4ch mode
6634 */
6635static struct hda_verb alc882_3ST_ch4_init[] = {
6636 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6637 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6638 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6639 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6640 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6641 { } /* end */
6642};
6643
6644/*
6645 * 6ch mode
6646 */
6647static struct hda_verb alc882_3ST_ch6_init[] = {
6648 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6649 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6650 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6651 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6652 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6653 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6654 { } /* end */
6655};
6656
6657static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6658 { 2, alc882_3ST_ch2_init },
6659 { 4, alc882_3ST_ch4_init },
6660 { 6, alc882_3ST_ch6_init },
6661};
6662
6663#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6664
6665/*
6666 * 2ch mode
6667 */
6668static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
6669 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
6670 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6671 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6672 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6673 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6674 { } /* end */
6675};
6676
6677/*
6678 * 4ch mode
6679 */
6680static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
6681 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6682 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6683 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6684 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6685 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6686 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6687 { } /* end */
6688};
6689
6690/*
6691 * 6ch mode
6692 */
6693static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
6694 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6695 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6696 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6697 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6698 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6699 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6700 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6701 { } /* end */
6702};
6703
6704static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
6705 { 2, alc883_3ST_ch2_clevo_init },
6706 { 4, alc883_3ST_ch4_clevo_init },
6707 { 6, alc883_3ST_ch6_clevo_init },
6708};
6709
6710
6711/*
6712 * 6ch mode
6713 */
6714static struct hda_verb alc882_sixstack_ch6_init[] = {
6715 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6716 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6717 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6718 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6719 { } /* end */
6720};
6721
6722/*
6723 * 8ch mode
6724 */
6725static struct hda_verb alc882_sixstack_ch8_init[] = {
6726 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6727 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6728 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6729 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6730 { } /* end */
6731};
6732
6733static struct hda_channel_mode alc882_sixstack_modes[2] = {
6734 { 6, alc882_sixstack_ch6_init },
6735 { 8, alc882_sixstack_ch8_init },
6736};
6737
6738/*
6739 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6740 */
6741
6742/*
6743 * 2ch mode
6744 */
6745static struct hda_verb alc885_mbp_ch2_init[] = {
6746 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6747 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6748 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6749 { } /* end */
6750};
6751
6752/*
6753 * 4ch mode
6754 */
6755static struct hda_verb alc885_mbp_ch4_init[] = {
6756 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6757 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6758 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6759 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6760 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6761 { } /* end */
6762};
6763
6764static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
6765 { 2, alc885_mbp_ch2_init },
6766 { 4, alc885_mbp_ch4_init },
6767};
6768
6769/*
6770 * 2ch
6771 * Speakers/Woofer/HP = Front
6772 * LineIn = Input
6773 */
6774static struct hda_verb alc885_mb5_ch2_init[] = {
6775 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6776 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6777 { } /* end */
6778};
6779
6780/*
6781 * 6ch mode
6782 * Speakers/HP = Front
6783 * Woofer = LFE
6784 * LineIn = Surround
6785 */
6786static struct hda_verb alc885_mb5_ch6_init[] = {
6787 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6788 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6789 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6790 { } /* end */
6791};
6792
6793static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6794 { 2, alc885_mb5_ch2_init },
6795 { 6, alc885_mb5_ch6_init },
6796};
6797
6798
6799/*
6800 * 2ch mode
6801 */
6802static struct hda_verb alc883_4ST_ch2_init[] = {
6803 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6804 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6805 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6806 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6807 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6808 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6809 { } /* end */
6810};
6811
6812/*
6813 * 4ch mode
6814 */
6815static struct hda_verb alc883_4ST_ch4_init[] = {
6816 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6817 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6818 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6819 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6820 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6821 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6822 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6823 { } /* end */
6824};
6825
6826/*
6827 * 6ch mode
6828 */
6829static struct hda_verb alc883_4ST_ch6_init[] = {
6830 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6831 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6832 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6833 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6834 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6835 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6836 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6837 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6838 { } /* end */
6839};
6840
6841/*
6842 * 8ch mode
6843 */
6844static struct hda_verb alc883_4ST_ch8_init[] = {
6845 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6846 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6847 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6848 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6849 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6850 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6851 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6852 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6853 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6854 { } /* end */
6855};
6856
6857static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6858 { 2, alc883_4ST_ch2_init },
6859 { 4, alc883_4ST_ch4_init },
6860 { 6, alc883_4ST_ch6_init },
6861 { 8, alc883_4ST_ch8_init },
6862};
6863
6864
6865/*
6866 * 2ch mode
6867 */
6868static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6869 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6870 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6871 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6872 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6873 { } /* end */
6874};
6875
6876/*
6877 * 4ch mode
6878 */
6879static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6880 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6881 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6882 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6883 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6884 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6885 { } /* end */
6886};
6887
6888/*
6889 * 6ch mode
6890 */
6891static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6892 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6893 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6894 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6895 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6896 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6897 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6898 { } /* end */
6899};
6900
6901static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6902 { 2, alc883_3ST_ch2_intel_init },
6903 { 4, alc883_3ST_ch4_intel_init },
6904 { 6, alc883_3ST_ch6_intel_init },
6905};
6906
6907/*
6908 * 2ch mode
6909 */
6910static struct hda_verb alc889_ch2_intel_init[] = {
6911 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6912 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
6913 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
6914 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
6915 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6916 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6917 { } /* end */
6918};
6919
6920/*
6921 * 6ch mode
6922 */
6923static struct hda_verb alc889_ch6_intel_init[] = {
6924 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6925 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6926 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6927 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6928 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6929 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6930 { } /* end */
6931};
6932
6933/*
6934 * 8ch mode
6935 */
6936static struct hda_verb alc889_ch8_intel_init[] = {
6937 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6938 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6939 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6940 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6941 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
6942 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6943 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6944 { } /* end */
6945};
6946
6947static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
6948 { 2, alc889_ch2_intel_init },
6949 { 6, alc889_ch6_intel_init },
6950 { 8, alc889_ch8_intel_init },
6951};
6952
6953/*
6954 * 6ch mode
6955 */
6956static struct hda_verb alc883_sixstack_ch6_init[] = {
6957 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6958 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6959 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6960 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6961 { } /* end */
6962};
6963
6964/*
6965 * 8ch mode
6966 */
6967static struct hda_verb alc883_sixstack_ch8_init[] = {
6968 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6969 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6970 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6971 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6972 { } /* end */
6973};
6974
6975static struct hda_channel_mode alc883_sixstack_modes[2] = {
6976 { 6, alc883_sixstack_ch6_init },
6977 { 8, alc883_sixstack_ch8_init },
6978};
6979
6980
6981/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6982 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6983 */
6984static struct snd_kcontrol_new alc882_base_mixer[] = {
6985 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6986 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6987 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6988 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6989 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6990 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6991 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6992 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6993 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6994 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6995 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6996 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6997 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7001 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7003 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7004 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7005 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7006 { } /* end */
7007};
7008
7009static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7010 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7011 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7012 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7013 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7014 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7015 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7016 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7018 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7019 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7020 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7021 { } /* end */
7022};
7023
7024static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7025 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7026 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7027 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7028 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7029 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7030 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7031 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7032 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
7033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7034 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7035 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7036 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7037 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7038 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7039 { } /* end */
7040};
7041
7042static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7043 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7044 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7045 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7046 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7047 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7048 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7049 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7050 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7051 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7052 { } /* end */
7053};
7054
7055static struct snd_kcontrol_new alc882_targa_mixer[] = {
7056 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7057 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7058 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7059 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7060 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7061 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7062 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7063 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7064 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7065 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7066 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7067 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7068 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7069 { } /* end */
7070};
7071
7072/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7073 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7074 */
7075static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7076 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7077 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7078 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7079 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7080 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7081 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7082 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7083 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7084 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7085 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7087 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7088 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7089 { } /* end */
7090};
7091
7092static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7093 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7094 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7095 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7097 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7101 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7103 { } /* end */
7104};
7105
7106static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7107 {
7108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7109 .name = "Channel Mode",
7110 .info = alc_ch_mode_info,
7111 .get = alc_ch_mode_get,
7112 .put = alc_ch_mode_put,
7113 },
7114 { } /* end */
7115};
7116
7117static struct hda_verb alc882_base_init_verbs[] = {
7118 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7121 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7122 /* Rear mixer */
7123 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7124 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7125 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7126 /* CLFE mixer */
7127 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7128 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7129 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7130 /* Side mixer */
7131 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7132 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7133 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7134
7135 /* mute analog input loopbacks */
7136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7139 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7140 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7141
7142 /* Front Pin: output 0 (0x0c) */
7143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7144 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7145 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7146 /* Rear Pin: output 1 (0x0d) */
7147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7148 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7149 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7150 /* CLFE Pin: output 2 (0x0e) */
7151 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7152 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7153 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7154 /* Side Pin: output 3 (0x0f) */
7155 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7156 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7157 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7158 /* Mic (rear) pin: input vref at 80% */
7159 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7160 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7161 /* Front Mic pin: input vref at 80% */
7162 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7163 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7164 /* Line In pin: input */
7165 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7166 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7167 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7168 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7169 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7170 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7171 /* CD pin widget for input */
7172 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7173
7174 /* FIXME: use matrix-type input source selection */
7175 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7176 /* Input mixer2 */
7177 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7178 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7179 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7180 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7181 /* Input mixer3 */
7182 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7183 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7184 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7185 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7186 /* ADC2: mute amp left and right */
7187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7188 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7189 /* ADC3: mute amp left and right */
7190 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7191 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7192
7193 { }
7194};
7195
7196static struct hda_verb alc882_adc1_init_verbs[] = {
7197 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7201 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7202 /* ADC1: mute amp left and right */
7203 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7204 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7205 { }
7206};
7207
7208static struct hda_verb alc882_eapd_verbs[] = {
7209 /* change to EAPD mode */
7210 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7211 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7212 { }
7213};
7214
7215static struct hda_verb alc889_eapd_verbs[] = {
7216 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7217 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7218 { }
7219};
7220
7221static struct hda_verb alc_hp15_unsol_verbs[] = {
7222 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7223 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7224 {}
7225};
7226
7227static struct hda_verb alc885_init_verbs[] = {
7228 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7231 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7232 /* Rear mixer */
7233 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7234 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7235 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7236 /* CLFE mixer */
7237 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7238 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7239 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7240 /* Side mixer */
7241 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7242 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7243 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7244
7245 /* mute analog input loopbacks */
7246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7249
7250 /* Front HP Pin: output 0 (0x0c) */
7251 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7252 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7253 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7254 /* Front Pin: output 0 (0x0c) */
7255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7256 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7257 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7258 /* Rear Pin: output 1 (0x0d) */
7259 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7260 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7261 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7262 /* CLFE Pin: output 2 (0x0e) */
7263 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7264 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7265 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7266 /* Side Pin: output 3 (0x0f) */
7267 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7268 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7269 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7270 /* Mic (rear) pin: input vref at 80% */
7271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7272 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7273 /* Front Mic pin: input vref at 80% */
7274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7275 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7276 /* Line In pin: input */
7277 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7278 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7279
7280 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7281 /* Input mixer1 */
7282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7284 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7285 /* Input mixer2 */
7286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7289 /* Input mixer3 */
7290 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7291 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7293 /* ADC2: mute amp left and right */
7294 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7295 /* ADC3: mute amp left and right */
7296 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7297
7298 { }
7299};
7300
7301static struct hda_verb alc885_init_input_verbs[] = {
7302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7303 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7305 { }
7306};
7307
7308
7309/* Unmute Selector 24h and set the default input to front mic */
7310static struct hda_verb alc889_init_input_verbs[] = {
7311 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7312 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7313 { }
7314};
7315
7316
7317#define alc883_init_verbs alc882_base_init_verbs
7318
7319/* Mac Pro test */
7320static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7321 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7322 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7323 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7324 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7325 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7326 /* FIXME: this looks suspicious...
7327 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7328 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
7329 */
7330 { } /* end */
7331};
7332
7333static struct hda_verb alc882_macpro_init_verbs[] = {
7334 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7336 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7337 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7338 /* Front Pin: output 0 (0x0c) */
7339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7340 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7342 /* Front Mic pin: input vref at 80% */
7343 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7344 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7345 /* Speaker: output */
7346 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7347 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7348 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7349 /* Headphone output (output 0 - 0x0c) */
7350 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7351 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7352 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7353
7354 /* FIXME: use matrix-type input source selection */
7355 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7356 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7361 /* Input mixer2 */
7362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7366 /* Input mixer3 */
7367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7368 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7369 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7371 /* ADC1: mute amp left and right */
7372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7373 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7374 /* ADC2: mute amp left and right */
7375 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7376 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7377 /* ADC3: mute amp left and right */
7378 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7379 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7380
7381 { }
7382};
7383
7384/* Macbook 5,1 */
7385static struct hda_verb alc885_mb5_init_verbs[] = {
7386 /* DACs */
7387 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7388 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7389 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7390 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7391 /* Front mixer */
7392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7395 /* Surround mixer */
7396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7398 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7399 /* LFE mixer */
7400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7401 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7402 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7403 /* HP mixer */
7404 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7405 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7406 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7407 /* Front Pin (0x0c) */
7408 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7409 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7410 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7411 /* LFE Pin (0x0e) */
7412 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7413 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7414 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7415 /* HP Pin (0x0f) */
7416 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7417 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7418 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7419 /* Front Mic pin: input vref at 80% */
7420 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7421 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7422 /* Line In pin */
7423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7425
7426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7428 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7429 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7430 { }
7431};
7432
7433/* Macbook Pro rev3 */
7434static struct hda_verb alc885_mbp3_init_verbs[] = {
7435 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7437 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7438 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7439 /* Rear mixer */
7440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7443 /* HP mixer */
7444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7445 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7446 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7447 /* Front Pin: output 0 (0x0c) */
7448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7449 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7450 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7451 /* HP Pin: output 0 (0x0e) */
7452 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7453 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7454 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
7455 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7456 /* Mic (rear) pin: input vref at 80% */
7457 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7458 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7459 /* Front Mic pin: input vref at 80% */
7460 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7461 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7462 /* Line In pin: use output 1 when in LineOut mode */
7463 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7464 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7465 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7466
7467 /* FIXME: use matrix-type input source selection */
7468 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7469 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7472 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7473 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7474 /* Input mixer2 */
7475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7478 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7479 /* Input mixer3 */
7480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7484 /* ADC1: mute amp left and right */
7485 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7486 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7487 /* ADC2: mute amp left and right */
7488 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7489 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7490 /* ADC3: mute amp left and right */
7491 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7492 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7493
7494 { }
7495};
7496
7497/* iMac 24 mixer. */
7498static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7499 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7500 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7501 { } /* end */
7502};
7503
7504/* iMac 24 init verbs. */
7505static struct hda_verb alc885_imac24_init_verbs[] = {
7506 /* Internal speakers: output 0 (0x0c) */
7507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7509 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7510 /* Internal speakers: output 0 (0x0c) */
7511 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7512 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7513 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7514 /* Headphone: output 0 (0x0c) */
7515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7516 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7517 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7518 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7519 /* Front Mic: input vref at 80% */
7520 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7521 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7522 { }
7523};
7524
7525/* Toggle speaker-output according to the hp-jack state */
7526static void alc885_imac24_setup(struct hda_codec *codec)
7527{
7528 struct alc_spec *spec = codec->spec;
7529
7530 spec->autocfg.hp_pins[0] = 0x14;
7531 spec->autocfg.speaker_pins[0] = 0x18;
7532 spec->autocfg.speaker_pins[1] = 0x1a;
7533}
7534
7535static void alc885_mbp3_setup(struct hda_codec *codec)
7536{
7537 struct alc_spec *spec = codec->spec;
7538
7539 spec->autocfg.hp_pins[0] = 0x15;
7540 spec->autocfg.speaker_pins[0] = 0x14;
7541}
7542
7543
7544static struct hda_verb alc882_targa_verbs[] = {
7545 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7547
7548 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7549 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7550
7551 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7552 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7553 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7554
7555 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7556 { } /* end */
7557};
7558
7559/* toggle speaker-output according to the hp-jack state */
7560static void alc882_targa_automute(struct hda_codec *codec)
7561{
7562 struct alc_spec *spec = codec->spec;
7563 alc_automute_amp(codec);
7564 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7565 spec->jack_present ? 1 : 3);
7566}
7567
7568static void alc882_targa_setup(struct hda_codec *codec)
7569{
7570 struct alc_spec *spec = codec->spec;
7571
7572 spec->autocfg.hp_pins[0] = 0x14;
7573 spec->autocfg.speaker_pins[0] = 0x1b;
7574}
7575
7576static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7577{
7578 if ((res >> 26) == ALC880_HP_EVENT)
7579 alc882_targa_automute(codec);
7580}
7581
7582static struct hda_verb alc882_asus_a7j_verbs[] = {
7583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7584 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7585
7586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7587 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7588 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7589
7590 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7592 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7593
7594 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7595 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7596 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7597 { } /* end */
7598};
7599
7600static struct hda_verb alc882_asus_a7m_verbs[] = {
7601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7603
7604 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7605 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7606 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7607
7608 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7609 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7610 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7611
7612 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7613 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7614 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7615 { } /* end */
7616};
7617
7618static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7619{
7620 unsigned int gpiostate, gpiomask, gpiodir;
7621
7622 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7623 AC_VERB_GET_GPIO_DATA, 0);
7624
7625 if (!muted)
7626 gpiostate |= (1 << pin);
7627 else
7628 gpiostate &= ~(1 << pin);
7629
7630 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7631 AC_VERB_GET_GPIO_MASK, 0);
7632 gpiomask |= (1 << pin);
7633
7634 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7635 AC_VERB_GET_GPIO_DIRECTION, 0);
7636 gpiodir |= (1 << pin);
7637
7638
7639 snd_hda_codec_write(codec, codec->afg, 0,
7640 AC_VERB_SET_GPIO_MASK, gpiomask);
7641 snd_hda_codec_write(codec, codec->afg, 0,
7642 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7643
7644 msleep(1);
7645
7646 snd_hda_codec_write(codec, codec->afg, 0,
7647 AC_VERB_SET_GPIO_DATA, gpiostate);
7648}
7649
7650/* set up GPIO at initialization */
7651static void alc885_macpro_init_hook(struct hda_codec *codec)
7652{
7653 alc882_gpio_mute(codec, 0, 0);
7654 alc882_gpio_mute(codec, 1, 0);
7655}
7656
7657/* set up GPIO and update auto-muting at initialization */
7658static void alc885_imac24_init_hook(struct hda_codec *codec)
7659{
7660 alc885_macpro_init_hook(codec);
7661 alc_automute_amp(codec);
7662}
7663
7664/*
7665 * generic initialization of ADC, input mixers and output mixers
7666 */
7667static struct hda_verb alc883_auto_init_verbs[] = {
7668 /*
7669 * Unmute ADC0-2 and set the default input to mic-in
7670 */
7671 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7672 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7673 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7674 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7675
7676 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7677 * mixer widget
7678 * Note: PASD motherboards uses the Line In 2 as the input for
7679 * front panel mic (mic 2)
7680 */
7681 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7682 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7683 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7687
7688 /*
7689 * Set up output mixers (0x0c - 0x0f)
7690 */
7691 /* set vol=0 to output mixers */
7692 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7693 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7694 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7695 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7696 /* set up input amps for analog loopback */
7697 /* Amp Indices: DAC = 0, mixer = 1 */
7698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7700 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7702 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7705 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7706 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7707 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7708
7709 /* FIXME: use matrix-type input source selection */
7710 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7711 /* Input mixer2 */
7712 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7713 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7714 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7715 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7716 /* Input mixer3 */
7717 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7719 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7720 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7721
7722 { }
7723};
7724
7725/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7726static struct hda_verb alc889A_mb31_ch2_init[] = {
7727 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7728 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7729 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7730 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7731 { } /* end */
7732};
7733
7734/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7735static struct hda_verb alc889A_mb31_ch4_init[] = {
7736 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7737 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7738 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7739 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7740 { } /* end */
7741};
7742
7743/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7744static struct hda_verb alc889A_mb31_ch5_init[] = {
7745 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7746 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7747 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7749 { } /* end */
7750};
7751
7752/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7753static struct hda_verb alc889A_mb31_ch6_init[] = {
7754 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7755 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7756 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7757 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7758 { } /* end */
7759};
7760
7761static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7762 { 2, alc889A_mb31_ch2_init },
7763 { 4, alc889A_mb31_ch4_init },
7764 { 5, alc889A_mb31_ch5_init },
7765 { 6, alc889A_mb31_ch6_init },
7766};
7767
7768static struct hda_verb alc883_medion_eapd_verbs[] = {
7769 /* eanable EAPD on medion laptop */
7770 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7771 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7772 { }
7773};
7774
7775#define alc883_base_mixer alc882_base_mixer
7776
7777static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7778 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7779 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7780 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7781 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7782 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7783 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7784 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7785 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7786 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7787 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7788 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7789 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7790 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7791 { } /* end */
7792};
7793
7794static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7795 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7796 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7797 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7798 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7799 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7800 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7801 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7802 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7803 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7804 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7805 { } /* end */
7806};
7807
7808static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7809 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7810 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7811 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7812 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7814 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7815 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7816 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7817 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7818 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7819 { } /* end */
7820};
7821
7822static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7823 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7824 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7825 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7826 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7827 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7828 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7829 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7831 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7832 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7833 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7834 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7835 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7836 { } /* end */
7837};
7838
7839static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7840 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7841 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7842 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7843 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7844 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7845 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7846 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7847 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7848 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7849 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7850 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7851 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7852 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7856 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7857 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7858 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7859 { } /* end */
7860};
7861
7862static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7863 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7864 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7865 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7866 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7867 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7868 HDA_OUTPUT),
7869 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7870 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7871 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7872 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7873 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7874 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7875 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7876 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7878 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7880 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7881 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7882 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7883 { } /* end */
7884};
7885
7886static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
7887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7889 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7890 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7891 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7892 HDA_OUTPUT),
7893 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7894 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7895 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7896 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7897 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
7898 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7899 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7900 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
7902 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
7903 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
7904 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7905 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7906 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7907 { } /* end */
7908};
7909
7910static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7911 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7912 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7913 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7914 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7915 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7916 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7917 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7918 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7919 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7920 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7921 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7922 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7923 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7924 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7925 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7927 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7928 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7929 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7930 { } /* end */
7931};
7932
7933static struct snd_kcontrol_new alc883_targa_mixer[] = {
7934 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7935 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7936 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7937 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7938 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7939 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7940 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7941 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7942 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7943 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7944 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7945 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7949 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7951 { } /* end */
7952};
7953
7954static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
7955 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7956 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7957 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7958 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7959 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7960 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7961 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7962 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7963 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7964 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7965 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7966 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7967 { } /* end */
7968};
7969
7970static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
7971 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7972 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7973 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7975 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7976 { } /* end */
7977};
7978
7979static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7980 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7981 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7982 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7983 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7986 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7987 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7988 { } /* end */
7989};
7990
7991static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7992 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7993 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7994 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7995 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7996 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7999 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8000 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8001 { } /* end */
8002};
8003
8004static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8005 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8006 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8007 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8012 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8013 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8014 { } /* end */
8015};
8016
8017static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8018 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8019 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8020 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8021 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8022 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8024 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8026 { } /* end */
8027};
8028
8029static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8030 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8031 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8032 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8033 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
8034 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8035 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8036 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8037 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8039 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8040 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8041 { } /* end */
8042};
8043
8044static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8045 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8046 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8047 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8048 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8049 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8050 0x0d, 1, 0x0, HDA_OUTPUT),
8051 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8052 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8053 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8055 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8056 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8057 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8058 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8059 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8061 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8063 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8064 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8065 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8066 { } /* end */
8067};
8068
8069static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8070 /* Output mixers */
8071 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8072 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8073 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8074 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8075 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8076 HDA_OUTPUT),
8077 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8078 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8079 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8080 /* Output switches */
8081 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8082 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8083 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8084 /* Boost mixers */
8085 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8086 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8087 /* Input mixers */
8088 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8089 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8090 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8091 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8092 { } /* end */
8093};
8094
8095static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8096 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8097 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8099 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8100 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8101 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8102 { } /* end */
8103};
8104
8105static struct hda_bind_ctls alc883_bind_cap_vol = {
8106 .ops = &snd_hda_bind_vol,
8107 .values = {
8108 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8109 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8110 0
8111 },
8112};
8113
8114static struct hda_bind_ctls alc883_bind_cap_switch = {
8115 .ops = &snd_hda_bind_sw,
8116 .values = {
8117 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8118 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8119 0
8120 },
8121};
8122
8123static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8124 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8125 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8126 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8127 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8128 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8129 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8130 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8131 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8132 { } /* end */
8133};
8134
8135static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8136 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8137 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8138 {
8139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8140 /* .name = "Capture Source", */
8141 .name = "Input Source",
8142 .count = 1,
8143 .info = alc_mux_enum_info,
8144 .get = alc_mux_enum_get,
8145 .put = alc_mux_enum_put,
8146 },
8147 { } /* end */
8148};
8149
8150static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8151 {
8152 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8153 .name = "Channel Mode",
8154 .info = alc_ch_mode_info,
8155 .get = alc_ch_mode_get,
8156 .put = alc_ch_mode_put,
8157 },
8158 { } /* end */
8159};
8160
8161/* toggle speaker-output according to the hp-jack state */
8162static void alc883_mitac_setup(struct hda_codec *codec)
8163{
8164 struct alc_spec *spec = codec->spec;
8165
8166 spec->autocfg.hp_pins[0] = 0x15;
8167 spec->autocfg.speaker_pins[0] = 0x14;
8168 spec->autocfg.speaker_pins[1] = 0x17;
8169}
8170
8171/* auto-toggle front mic */
8172/*
8173static void alc883_mitac_mic_automute(struct hda_codec *codec)
8174{
8175 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
8176
8177 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8178}
8179*/
8180
8181static struct hda_verb alc883_mitac_verbs[] = {
8182 /* HP */
8183 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8184 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8185 /* Subwoofer */
8186 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8187 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8188
8189 /* enable unsolicited event */
8190 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8191 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8192
8193 { } /* end */
8194};
8195
8196static struct hda_verb alc883_clevo_m540r_verbs[] = {
8197 /* HP */
8198 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8199 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8200 /* Int speaker */
8201 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8202
8203 /* enable unsolicited event */
8204 /*
8205 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8206 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8207 */
8208
8209 { } /* end */
8210};
8211
8212static struct hda_verb alc883_clevo_m720_verbs[] = {
8213 /* HP */
8214 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8216 /* Int speaker */
8217 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8219
8220 /* enable unsolicited event */
8221 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8222 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8223
8224 { } /* end */
8225};
8226
8227static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8228 /* HP */
8229 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8230 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8231 /* Subwoofer */
8232 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8233 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8234
8235 /* enable unsolicited event */
8236 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8237
8238 { } /* end */
8239};
8240
8241static struct hda_verb alc883_targa_verbs[] = {
8242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8243 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8244
8245 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8247
8248/* Connect Line-Out side jack (SPDIF) to Side */
8249 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8250 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8251 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8252/* Connect Mic jack to CLFE */
8253 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8254 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8255 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8256/* Connect Line-in jack to Surround */
8257 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8258 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8259 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8260/* Connect HP out jack to Front */
8261 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8262 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8263 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8264
8265 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8266
8267 { } /* end */
8268};
8269
8270static struct hda_verb alc883_lenovo_101e_verbs[] = {
8271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8272 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8273 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8274 { } /* end */
8275};
8276
8277static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8278 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8279 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8280 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8281 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8282 { } /* end */
8283};
8284
8285static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8288 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8289 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8290 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8291 { } /* end */
8292};
8293
8294static struct hda_verb alc883_haier_w66_verbs[] = {
8295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8297
8298 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8299
8300 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8301 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8302 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8303 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8304 { } /* end */
8305};
8306
8307static struct hda_verb alc888_lenovo_sky_verbs[] = {
8308 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8309 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8310 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8311 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8313 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8314 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8315 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8316 { } /* end */
8317};
8318
8319static struct hda_verb alc888_6st_dell_verbs[] = {
8320 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8321 { }
8322};
8323
8324static struct hda_verb alc883_vaiott_verbs[] = {
8325 /* HP */
8326 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8328
8329 /* enable unsolicited event */
8330 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8331
8332 { } /* end */
8333};
8334
8335static void alc888_3st_hp_setup(struct hda_codec *codec)
8336{
8337 struct alc_spec *spec = codec->spec;
8338
8339 spec->autocfg.hp_pins[0] = 0x1b;
8340 spec->autocfg.speaker_pins[0] = 0x14;
8341 spec->autocfg.speaker_pins[1] = 0x16;
8342 spec->autocfg.speaker_pins[2] = 0x18;
8343}
8344
8345static struct hda_verb alc888_3st_hp_verbs[] = {
8346 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8347 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8348 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8349 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8350 { } /* end */
8351};
8352
8353/*
8354 * 2ch mode
8355 */
8356static struct hda_verb alc888_3st_hp_2ch_init[] = {
8357 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8358 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8359 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8360 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8361 { } /* end */
8362};
8363
8364/*
8365 * 4ch mode
8366 */
8367static struct hda_verb alc888_3st_hp_4ch_init[] = {
8368 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8369 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8370 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8371 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8372 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8373 { } /* end */
8374};
8375
8376/*
8377 * 6ch mode
8378 */
8379static struct hda_verb alc888_3st_hp_6ch_init[] = {
8380 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8381 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8382 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8383 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8384 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8385 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8386 { } /* end */
8387};
8388
8389static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8390 { 2, alc888_3st_hp_2ch_init },
8391 { 4, alc888_3st_hp_4ch_init },
8392 { 6, alc888_3st_hp_6ch_init },
8393};
8394
8395/* toggle front-jack and RCA according to the hp-jack state */
8396static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8397{
8398 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
8399
8400 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8401 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8402 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8403 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8404}
8405
8406/* toggle RCA according to the front-jack state */
8407static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8408{
8409 unsigned int present = snd_hda_jack_detect(codec, 0x14);
8410
8411 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8412 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8413}
8414
8415static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8416 unsigned int res)
8417{
8418 if ((res >> 26) == ALC880_HP_EVENT)
8419 alc888_lenovo_ms7195_front_automute(codec);
8420 if ((res >> 26) == ALC880_FRONT_EVENT)
8421 alc888_lenovo_ms7195_rca_automute(codec);
8422}
8423
8424static struct hda_verb alc883_medion_md2_verbs[] = {
8425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8427
8428 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8429
8430 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8431 { } /* end */
8432};
8433
8434/* toggle speaker-output according to the hp-jack state */
8435static void alc883_medion_md2_setup(struct hda_codec *codec)
8436{
8437 struct alc_spec *spec = codec->spec;
8438
8439 spec->autocfg.hp_pins[0] = 0x14;
8440 spec->autocfg.speaker_pins[0] = 0x15;
8441}
8442
8443/* toggle speaker-output according to the hp-jack state */
8444#define alc883_targa_init_hook alc882_targa_init_hook
8445#define alc883_targa_unsol_event alc882_targa_unsol_event
8446
8447static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8448{
8449 unsigned int present;
8450
8451 present = snd_hda_jack_detect(codec, 0x18);
8452 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8453 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8454}
8455
8456static void alc883_clevo_m720_setup(struct hda_codec *codec)
8457{
8458 struct alc_spec *spec = codec->spec;
8459
8460 spec->autocfg.hp_pins[0] = 0x15;
8461 spec->autocfg.speaker_pins[0] = 0x14;
8462}
8463
8464static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8465{
8466 alc_automute_amp(codec);
8467 alc883_clevo_m720_mic_automute(codec);
8468}
8469
8470static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8471 unsigned int res)
8472{
8473 switch (res >> 26) {
8474 case ALC880_MIC_EVENT:
8475 alc883_clevo_m720_mic_automute(codec);
8476 break;
8477 default:
8478 alc_automute_amp_unsol_event(codec, res);
8479 break;
8480 }
8481}
8482
8483/* toggle speaker-output according to the hp-jack state */
8484static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
8485{
8486 struct alc_spec *spec = codec->spec;
8487
8488 spec->autocfg.hp_pins[0] = 0x14;
8489 spec->autocfg.speaker_pins[0] = 0x15;
8490}
8491
8492static void alc883_haier_w66_setup(struct hda_codec *codec)
8493{
8494 struct alc_spec *spec = codec->spec;
8495
8496 spec->autocfg.hp_pins[0] = 0x1b;
8497 spec->autocfg.speaker_pins[0] = 0x14;
8498}
8499
8500static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8501{
8502 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
8503
8504 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8505 HDA_AMP_MUTE, bits);
8506}
8507
8508static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8509{
8510 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
8511
8512 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8513 HDA_AMP_MUTE, bits);
8514 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8515 HDA_AMP_MUTE, bits);
8516}
8517
8518static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8519 unsigned int res)
8520{
8521 if ((res >> 26) == ALC880_HP_EVENT)
8522 alc883_lenovo_101e_all_automute(codec);
8523 if ((res >> 26) == ALC880_FRONT_EVENT)
8524 alc883_lenovo_101e_ispeaker_automute(codec);
8525}
8526
8527/* toggle speaker-output according to the hp-jack state */
8528static void alc883_acer_aspire_setup(struct hda_codec *codec)
8529{
8530 struct alc_spec *spec = codec->spec;
8531
8532 spec->autocfg.hp_pins[0] = 0x14;
8533 spec->autocfg.speaker_pins[0] = 0x15;
8534 spec->autocfg.speaker_pins[1] = 0x16;
8535}
8536
8537static struct hda_verb alc883_acer_eapd_verbs[] = {
8538 /* HP Pin: output 0 (0x0c) */
8539 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8541 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8542 /* Front Pin: output 0 (0x0c) */
8543 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8545 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8546 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8547 /* eanable EAPD on medion laptop */
8548 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8549 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8550 /* enable unsolicited event */
8551 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8552 { }
8553};
8554
8555static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
8556 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8557 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8558 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8559 { } /* end */
8560};
8561
8562static void alc888_6st_dell_setup(struct hda_codec *codec)
8563{
8564 struct alc_spec *spec = codec->spec;
8565
8566 spec->autocfg.hp_pins[0] = 0x1b;
8567 spec->autocfg.speaker_pins[0] = 0x14;
8568 spec->autocfg.speaker_pins[1] = 0x15;
8569 spec->autocfg.speaker_pins[2] = 0x16;
8570 spec->autocfg.speaker_pins[3] = 0x17;
8571}
8572
8573static void alc888_lenovo_sky_setup(struct hda_codec *codec)
8574{
8575 struct alc_spec *spec = codec->spec;
8576
8577 spec->autocfg.hp_pins[0] = 0x1b;
8578 spec->autocfg.speaker_pins[0] = 0x14;
8579 spec->autocfg.speaker_pins[1] = 0x15;
8580 spec->autocfg.speaker_pins[2] = 0x16;
8581 spec->autocfg.speaker_pins[3] = 0x17;
8582 spec->autocfg.speaker_pins[4] = 0x1a;
8583}
8584
8585static void alc883_vaiott_setup(struct hda_codec *codec)
8586{
8587 struct alc_spec *spec = codec->spec;
8588
8589 spec->autocfg.hp_pins[0] = 0x15;
8590 spec->autocfg.speaker_pins[0] = 0x14;
8591 spec->autocfg.speaker_pins[1] = 0x17;
8592}
8593
8594static struct hda_verb alc888_asus_m90v_verbs[] = {
8595 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8597 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8598 /* enable unsolicited event */
8599 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8600 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8601 { } /* end */
8602};
8603
8604static void alc883_mode2_setup(struct hda_codec *codec)
8605{
8606 struct alc_spec *spec = codec->spec;
8607
8608 spec->autocfg.hp_pins[0] = 0x1b;
8609 spec->autocfg.speaker_pins[0] = 0x14;
8610 spec->autocfg.speaker_pins[1] = 0x15;
8611 spec->autocfg.speaker_pins[2] = 0x16;
8612 spec->ext_mic.pin = 0x18;
8613 spec->int_mic.pin = 0x19;
8614 spec->ext_mic.mux_idx = 0;
8615 spec->int_mic.mux_idx = 1;
8616 spec->auto_mic = 1;
8617}
8618
8619static struct hda_verb alc888_asus_eee1601_verbs[] = {
8620 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8621 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8622 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8623 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8624 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8625 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8626 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8627 /* enable unsolicited event */
8628 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8629 { } /* end */
8630};
8631
8632static void alc883_eee1601_inithook(struct hda_codec *codec)
8633{
8634 struct alc_spec *spec = codec->spec;
8635
8636 spec->autocfg.hp_pins[0] = 0x14;
8637 spec->autocfg.speaker_pins[0] = 0x1b;
8638 alc_automute_pin(codec);
8639}
8640
8641static struct hda_verb alc889A_mb31_verbs[] = {
8642 /* Init rear pin (used as headphone output) */
8643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8645 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8646 /* Init line pin (used as output in 4ch and 6ch mode) */
8647 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8648 /* Init line 2 pin (used as headphone out by default) */
8649 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8650 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8651 { } /* end */
8652};
8653
8654/* Mute speakers according to the headphone jack state */
8655static void alc889A_mb31_automute(struct hda_codec *codec)
8656{
8657 unsigned int present;
8658
8659 /* Mute only in 2ch or 4ch mode */
8660 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8661 == 0x00) {
8662 present = snd_hda_jack_detect(codec, 0x15);
8663 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8664 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8665 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8666 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8667 }
8668}
8669
8670static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8671{
8672 if ((res >> 26) == ALC880_HP_EVENT)
8673 alc889A_mb31_automute(codec);
8674}
8675
8676
8677#ifdef CONFIG_SND_HDA_POWER_SAVE
8678#define alc882_loopbacks alc880_loopbacks
8679#endif
8680
8681/* pcm configuration: identical with ALC880 */
8682#define alc882_pcm_analog_playback alc880_pcm_analog_playback
8683#define alc882_pcm_analog_capture alc880_pcm_analog_capture
8684#define alc882_pcm_digital_playback alc880_pcm_digital_playback
8685#define alc882_pcm_digital_capture alc880_pcm_digital_capture
8686
8687static hda_nid_t alc883_slave_dig_outs[] = {
8688 ALC1200_DIGOUT_NID, 0,
8689};
8690
8691static hda_nid_t alc1200_slave_dig_outs[] = {
8692 ALC883_DIGOUT_NID, 0,
8693};
8694
8695/*
8696 * configuration and preset
8697 */
8698static const char *alc882_models[ALC882_MODEL_LAST] = {
8699 [ALC882_3ST_DIG] = "3stack-dig",
8700 [ALC882_6ST_DIG] = "6stack-dig",
8701 [ALC882_ARIMA] = "arima",
8702 [ALC882_W2JC] = "w2jc",
8703 [ALC882_TARGA] = "targa",
8704 [ALC882_ASUS_A7J] = "asus-a7j",
8705 [ALC882_ASUS_A7M] = "asus-a7m",
8706 [ALC885_MACPRO] = "macpro",
8707 [ALC885_MB5] = "mb5",
8708 [ALC885_MBP3] = "mbp3",
8709 [ALC885_IMAC24] = "imac24",
8710 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
8711 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8712 [ALC883_3ST_6ch] = "3stack-6ch",
8713 [ALC883_6ST_DIG] = "alc883-6stack-dig",
8714 [ALC883_TARGA_DIG] = "targa-dig",
8715 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8716 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
8717 [ALC883_ACER] = "acer",
8718 [ALC883_ACER_ASPIRE] = "acer-aspire",
8719 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8720 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
8721 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
8722 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
8723 [ALC883_MEDION] = "medion",
8724 [ALC883_MEDION_MD2] = "medion-md2",
8725 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8726 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8727 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8728 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8729 [ALC888_LENOVO_SKY] = "lenovo-sky",
8730 [ALC883_HAIER_W66] = "haier-w66",
8731 [ALC888_3ST_HP] = "3stack-hp",
8732 [ALC888_6ST_DELL] = "6stack-dell",
8733 [ALC883_MITAC] = "mitac",
8734 [ALC883_CLEVO_M540R] = "clevo-m540r",
8735 [ALC883_CLEVO_M720] = "clevo-m720",
8736 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8737 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8738 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8739 [ALC889A_INTEL] = "intel-alc889a",
8740 [ALC889_INTEL] = "intel-x58",
8741 [ALC1200_ASUS_P5Q] = "asus-p5q",
8742 [ALC889A_MB31] = "mb31",
8743 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
8744 [ALC882_AUTO] = "auto",
8745};
8746
8747static struct snd_pci_quirk alc882_cfg_tbl[] = {
8748 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8749
8750 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8751 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8752 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8753 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8754 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8755 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8756 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8757 ALC888_ACER_ASPIRE_4930G),
8758 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8759 ALC888_ACER_ASPIRE_4930G),
8760 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8761 ALC888_ACER_ASPIRE_8930G),
8762 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
8763 ALC888_ACER_ASPIRE_8930G),
8764 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
8765 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
8766 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8767 ALC888_ACER_ASPIRE_6530G),
8768 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8769 ALC888_ACER_ASPIRE_6530G),
8770 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
8771 ALC888_ACER_ASPIRE_7730G),
8772 /* default Acer -- disabled as it causes more problems.
8773 * model=auto should work fine now
8774 */
8775 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8776
8777 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8778
8779 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8780 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8781 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8782 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8783 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8784 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8785
8786 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8787 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8788 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
8789 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8790 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8791 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8792 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
8793 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8794 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8795 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8796 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8797
8798 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
8799 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8800 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
8801 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8802 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8803 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8804 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8805 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8806 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8807
8808 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8809 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8810 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8811 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
8812 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8813 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
8814 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8815 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8816 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8817 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8818 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8819 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8820 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8821 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8822 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
8823 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8824 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8825 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8826 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
8827 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8828 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8829 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8830 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8831 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8832 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8833 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8834 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
8835 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8836 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
8837
8838 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8839 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8840 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8841 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
8842 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8843 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8844 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
8845 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8846 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8847 ALC883_FUJITSU_PI2515),
8848 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8849 ALC888_FUJITSU_XA3530),
8850 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8851 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8852 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8853 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8854 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8855 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8856 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8857 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8858 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8859
8860 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8861 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8862 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8863 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
8864 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
8865 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
8866 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8867
8868 {}
8869};
8870
8871/* codec SSID table for Intel Mac */
8872static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8873 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8874 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8875 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8876 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8877 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8878 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8879 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8880 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8881 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8882 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8883 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8884 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
8885 * so apparently no perfect solution yet
8886 */
8887 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8888 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
8889 {} /* terminator */
8890};
8891
8892static struct alc_config_preset alc882_presets[] = {
8893 [ALC882_3ST_DIG] = {
8894 .mixers = { alc882_base_mixer },
8895 .init_verbs = { alc882_base_init_verbs,
8896 alc882_adc1_init_verbs },
8897 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8898 .dac_nids = alc882_dac_nids,
8899 .dig_out_nid = ALC882_DIGOUT_NID,
8900 .dig_in_nid = ALC882_DIGIN_NID,
8901 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8902 .channel_mode = alc882_ch_modes,
8903 .need_dac_fix = 1,
8904 .input_mux = &alc882_capture_source,
8905 },
8906 [ALC882_6ST_DIG] = {
8907 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8908 .init_verbs = { alc882_base_init_verbs,
8909 alc882_adc1_init_verbs },
8910 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8911 .dac_nids = alc882_dac_nids,
8912 .dig_out_nid = ALC882_DIGOUT_NID,
8913 .dig_in_nid = ALC882_DIGIN_NID,
8914 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8915 .channel_mode = alc882_sixstack_modes,
8916 .input_mux = &alc882_capture_source,
8917 },
8918 [ALC882_ARIMA] = {
8919 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8920 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8921 alc882_eapd_verbs },
8922 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8923 .dac_nids = alc882_dac_nids,
8924 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8925 .channel_mode = alc882_sixstack_modes,
8926 .input_mux = &alc882_capture_source,
8927 },
8928 [ALC882_W2JC] = {
8929 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8930 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8931 alc882_eapd_verbs, alc880_gpio1_init_verbs },
8932 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8933 .dac_nids = alc882_dac_nids,
8934 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8935 .channel_mode = alc880_threestack_modes,
8936 .need_dac_fix = 1,
8937 .input_mux = &alc882_capture_source,
8938 .dig_out_nid = ALC882_DIGOUT_NID,
8939 },
8940 [ALC885_MBP3] = {
8941 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8942 .init_verbs = { alc885_mbp3_init_verbs,
8943 alc880_gpio1_init_verbs },
8944 .num_dacs = 2,
8945 .dac_nids = alc882_dac_nids,
8946 .hp_nid = 0x04,
8947 .channel_mode = alc885_mbp_4ch_modes,
8948 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
8949 .input_mux = &alc882_capture_source,
8950 .dig_out_nid = ALC882_DIGOUT_NID,
8951 .dig_in_nid = ALC882_DIGIN_NID,
8952 .unsol_event = alc_automute_amp_unsol_event,
8953 .setup = alc885_mbp3_setup,
8954 .init_hook = alc_automute_amp,
8955 },
8956 [ALC885_MB5] = {
8957 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8958 .init_verbs = { alc885_mb5_init_verbs,
8959 alc880_gpio1_init_verbs },
8960 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8961 .dac_nids = alc882_dac_nids,
8962 .channel_mode = alc885_mb5_6ch_modes,
8963 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8964 .input_mux = &mb5_capture_source,
8965 .dig_out_nid = ALC882_DIGOUT_NID,
8966 .dig_in_nid = ALC882_DIGIN_NID,
8967 },
8968 [ALC885_MACPRO] = {
8969 .mixers = { alc882_macpro_mixer },
8970 .init_verbs = { alc882_macpro_init_verbs },
8971 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8972 .dac_nids = alc882_dac_nids,
8973 .dig_out_nid = ALC882_DIGOUT_NID,
8974 .dig_in_nid = ALC882_DIGIN_NID,
8975 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8976 .channel_mode = alc882_ch_modes,
8977 .input_mux = &alc882_capture_source,
8978 .init_hook = alc885_macpro_init_hook,
8979 },
8980 [ALC885_IMAC24] = {
8981 .mixers = { alc885_imac24_mixer },
8982 .init_verbs = { alc885_imac24_init_verbs },
8983 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8984 .dac_nids = alc882_dac_nids,
8985 .dig_out_nid = ALC882_DIGOUT_NID,
8986 .dig_in_nid = ALC882_DIGIN_NID,
8987 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8988 .channel_mode = alc882_ch_modes,
8989 .input_mux = &alc882_capture_source,
8990 .unsol_event = alc_automute_amp_unsol_event,
8991 .setup = alc885_imac24_setup,
8992 .init_hook = alc885_imac24_init_hook,
8993 },
8994 [ALC882_TARGA] = {
8995 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8996 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8997 alc880_gpio3_init_verbs, alc882_targa_verbs},
8998 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8999 .dac_nids = alc882_dac_nids,
9000 .dig_out_nid = ALC882_DIGOUT_NID,
9001 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9002 .adc_nids = alc882_adc_nids,
9003 .capsrc_nids = alc882_capsrc_nids,
9004 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9005 .channel_mode = alc882_3ST_6ch_modes,
9006 .need_dac_fix = 1,
9007 .input_mux = &alc882_capture_source,
9008 .unsol_event = alc882_targa_unsol_event,
9009 .setup = alc882_targa_setup,
9010 .init_hook = alc882_targa_automute,
9011 },
9012 [ALC882_ASUS_A7J] = {
9013 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9014 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9015 alc882_asus_a7j_verbs},
9016 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9017 .dac_nids = alc882_dac_nids,
9018 .dig_out_nid = ALC882_DIGOUT_NID,
9019 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9020 .adc_nids = alc882_adc_nids,
9021 .capsrc_nids = alc882_capsrc_nids,
9022 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9023 .channel_mode = alc882_3ST_6ch_modes,
9024 .need_dac_fix = 1,
9025 .input_mux = &alc882_capture_source,
9026 },
9027 [ALC882_ASUS_A7M] = {
9028 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9029 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9030 alc882_eapd_verbs, alc880_gpio1_init_verbs,
9031 alc882_asus_a7m_verbs },
9032 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9033 .dac_nids = alc882_dac_nids,
9034 .dig_out_nid = ALC882_DIGOUT_NID,
9035 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9036 .channel_mode = alc880_threestack_modes,
9037 .need_dac_fix = 1,
9038 .input_mux = &alc882_capture_source,
9039 },
9040 [ALC883_3ST_2ch_DIG] = {
9041 .mixers = { alc883_3ST_2ch_mixer },
9042 .init_verbs = { alc883_init_verbs },
9043 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9044 .dac_nids = alc883_dac_nids,
9045 .dig_out_nid = ALC883_DIGOUT_NID,
9046 .dig_in_nid = ALC883_DIGIN_NID,
9047 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9048 .channel_mode = alc883_3ST_2ch_modes,
9049 .input_mux = &alc883_capture_source,
9050 },
9051 [ALC883_3ST_6ch_DIG] = {
9052 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9053 .init_verbs = { alc883_init_verbs },
9054 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9055 .dac_nids = alc883_dac_nids,
9056 .dig_out_nid = ALC883_DIGOUT_NID,
9057 .dig_in_nid = ALC883_DIGIN_NID,
9058 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9059 .channel_mode = alc883_3ST_6ch_modes,
9060 .need_dac_fix = 1,
9061 .input_mux = &alc883_capture_source,
9062 },
9063 [ALC883_3ST_6ch] = {
9064 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9065 .init_verbs = { alc883_init_verbs },
9066 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9067 .dac_nids = alc883_dac_nids,
9068 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9069 .channel_mode = alc883_3ST_6ch_modes,
9070 .need_dac_fix = 1,
9071 .input_mux = &alc883_capture_source,
9072 },
9073 [ALC883_3ST_6ch_INTEL] = {
9074 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9075 .init_verbs = { alc883_init_verbs },
9076 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9077 .dac_nids = alc883_dac_nids,
9078 .dig_out_nid = ALC883_DIGOUT_NID,
9079 .dig_in_nid = ALC883_DIGIN_NID,
9080 .slave_dig_outs = alc883_slave_dig_outs,
9081 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9082 .channel_mode = alc883_3ST_6ch_intel_modes,
9083 .need_dac_fix = 1,
9084 .input_mux = &alc883_3stack_6ch_intel,
9085 },
9086 [ALC889A_INTEL] = {
9087 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9088 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9089 alc_hp15_unsol_verbs },
9090 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9091 .dac_nids = alc883_dac_nids,
9092 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9093 .adc_nids = alc889_adc_nids,
9094 .dig_out_nid = ALC883_DIGOUT_NID,
9095 .dig_in_nid = ALC883_DIGIN_NID,
9096 .slave_dig_outs = alc883_slave_dig_outs,
9097 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9098 .channel_mode = alc889_8ch_intel_modes,
9099 .capsrc_nids = alc889_capsrc_nids,
9100 .input_mux = &alc889_capture_source,
9101 .setup = alc889_automute_setup,
9102 .init_hook = alc_automute_amp,
9103 .unsol_event = alc_automute_amp_unsol_event,
9104 .need_dac_fix = 1,
9105 },
9106 [ALC889_INTEL] = {
9107 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9108 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9109 alc889_eapd_verbs, alc_hp15_unsol_verbs},
9110 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9111 .dac_nids = alc883_dac_nids,
9112 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9113 .adc_nids = alc889_adc_nids,
9114 .dig_out_nid = ALC883_DIGOUT_NID,
9115 .dig_in_nid = ALC883_DIGIN_NID,
9116 .slave_dig_outs = alc883_slave_dig_outs,
9117 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9118 .channel_mode = alc889_8ch_intel_modes,
9119 .capsrc_nids = alc889_capsrc_nids,
9120 .input_mux = &alc889_capture_source,
9121 .setup = alc889_automute_setup,
9122 .init_hook = alc889_intel_init_hook,
9123 .unsol_event = alc_automute_amp_unsol_event,
9124 .need_dac_fix = 1,
9125 },
9126 [ALC883_6ST_DIG] = {
9127 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9128 .init_verbs = { alc883_init_verbs },
9129 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9130 .dac_nids = alc883_dac_nids,
9131 .dig_out_nid = ALC883_DIGOUT_NID,
9132 .dig_in_nid = ALC883_DIGIN_NID,
9133 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9134 .channel_mode = alc883_sixstack_modes,
9135 .input_mux = &alc883_capture_source,
9136 },
9137 [ALC883_TARGA_DIG] = {
9138 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9139 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9140 alc883_targa_verbs},
9141 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9142 .dac_nids = alc883_dac_nids,
9143 .dig_out_nid = ALC883_DIGOUT_NID,
9144 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9145 .channel_mode = alc883_3ST_6ch_modes,
9146 .need_dac_fix = 1,
9147 .input_mux = &alc883_capture_source,
9148 .unsol_event = alc883_targa_unsol_event,
9149 .setup = alc882_targa_setup,
9150 .init_hook = alc882_targa_automute,
9151 },
9152 [ALC883_TARGA_2ch_DIG] = {
9153 .mixers = { alc883_targa_2ch_mixer},
9154 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9155 alc883_targa_verbs},
9156 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9157 .dac_nids = alc883_dac_nids,
9158 .adc_nids = alc883_adc_nids_alt,
9159 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9160 .dig_out_nid = ALC883_DIGOUT_NID,
9161 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9162 .channel_mode = alc883_3ST_2ch_modes,
9163 .input_mux = &alc883_capture_source,
9164 .unsol_event = alc883_targa_unsol_event,
9165 .setup = alc882_targa_setup,
9166 .init_hook = alc882_targa_automute,
9167 },
9168 [ALC883_TARGA_8ch_DIG] = {
9169 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9170 alc883_chmode_mixer },
9171 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9172 alc883_targa_verbs },
9173 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9174 .dac_nids = alc883_dac_nids,
9175 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9176 .adc_nids = alc883_adc_nids_rev,
9177 .capsrc_nids = alc883_capsrc_nids_rev,
9178 .dig_out_nid = ALC883_DIGOUT_NID,
9179 .dig_in_nid = ALC883_DIGIN_NID,
9180 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9181 .channel_mode = alc883_4ST_8ch_modes,
9182 .need_dac_fix = 1,
9183 .input_mux = &alc883_capture_source,
9184 .unsol_event = alc883_targa_unsol_event,
9185 .setup = alc882_targa_setup,
9186 .init_hook = alc882_targa_automute,
9187 },
9188 [ALC883_ACER] = {
9189 .mixers = { alc883_base_mixer },
9190 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9191 * and the headphone jack. Turn this on and rely on the
9192 * standard mute methods whenever the user wants to turn
9193 * these outputs off.
9194 */
9195 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9196 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9197 .dac_nids = alc883_dac_nids,
9198 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9199 .channel_mode = alc883_3ST_2ch_modes,
9200 .input_mux = &alc883_capture_source,
9201 },
9202 [ALC883_ACER_ASPIRE] = {
9203 .mixers = { alc883_acer_aspire_mixer },
9204 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9205 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9206 .dac_nids = alc883_dac_nids,
9207 .dig_out_nid = ALC883_DIGOUT_NID,
9208 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9209 .channel_mode = alc883_3ST_2ch_modes,
9210 .input_mux = &alc883_capture_source,
9211 .unsol_event = alc_automute_amp_unsol_event,
9212 .setup = alc883_acer_aspire_setup,
9213 .init_hook = alc_automute_amp,
9214 },
9215 [ALC888_ACER_ASPIRE_4930G] = {
9216 .mixers = { alc888_base_mixer,
9217 alc883_chmode_mixer },
9218 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9219 alc888_acer_aspire_4930g_verbs },
9220 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9221 .dac_nids = alc883_dac_nids,
9222 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9223 .adc_nids = alc883_adc_nids_rev,
9224 .capsrc_nids = alc883_capsrc_nids_rev,
9225 .dig_out_nid = ALC883_DIGOUT_NID,
9226 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9227 .channel_mode = alc883_3ST_6ch_modes,
9228 .need_dac_fix = 1,
9229 .num_mux_defs =
9230 ARRAY_SIZE(alc888_2_capture_sources),
9231 .input_mux = alc888_2_capture_sources,
9232 .unsol_event = alc_automute_amp_unsol_event,
9233 .setup = alc888_acer_aspire_4930g_setup,
9234 .init_hook = alc_automute_amp,
9235 },
9236 [ALC888_ACER_ASPIRE_6530G] = {
9237 .mixers = { alc888_acer_aspire_6530_mixer },
9238 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9239 alc888_acer_aspire_6530g_verbs },
9240 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9241 .dac_nids = alc883_dac_nids,
9242 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9243 .adc_nids = alc883_adc_nids_rev,
9244 .capsrc_nids = alc883_capsrc_nids_rev,
9245 .dig_out_nid = ALC883_DIGOUT_NID,
9246 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9247 .channel_mode = alc883_3ST_2ch_modes,
9248 .num_mux_defs =
9249 ARRAY_SIZE(alc888_2_capture_sources),
9250 .input_mux = alc888_acer_aspire_6530_sources,
9251 .unsol_event = alc_automute_amp_unsol_event,
9252 .setup = alc888_acer_aspire_6530g_setup,
9253 .init_hook = alc_automute_amp,
9254 },
9255 [ALC888_ACER_ASPIRE_8930G] = {
9256 .mixers = { alc888_base_mixer,
9257 alc883_chmode_mixer },
9258 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9259 alc889_acer_aspire_8930g_verbs },
9260 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9261 .dac_nids = alc883_dac_nids,
9262 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9263 .adc_nids = alc889_adc_nids,
9264 .capsrc_nids = alc889_capsrc_nids,
9265 .dig_out_nid = ALC883_DIGOUT_NID,
9266 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9267 .channel_mode = alc883_3ST_6ch_modes,
9268 .need_dac_fix = 1,
9269 .const_channel_count = 6,
9270 .num_mux_defs =
9271 ARRAY_SIZE(alc889_capture_sources),
9272 .input_mux = alc889_capture_sources,
9273 .unsol_event = alc_automute_amp_unsol_event,
9274 .setup = alc889_acer_aspire_8930g_setup,
9275 .init_hook = alc_automute_amp,
9276 },
9277 [ALC888_ACER_ASPIRE_7730G] = {
9278 .mixers = { alc883_3ST_6ch_mixer,
9279 alc883_chmode_mixer },
9280 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9281 alc888_acer_aspire_7730G_verbs },
9282 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9283 .dac_nids = alc883_dac_nids,
9284 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9285 .adc_nids = alc883_adc_nids_rev,
9286 .capsrc_nids = alc883_capsrc_nids_rev,
9287 .dig_out_nid = ALC883_DIGOUT_NID,
9288 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9289 .channel_mode = alc883_3ST_6ch_modes,
9290 .need_dac_fix = 1,
9291 .const_channel_count = 6,
9292 .input_mux = &alc883_capture_source,
9293 .unsol_event = alc_automute_amp_unsol_event,
9294 .setup = alc888_acer_aspire_6530g_setup,
9295 .init_hook = alc_automute_amp,
9296 },
9297 [ALC883_MEDION] = {
9298 .mixers = { alc883_fivestack_mixer,
9299 alc883_chmode_mixer },
9300 .init_verbs = { alc883_init_verbs,
9301 alc883_medion_eapd_verbs },
9302 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9303 .dac_nids = alc883_dac_nids,
9304 .adc_nids = alc883_adc_nids_alt,
9305 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9306 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9307 .channel_mode = alc883_sixstack_modes,
9308 .input_mux = &alc883_capture_source,
9309 },
9310 [ALC883_MEDION_MD2] = {
9311 .mixers = { alc883_medion_md2_mixer},
9312 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9313 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9314 .dac_nids = alc883_dac_nids,
9315 .dig_out_nid = ALC883_DIGOUT_NID,
9316 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9317 .channel_mode = alc883_3ST_2ch_modes,
9318 .input_mux = &alc883_capture_source,
9319 .unsol_event = alc_automute_amp_unsol_event,
9320 .setup = alc883_medion_md2_setup,
9321 .init_hook = alc_automute_amp,
9322 },
9323 [ALC883_LAPTOP_EAPD] = {
9324 .mixers = { alc883_base_mixer },
9325 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9326 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9327 .dac_nids = alc883_dac_nids,
9328 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9329 .channel_mode = alc883_3ST_2ch_modes,
9330 .input_mux = &alc883_capture_source,
9331 },
9332 [ALC883_CLEVO_M540R] = {
9333 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9334 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9335 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9336 .dac_nids = alc883_dac_nids,
9337 .dig_out_nid = ALC883_DIGOUT_NID,
9338 .dig_in_nid = ALC883_DIGIN_NID,
9339 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9340 .channel_mode = alc883_3ST_6ch_clevo_modes,
9341 .need_dac_fix = 1,
9342 .input_mux = &alc883_capture_source,
9343 /* This machine has the hardware HP auto-muting, thus
9344 * we need no software mute via unsol event
9345 */
9346 },
9347 [ALC883_CLEVO_M720] = {
9348 .mixers = { alc883_clevo_m720_mixer },
9349 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9350 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9351 .dac_nids = alc883_dac_nids,
9352 .dig_out_nid = ALC883_DIGOUT_NID,
9353 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9354 .channel_mode = alc883_3ST_2ch_modes,
9355 .input_mux = &alc883_capture_source,
9356 .unsol_event = alc883_clevo_m720_unsol_event,
9357 .setup = alc883_clevo_m720_setup,
9358 .init_hook = alc883_clevo_m720_init_hook,
9359 },
9360 [ALC883_LENOVO_101E_2ch] = {
9361 .mixers = { alc883_lenovo_101e_2ch_mixer},
9362 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9363 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9364 .dac_nids = alc883_dac_nids,
9365 .adc_nids = alc883_adc_nids_alt,
9366 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9367 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9368 .channel_mode = alc883_3ST_2ch_modes,
9369 .input_mux = &alc883_lenovo_101e_capture_source,
9370 .unsol_event = alc883_lenovo_101e_unsol_event,
9371 .init_hook = alc883_lenovo_101e_all_automute,
9372 },
9373 [ALC883_LENOVO_NB0763] = {
9374 .mixers = { alc883_lenovo_nb0763_mixer },
9375 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9376 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9377 .dac_nids = alc883_dac_nids,
9378 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9379 .channel_mode = alc883_3ST_2ch_modes,
9380 .need_dac_fix = 1,
9381 .input_mux = &alc883_lenovo_nb0763_capture_source,
9382 .unsol_event = alc_automute_amp_unsol_event,
9383 .setup = alc883_medion_md2_setup,
9384 .init_hook = alc_automute_amp,
9385 },
9386 [ALC888_LENOVO_MS7195_DIG] = {
9387 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9388 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9389 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9390 .dac_nids = alc883_dac_nids,
9391 .dig_out_nid = ALC883_DIGOUT_NID,
9392 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9393 .channel_mode = alc883_3ST_6ch_modes,
9394 .need_dac_fix = 1,
9395 .input_mux = &alc883_capture_source,
9396 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9397 .init_hook = alc888_lenovo_ms7195_front_automute,
9398 },
9399 [ALC883_HAIER_W66] = {
9400 .mixers = { alc883_targa_2ch_mixer},
9401 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9402 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9403 .dac_nids = alc883_dac_nids,
9404 .dig_out_nid = ALC883_DIGOUT_NID,
9405 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9406 .channel_mode = alc883_3ST_2ch_modes,
9407 .input_mux = &alc883_capture_source,
9408 .unsol_event = alc_automute_amp_unsol_event,
9409 .setup = alc883_haier_w66_setup,
9410 .init_hook = alc_automute_amp,
9411 },
9412 [ALC888_3ST_HP] = {
9413 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9414 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9415 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9416 .dac_nids = alc883_dac_nids,
9417 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9418 .channel_mode = alc888_3st_hp_modes,
9419 .need_dac_fix = 1,
9420 .input_mux = &alc883_capture_source,
9421 .unsol_event = alc_automute_amp_unsol_event,
9422 .setup = alc888_3st_hp_setup,
9423 .init_hook = alc_automute_amp,
9424 },
9425 [ALC888_6ST_DELL] = {
9426 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9427 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9428 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9429 .dac_nids = alc883_dac_nids,
9430 .dig_out_nid = ALC883_DIGOUT_NID,
9431 .dig_in_nid = ALC883_DIGIN_NID,
9432 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9433 .channel_mode = alc883_sixstack_modes,
9434 .input_mux = &alc883_capture_source,
9435 .unsol_event = alc_automute_amp_unsol_event,
9436 .setup = alc888_6st_dell_setup,
9437 .init_hook = alc_automute_amp,
9438 },
9439 [ALC883_MITAC] = {
9440 .mixers = { alc883_mitac_mixer },
9441 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9442 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9443 .dac_nids = alc883_dac_nids,
9444 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9445 .channel_mode = alc883_3ST_2ch_modes,
9446 .input_mux = &alc883_capture_source,
9447 .unsol_event = alc_automute_amp_unsol_event,
9448 .setup = alc883_mitac_setup,
9449 .init_hook = alc_automute_amp,
9450 },
9451 [ALC883_FUJITSU_PI2515] = {
9452 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9453 .init_verbs = { alc883_init_verbs,
9454 alc883_2ch_fujitsu_pi2515_verbs},
9455 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9456 .dac_nids = alc883_dac_nids,
9457 .dig_out_nid = ALC883_DIGOUT_NID,
9458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9459 .channel_mode = alc883_3ST_2ch_modes,
9460 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9461 .unsol_event = alc_automute_amp_unsol_event,
9462 .setup = alc883_2ch_fujitsu_pi2515_setup,
9463 .init_hook = alc_automute_amp,
9464 },
9465 [ALC888_FUJITSU_XA3530] = {
9466 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9467 .init_verbs = { alc883_init_verbs,
9468 alc888_fujitsu_xa3530_verbs },
9469 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9470 .dac_nids = alc883_dac_nids,
9471 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9472 .adc_nids = alc883_adc_nids_rev,
9473 .capsrc_nids = alc883_capsrc_nids_rev,
9474 .dig_out_nid = ALC883_DIGOUT_NID,
9475 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9476 .channel_mode = alc888_4ST_8ch_intel_modes,
9477 .num_mux_defs =
9478 ARRAY_SIZE(alc888_2_capture_sources),
9479 .input_mux = alc888_2_capture_sources,
9480 .unsol_event = alc_automute_amp_unsol_event,
9481 .setup = alc888_fujitsu_xa3530_setup,
9482 .init_hook = alc_automute_amp,
9483 },
9484 [ALC888_LENOVO_SKY] = {
9485 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9486 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9487 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9488 .dac_nids = alc883_dac_nids,
9489 .dig_out_nid = ALC883_DIGOUT_NID,
9490 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9491 .channel_mode = alc883_sixstack_modes,
9492 .need_dac_fix = 1,
9493 .input_mux = &alc883_lenovo_sky_capture_source,
9494 .unsol_event = alc_automute_amp_unsol_event,
9495 .setup = alc888_lenovo_sky_setup,
9496 .init_hook = alc_automute_amp,
9497 },
9498 [ALC888_ASUS_M90V] = {
9499 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9500 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9502 .dac_nids = alc883_dac_nids,
9503 .dig_out_nid = ALC883_DIGOUT_NID,
9504 .dig_in_nid = ALC883_DIGIN_NID,
9505 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9506 .channel_mode = alc883_3ST_6ch_modes,
9507 .need_dac_fix = 1,
9508 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9509 .unsol_event = alc_sku_unsol_event,
9510 .setup = alc883_mode2_setup,
9511 .init_hook = alc_inithook,
9512 },
9513 [ALC888_ASUS_EEE1601] = {
9514 .mixers = { alc883_asus_eee1601_mixer },
9515 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9516 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9518 .dac_nids = alc883_dac_nids,
9519 .dig_out_nid = ALC883_DIGOUT_NID,
9520 .dig_in_nid = ALC883_DIGIN_NID,
9521 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9522 .channel_mode = alc883_3ST_2ch_modes,
9523 .need_dac_fix = 1,
9524 .input_mux = &alc883_asus_eee1601_capture_source,
9525 .unsol_event = alc_sku_unsol_event,
9526 .init_hook = alc883_eee1601_inithook,
9527 },
9528 [ALC1200_ASUS_P5Q] = {
9529 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9530 .init_verbs = { alc883_init_verbs },
9531 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9532 .dac_nids = alc883_dac_nids,
9533 .dig_out_nid = ALC1200_DIGOUT_NID,
9534 .dig_in_nid = ALC883_DIGIN_NID,
9535 .slave_dig_outs = alc1200_slave_dig_outs,
9536 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9537 .channel_mode = alc883_sixstack_modes,
9538 .input_mux = &alc883_capture_source,
9539 },
9540 [ALC889A_MB31] = {
9541 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9542 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9543 alc880_gpio1_init_verbs },
9544 .adc_nids = alc883_adc_nids,
9545 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9546 .dac_nids = alc883_dac_nids,
9547 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9548 .channel_mode = alc889A_mb31_6ch_modes,
9549 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9550 .input_mux = &alc889A_mb31_capture_source,
9551 .dig_out_nid = ALC883_DIGOUT_NID,
9552 .unsol_event = alc889A_mb31_unsol_event,
9553 .init_hook = alc889A_mb31_automute,
9554 },
9555 [ALC883_SONY_VAIO_TT] = {
9556 .mixers = { alc883_vaiott_mixer },
9557 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9558 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9559 .dac_nids = alc883_dac_nids,
9560 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9561 .channel_mode = alc883_3ST_2ch_modes,
9562 .input_mux = &alc883_capture_source,
9563 .unsol_event = alc_automute_amp_unsol_event,
9564 .setup = alc883_vaiott_setup,
9565 .init_hook = alc_automute_amp,
9566 },
9567};
9568
9569
9570/*
9571 * Pin config fixes
9572 */
9573enum {
9574 PINFIX_ABIT_AW9D_MAX
9575};
9576
9577static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9578 { 0x15, 0x01080104 }, /* side */
9579 { 0x16, 0x01011012 }, /* rear */
9580 { 0x17, 0x01016011 }, /* clfe */
9581 { }
9582};
9583
9584static const struct alc_fixup alc882_fixups[] = {
9585 [PINFIX_ABIT_AW9D_MAX] = {
9586 .pins = alc882_abit_aw9d_pinfix
9587 },
9588};
9589
9590static struct snd_pci_quirk alc882_fixup_tbl[] = {
9591 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9592 {}
9593};
9594
9595/*
9596 * BIOS auto configuration
9597 */
9598static int alc882_auto_create_input_ctls(struct hda_codec *codec,
9599 const struct auto_pin_cfg *cfg)
9600{
9601 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
9602}
9603
9604static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9605 hda_nid_t nid, int pin_type,
9606 int dac_idx)
9607{
9608 /* set as output */
9609 struct alc_spec *spec = codec->spec;
9610 int idx;
9611
9612 alc_set_pin_output(codec, nid, pin_type);
9613 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9614 idx = 4;
9615 else
9616 idx = spec->multiout.dac_nids[dac_idx] - 2;
9617 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9618
9619}
9620
9621static void alc882_auto_init_multi_out(struct hda_codec *codec)
9622{
9623 struct alc_spec *spec = codec->spec;
9624 int i;
9625
9626 for (i = 0; i <= HDA_SIDE; i++) {
9627 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9628 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9629 if (nid)
9630 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9631 i);
9632 }
9633}
9634
9635static void alc882_auto_init_hp_out(struct hda_codec *codec)
9636{
9637 struct alc_spec *spec = codec->spec;
9638 hda_nid_t pin;
9639
9640 pin = spec->autocfg.hp_pins[0];
9641 if (pin) /* connect to front */
9642 /* use dac 0 */
9643 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9644 pin = spec->autocfg.speaker_pins[0];
9645 if (pin)
9646 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9647}
9648
9649static void alc882_auto_init_analog_input(struct hda_codec *codec)
9650{
9651 struct alc_spec *spec = codec->spec;
9652 int i;
9653
9654 for (i = 0; i < AUTO_PIN_LAST; i++) {
9655 hda_nid_t nid = spec->autocfg.input_pins[i];
9656 if (!nid)
9657 continue;
9658 alc_set_input_pin(codec, nid, i);
9659 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9660 snd_hda_codec_write(codec, nid, 0,
9661 AC_VERB_SET_AMP_GAIN_MUTE,
9662 AMP_OUT_MUTE);
9663 }
9664}
9665
9666static void alc882_auto_init_input_src(struct hda_codec *codec)
9667{
9668 struct alc_spec *spec = codec->spec;
9669 int c;
9670
9671 for (c = 0; c < spec->num_adc_nids; c++) {
9672 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9673 hda_nid_t nid = spec->capsrc_nids[c];
9674 unsigned int mux_idx;
9675 const struct hda_input_mux *imux;
9676 int conns, mute, idx, item;
9677
9678 conns = snd_hda_get_connections(codec, nid, conn_list,
9679 ARRAY_SIZE(conn_list));
9680 if (conns < 0)
9681 continue;
9682 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9683 imux = &spec->input_mux[mux_idx];
9684 for (idx = 0; idx < conns; idx++) {
9685 /* if the current connection is the selected one,
9686 * unmute it as default - otherwise mute it
9687 */
9688 mute = AMP_IN_MUTE(idx);
9689 for (item = 0; item < imux->num_items; item++) {
9690 if (imux->items[item].index == idx) {
9691 if (spec->cur_mux[c] == item)
9692 mute = AMP_IN_UNMUTE(idx);
9693 break;
9694 }
9695 }
9696 /* check if we have a selector or mixer
9697 * we could check for the widget type instead, but
9698 * just check for Amp-In presence (in case of mixer
9699 * without amp-in there is something wrong, this
9700 * function shouldn't be used or capsrc nid is wrong)
9701 */
9702 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9703 snd_hda_codec_write(codec, nid, 0,
9704 AC_VERB_SET_AMP_GAIN_MUTE,
9705 mute);
9706 else if (mute != AMP_IN_MUTE(idx))
9707 snd_hda_codec_write(codec, nid, 0,
9708 AC_VERB_SET_CONNECT_SEL,
9709 idx);
9710 }
9711 }
9712}
9713
9714/* add mic boosts if needed */
9715static int alc_auto_add_mic_boost(struct hda_codec *codec)
9716{
9717 struct alc_spec *spec = codec->spec;
9718 int err;
9719 hda_nid_t nid;
9720
9721 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9722 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9723 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9724 "Mic Boost",
9725 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9726 if (err < 0)
9727 return err;
9728 }
9729 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9730 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9731 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9732 "Front Mic Boost",
9733 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9734 if (err < 0)
9735 return err;
9736 }
9737 return 0;
9738}
9739
9740/* almost identical with ALC880 parser... */
9741static int alc882_parse_auto_config(struct hda_codec *codec)
9742{
9743 struct alc_spec *spec = codec->spec;
9744 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
9745 int i, err;
9746
9747 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9748 alc882_ignore);
9749 if (err < 0)
9750 return err;
9751 if (!spec->autocfg.line_outs)
9752 return 0; /* can't find valid BIOS pin config */
9753
9754 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
9755 if (err < 0)
9756 return err;
9757 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
9758 if (err < 0)
9759 return err;
9760 err = alc880_auto_create_extra_out(spec,
9761 spec->autocfg.speaker_pins[0],
9762 "Speaker");
9763 if (err < 0)
9764 return err;
9765 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
9766 "Headphone");
9767 if (err < 0)
9768 return err;
9769 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
9770 if (err < 0)
9771 return err;
9772
9773 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9774
9775 /* check multiple SPDIF-out (for recent codecs) */
9776 for (i = 0; i < spec->autocfg.dig_outs; i++) {
9777 hda_nid_t dig_nid;
9778 err = snd_hda_get_connections(codec,
9779 spec->autocfg.dig_out_pins[i],
9780 &dig_nid, 1);
9781 if (err < 0)
9782 continue;
9783 if (!i)
9784 spec->multiout.dig_out_nid = dig_nid;
9785 else {
9786 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
9787 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
9788 break;
9789 spec->slave_dig_outs[i - 1] = dig_nid;
9790 }
9791 }
9792 if (spec->autocfg.dig_in_pin)
9793 spec->dig_in_nid = ALC880_DIGIN_NID;
9794
9795 if (spec->kctls.list)
9796 add_mixer(spec, spec->kctls.list);
9797
9798 add_verb(spec, alc883_auto_init_verbs);
9799 /* if ADC 0x07 is available, initialize it, too */
9800 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
9801 add_verb(spec, alc882_adc1_init_verbs);
9802
9803 spec->num_mux_defs = 1;
9804 spec->input_mux = &spec->private_imux[0];
9805
9806 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
9807
9808 err = alc_auto_add_mic_boost(codec);
9809 if (err < 0)
9810 return err;
9811
9812 return 1; /* config found */
9813}
9814
9815/* additional initialization for auto-configuration model */
9816static void alc882_auto_init(struct hda_codec *codec)
9817{
9818 struct alc_spec *spec = codec->spec;
9819 alc882_auto_init_multi_out(codec);
9820 alc882_auto_init_hp_out(codec);
9821 alc882_auto_init_analog_input(codec);
9822 alc882_auto_init_input_src(codec);
9823 if (spec->unsol_event)
9824 alc_inithook(codec);
9825}
9826
9827static int patch_alc882(struct hda_codec *codec)
9828{
9829 struct alc_spec *spec;
9830 int err, board_config;
9831
9832 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9833 if (spec == NULL)
9834 return -ENOMEM;
9835
9836 codec->spec = spec;
9837
9838 switch (codec->vendor_id) {
9839 case 0x10ec0882:
9840 case 0x10ec0885:
9841 break;
9842 default:
9843 /* ALC883 and variants */
9844 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9845 break;
9846 }
9847
9848 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9849 alc882_models,
9850 alc882_cfg_tbl);
9851
9852 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9853 board_config = snd_hda_check_board_codec_sid_config(codec,
9854 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9855
9856 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9857 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
9858 codec->chip_name);
9859 board_config = ALC882_AUTO;
9860 }
9861
9862 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
9863
9864 if (board_config == ALC882_AUTO) {
9865 /* automatic parse from the BIOS config */
9866 err = alc882_parse_auto_config(codec);
9867 if (err < 0) {
9868 alc_free(codec);
9869 return err;
9870 } else if (!err) {
9871 printk(KERN_INFO
9872 "hda_codec: Cannot set up configuration "
9873 "from BIOS. Using base mode...\n");
9874 board_config = ALC882_3ST_DIG;
9875 }
9876 }
9877
9878 err = snd_hda_attach_beep_device(codec, 0x1);
9879 if (err < 0) {
9880 alc_free(codec);
9881 return err;
9882 }
9883
9884 if (board_config != ALC882_AUTO)
9885 setup_preset(codec, &alc882_presets[board_config]);
9886
9887 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9888 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9889 /* FIXME: setup DAC5 */
9890 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9891 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9892
9893 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9894 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9895
9896 if (codec->vendor_id == 0x10ec0888)
9897 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9898
9899 if (!spec->adc_nids && spec->input_mux) {
9900 int i;
9901 spec->num_adc_nids = 0;
9902 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9903 hda_nid_t cap;
9904 hda_nid_t nid = alc882_adc_nids[i];
9905 unsigned int wcap = get_wcaps(codec, nid);
9906 /* get type */
9907 wcap = get_wcaps_type(wcap);
9908 if (wcap != AC_WID_AUD_IN)
9909 continue;
9910 spec->private_adc_nids[spec->num_adc_nids] = nid;
9911 err = snd_hda_get_connections(codec, nid, &cap, 1);
9912 if (err < 0)
9913 continue;
9914 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9915 spec->num_adc_nids++;
9916 }
9917 spec->adc_nids = spec->private_adc_nids;
9918 spec->capsrc_nids = spec->private_capsrc_nids;
9919 }
9920
9921 set_capture_mixer(codec);
9922 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9923
9924 spec->vmaster_nid = 0x0c;
9925
9926 codec->patch_ops = alc_patch_ops;
9927 if (board_config == ALC882_AUTO)
9928 spec->init_hook = alc882_auto_init;
9929#ifdef CONFIG_SND_HDA_POWER_SAVE
9930 if (!spec->loopback.amplist)
9931 spec->loopback.amplist = alc882_loopbacks;
9932#endif
9933 codec->proc_widget_hook = print_realtek_coef;
9934
9935 return 0;
9936}
9937
9938
9939/*
9940 * ALC262 support
9941 */
9942
9943#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9944#define ALC262_DIGIN_NID ALC880_DIGIN_NID
9945
9946#define alc262_dac_nids alc260_dac_nids
9947#define alc262_adc_nids alc882_adc_nids
9948#define alc262_adc_nids_alt alc882_adc_nids_alt
9949#define alc262_capsrc_nids alc882_capsrc_nids
9950#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9951
9952#define alc262_modes alc260_modes
9953#define alc262_capture_source alc882_capture_source
9954
9955static hda_nid_t alc262_dmic_adc_nids[1] = {
9956 /* ADC0 */
9957 0x09
9958};
9959
9960static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9961
9962static struct snd_kcontrol_new alc262_base_mixer[] = {
9963 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9964 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9965 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9966 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9968 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9970 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9971 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9972 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9973 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9974 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9975 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9976 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9977 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9978 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9979 { } /* end */
9980};
9981
9982/* update HP, line and mono-out pins according to the master switch */
9983static void alc262_hp_master_update(struct hda_codec *codec)
9984{
9985 struct alc_spec *spec = codec->spec;
9986 int val = spec->master_sw;
9987
9988 /* HP & line-out */
9989 snd_hda_codec_write_cache(codec, 0x1b, 0,
9990 AC_VERB_SET_PIN_WIDGET_CONTROL,
9991 val ? PIN_HP : 0);
9992 snd_hda_codec_write_cache(codec, 0x15, 0,
9993 AC_VERB_SET_PIN_WIDGET_CONTROL,
9994 val ? PIN_HP : 0);
9995 /* mono (speaker) depending on the HP jack sense */
9996 val = val && !spec->jack_present;
9997 snd_hda_codec_write_cache(codec, 0x16, 0,
9998 AC_VERB_SET_PIN_WIDGET_CONTROL,
9999 val ? PIN_OUT : 0);
10000}
10001
10002static void alc262_hp_bpc_automute(struct hda_codec *codec)
10003{
10004 struct alc_spec *spec = codec->spec;
10005
10006 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10007 alc262_hp_master_update(codec);
10008}
10009
10010static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10011{
10012 if ((res >> 26) != ALC880_HP_EVENT)
10013 return;
10014 alc262_hp_bpc_automute(codec);
10015}
10016
10017static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10018{
10019 struct alc_spec *spec = codec->spec;
10020
10021 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10022 alc262_hp_master_update(codec);
10023}
10024
10025static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10026 unsigned int res)
10027{
10028 if ((res >> 26) != ALC880_HP_EVENT)
10029 return;
10030 alc262_hp_wildwest_automute(codec);
10031}
10032
10033#define alc262_hp_master_sw_get alc260_hp_master_sw_get
10034
10035static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10036 struct snd_ctl_elem_value *ucontrol)
10037{
10038 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10039 struct alc_spec *spec = codec->spec;
10040 int val = !!*ucontrol->value.integer.value;
10041
10042 if (val == spec->master_sw)
10043 return 0;
10044 spec->master_sw = val;
10045 alc262_hp_master_update(codec);
10046 return 1;
10047}
10048
10049#define ALC262_HP_MASTER_SWITCH \
10050 { \
10051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10052 .name = "Master Playback Switch", \
10053 .info = snd_ctl_boolean_mono_info, \
10054 .get = alc262_hp_master_sw_get, \
10055 .put = alc262_hp_master_sw_put, \
10056 }
10057
10058static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10059 ALC262_HP_MASTER_SWITCH,
10060 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10061 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10062 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10063 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10064 HDA_OUTPUT),
10065 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10066 HDA_OUTPUT),
10067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10069 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10070 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10071 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10072 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10073 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10074 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10075 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10076 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10077 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10078 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10079 { } /* end */
10080};
10081
10082static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10083 ALC262_HP_MASTER_SWITCH,
10084 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10085 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10086 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10087 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10088 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10089 HDA_OUTPUT),
10090 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10091 HDA_OUTPUT),
10092 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10093 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
10094 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
10095 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10096 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10097 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10098 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10099 { } /* end */
10100};
10101
10102static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10103 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10104 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10105 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
10106 { } /* end */
10107};
10108
10109/* mute/unmute internal speaker according to the hp jack and mute state */
10110static void alc262_hp_t5735_setup(struct hda_codec *codec)
10111{
10112 struct alc_spec *spec = codec->spec;
10113
10114 spec->autocfg.hp_pins[0] = 0x15;
10115 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
10116}
10117
10118static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10119 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10120 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10121 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10122 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10125 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10126 { } /* end */
10127};
10128
10129static struct hda_verb alc262_hp_t5735_verbs[] = {
10130 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10132
10133 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10134 { }
10135};
10136
10137static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
10138 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10139 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10140 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10141 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
10142 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10143 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10144 { } /* end */
10145};
10146
10147static struct hda_verb alc262_hp_rp5700_verbs[] = {
10148 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10149 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10150 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10151 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10152 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10153 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10155 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10157 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10158 {}
10159};
10160
10161static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10162 .num_items = 1,
10163 .items = {
10164 { "Line", 0x1 },
10165 },
10166};
10167
10168/* bind hp and internal speaker mute (with plug check) as master switch */
10169static void alc262_hippo_master_update(struct hda_codec *codec)
10170{
10171 struct alc_spec *spec = codec->spec;
10172 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10173 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10174 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10175 unsigned int mute;
10176
10177 /* HP */
10178 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10179 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10180 HDA_AMP_MUTE, mute);
10181 /* mute internal speaker per jack sense */
10182 if (spec->jack_present)
10183 mute = HDA_AMP_MUTE;
10184 if (line_nid)
10185 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10186 HDA_AMP_MUTE, mute);
10187 if (speaker_nid && speaker_nid != line_nid)
10188 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10189 HDA_AMP_MUTE, mute);
10190}
10191
10192#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10193
10194static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10195 struct snd_ctl_elem_value *ucontrol)
10196{
10197 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10198 struct alc_spec *spec = codec->spec;
10199 int val = !!*ucontrol->value.integer.value;
10200
10201 if (val == spec->master_sw)
10202 return 0;
10203 spec->master_sw = val;
10204 alc262_hippo_master_update(codec);
10205 return 1;
10206}
10207
10208#define ALC262_HIPPO_MASTER_SWITCH \
10209 { \
10210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10211 .name = "Master Playback Switch", \
10212 .info = snd_ctl_boolean_mono_info, \
10213 .get = alc262_hippo_master_sw_get, \
10214 .put = alc262_hippo_master_sw_put, \
10215 }
10216
10217static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10218 ALC262_HIPPO_MASTER_SWITCH,
10219 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10226 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10227 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10229 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10230 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10231 { } /* end */
10232};
10233
10234static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10235 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10236 ALC262_HIPPO_MASTER_SWITCH,
10237 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10238 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10239 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10240 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10241 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10242 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10244 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10245 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10246 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10247 { } /* end */
10248};
10249
10250/* mute/unmute internal speaker according to the hp jack and mute state */
10251static void alc262_hippo_automute(struct hda_codec *codec)
10252{
10253 struct alc_spec *spec = codec->spec;
10254 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10255
10256 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
10257 alc262_hippo_master_update(codec);
10258}
10259
10260static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10261{
10262 if ((res >> 26) != ALC880_HP_EVENT)
10263 return;
10264 alc262_hippo_automute(codec);
10265}
10266
10267static void alc262_hippo_setup(struct hda_codec *codec)
10268{
10269 struct alc_spec *spec = codec->spec;
10270
10271 spec->autocfg.hp_pins[0] = 0x15;
10272 spec->autocfg.speaker_pins[0] = 0x14;
10273}
10274
10275static void alc262_hippo1_setup(struct hda_codec *codec)
10276{
10277 struct alc_spec *spec = codec->spec;
10278
10279 spec->autocfg.hp_pins[0] = 0x1b;
10280 spec->autocfg.speaker_pins[0] = 0x14;
10281}
10282
10283
10284static struct snd_kcontrol_new alc262_sony_mixer[] = {
10285 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10286 ALC262_HIPPO_MASTER_SWITCH,
10287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10288 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10289 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10290 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10291 { } /* end */
10292};
10293
10294static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
10295 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10296 ALC262_HIPPO_MASTER_SWITCH,
10297 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10299 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10300 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10301 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10302 { } /* end */
10303};
10304
10305static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10306 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10307 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10308 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10309 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10310 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10311 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10313 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10314 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10315 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10316 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10317 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10318 { } /* end */
10319};
10320
10321static struct hda_verb alc262_tyan_verbs[] = {
10322 /* Headphone automute */
10323 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10324 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10325 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10326
10327 /* P11 AUX_IN, white 4-pin connector */
10328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10329 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10330 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10331 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10332
10333 {}
10334};
10335
10336/* unsolicited event for HP jack sensing */
10337static void alc262_tyan_setup(struct hda_codec *codec)
10338{
10339 struct alc_spec *spec = codec->spec;
10340
10341 spec->autocfg.hp_pins[0] = 0x1b;
10342 spec->autocfg.speaker_pins[0] = 0x15;
10343}
10344
10345
10346#define alc262_capture_mixer alc882_capture_mixer
10347#define alc262_capture_alt_mixer alc882_capture_alt_mixer
10348
10349/*
10350 * generic initialization of ADC, input mixers and output mixers
10351 */
10352static struct hda_verb alc262_init_verbs[] = {
10353 /*
10354 * Unmute ADC0-2 and set the default input to mic-in
10355 */
10356 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10358 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10359 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10360 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10361 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10362
10363 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10364 * mixer widget
10365 * Note: PASD motherboards uses the Line In 2 as the input for
10366 * front panel mic (mic 2)
10367 */
10368 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10372 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10373 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10374
10375 /*
10376 * Set up output mixers (0x0c - 0x0e)
10377 */
10378 /* set vol=0 to output mixers */
10379 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10380 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10381 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10382 /* set up input amps for analog loopback */
10383 /* Amp Indices: DAC = 0, mixer = 1 */
10384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10387 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10389 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10390
10391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10392 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10393 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10394 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10395 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10396 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10397
10398 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10400 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10401 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10402 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10403
10404 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10405 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10406
10407 /* FIXME: use matrix-type input source selection */
10408 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10409 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10410 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10411 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10412 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10413 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10414 /* Input mixer2 */
10415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10419 /* Input mixer3 */
10420 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10424
10425 { }
10426};
10427
10428static struct hda_verb alc262_eapd_verbs[] = {
10429 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10430 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10431 { }
10432};
10433
10434static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10435 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10436 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10437 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10438
10439 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10440 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10441 {}
10442};
10443
10444static struct hda_verb alc262_sony_unsol_verbs[] = {
10445 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10446 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10447 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10448
10449 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10451 {}
10452};
10453
10454static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10455 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10456 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10460 { } /* end */
10461};
10462
10463static struct hda_verb alc262_toshiba_s06_verbs[] = {
10464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10466 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10468 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10469 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10470 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10471 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10472 {}
10473};
10474
10475static void alc262_toshiba_s06_setup(struct hda_codec *codec)
10476{
10477 struct alc_spec *spec = codec->spec;
10478
10479 spec->autocfg.hp_pins[0] = 0x15;
10480 spec->autocfg.speaker_pins[0] = 0x14;
10481 spec->ext_mic.pin = 0x18;
10482 spec->ext_mic.mux_idx = 0;
10483 spec->int_mic.pin = 0x12;
10484 spec->int_mic.mux_idx = 9;
10485 spec->auto_mic = 1;
10486}
10487
10488/*
10489 * nec model
10490 * 0x15 = headphone
10491 * 0x16 = internal speaker
10492 * 0x18 = external mic
10493 */
10494
10495static struct snd_kcontrol_new alc262_nec_mixer[] = {
10496 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10497 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10498
10499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10501 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10502
10503 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10504 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10505 { } /* end */
10506};
10507
10508static struct hda_verb alc262_nec_verbs[] = {
10509 /* Unmute Speaker */
10510 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10511
10512 /* Headphone */
10513 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10515
10516 /* External mic to headphone */
10517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10518 /* External mic to speaker */
10519 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10520 {}
10521};
10522
10523/*
10524 * fujitsu model
10525 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10526 * 0x1b = port replicator headphone out
10527 */
10528
10529#define ALC_HP_EVENT 0x37
10530
10531static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10532 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10534 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10535 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10536 {}
10537};
10538
10539static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10540 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10541 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10542 {}
10543};
10544
10545static struct hda_input_mux alc262_fujitsu_capture_source = {
10546 .num_items = 3,
10547 .items = {
10548 { "Mic", 0x0 },
10549 { "Int Mic", 0x1 },
10550 { "CD", 0x4 },
10551 },
10552};
10553
10554static struct hda_input_mux alc262_HP_capture_source = {
10555 .num_items = 5,
10556 .items = {
10557 { "Mic", 0x0 },
10558 { "Front Mic", 0x1 },
10559 { "Line", 0x2 },
10560 { "CD", 0x4 },
10561 { "AUX IN", 0x6 },
10562 },
10563};
10564
10565static struct hda_input_mux alc262_HP_D7000_capture_source = {
10566 .num_items = 4,
10567 .items = {
10568 { "Mic", 0x0 },
10569 { "Front Mic", 0x2 },
10570 { "Line", 0x1 },
10571 { "CD", 0x4 },
10572 },
10573};
10574
10575/* mute/unmute internal speaker according to the hp jacks and mute state */
10576static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10577{
10578 struct alc_spec *spec = codec->spec;
10579 unsigned int mute;
10580
10581 if (force || !spec->sense_updated) {
10582 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
10583 snd_hda_jack_detect(codec, 0x1b);
10584 spec->sense_updated = 1;
10585 }
10586 /* unmute internal speaker only if both HPs are unplugged and
10587 * master switch is on
10588 */
10589 if (spec->jack_present)
10590 mute = HDA_AMP_MUTE;
10591 else
10592 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10593 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10594 HDA_AMP_MUTE, mute);
10595}
10596
10597/* unsolicited event for HP jack sensing */
10598static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10599 unsigned int res)
10600{
10601 if ((res >> 26) != ALC_HP_EVENT)
10602 return;
10603 alc262_fujitsu_automute(codec, 1);
10604}
10605
10606static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10607{
10608 alc262_fujitsu_automute(codec, 1);
10609}
10610
10611/* bind volumes of both NID 0x0c and 0x0d */
10612static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10613 .ops = &snd_hda_bind_vol,
10614 .values = {
10615 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10616 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10617 0
10618 },
10619};
10620
10621/* mute/unmute internal speaker according to the hp jack and mute state */
10622static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10623{
10624 struct alc_spec *spec = codec->spec;
10625 unsigned int mute;
10626
10627 if (force || !spec->sense_updated) {
10628 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10629 spec->sense_updated = 1;
10630 }
10631 if (spec->jack_present) {
10632 /* mute internal speaker */
10633 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10634 HDA_AMP_MUTE, HDA_AMP_MUTE);
10635 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10636 HDA_AMP_MUTE, HDA_AMP_MUTE);
10637 } else {
10638 /* unmute internal speaker if necessary */
10639 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10640 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10641 HDA_AMP_MUTE, mute);
10642 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10643 HDA_AMP_MUTE, mute);
10644 }
10645}
10646
10647/* unsolicited event for HP jack sensing */
10648static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10649 unsigned int res)
10650{
10651 if ((res >> 26) != ALC_HP_EVENT)
10652 return;
10653 alc262_lenovo_3000_automute(codec, 1);
10654}
10655
10656static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
10657 int dir, int idx, long *valp)
10658{
10659 int i, change = 0;
10660
10661 for (i = 0; i < 2; i++, valp++)
10662 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
10663 HDA_AMP_MUTE,
10664 *valp ? 0 : HDA_AMP_MUTE);
10665 return change;
10666}
10667
10668/* bind hp and internal speaker mute (with plug check) */
10669static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10670 struct snd_ctl_elem_value *ucontrol)
10671{
10672 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10673 long *valp = ucontrol->value.integer.value;
10674 int change;
10675
10676 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
10677 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10678 if (change)
10679 alc262_fujitsu_automute(codec, 0);
10680 return change;
10681}
10682
10683static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10684 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10685 {
10686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10687 .name = "Master Playback Switch",
10688 .info = snd_hda_mixer_amp_switch_info,
10689 .get = snd_hda_mixer_amp_switch_get,
10690 .put = alc262_fujitsu_master_sw_put,
10691 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10692 },
10693 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10694 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10695 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10696 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10697 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10698 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10699 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10700 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10701 { } /* end */
10702};
10703
10704/* bind hp and internal speaker mute (with plug check) */
10705static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10706 struct snd_ctl_elem_value *ucontrol)
10707{
10708 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10709 long *valp = ucontrol->value.integer.value;
10710 int change;
10711
10712 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10713 if (change)
10714 alc262_lenovo_3000_automute(codec, 0);
10715 return change;
10716}
10717
10718static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10719 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10720 {
10721 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10722 .name = "Master Playback Switch",
10723 .info = snd_hda_mixer_amp_switch_info,
10724 .get = snd_hda_mixer_amp_switch_get,
10725 .put = alc262_lenovo_3000_master_sw_put,
10726 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10727 },
10728 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10729 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10730 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10731 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10733 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10734 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10735 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10736 { } /* end */
10737};
10738
10739static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10740 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10741 ALC262_HIPPO_MASTER_SWITCH,
10742 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10743 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10744 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10745 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10746 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10747 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10748 { } /* end */
10749};
10750
10751/* additional init verbs for Benq laptops */
10752static struct hda_verb alc262_EAPD_verbs[] = {
10753 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10754 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10755 {}
10756};
10757
10758static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10759 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10760 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10761
10762 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10763 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10764 {}
10765};
10766
10767/* Samsung Q1 Ultra Vista model setup */
10768static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10769 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10770 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10771 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10772 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10773 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10774 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10775 { } /* end */
10776};
10777
10778static struct hda_verb alc262_ultra_verbs[] = {
10779 /* output mixer */
10780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10783 /* speaker */
10784 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10787 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10788 /* HP */
10789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10790 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10791 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10792 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10793 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10794 /* internal mic */
10795 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10797 /* ADC, choose mic */
10798 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10799 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10800 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10801 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10802 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10803 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10804 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10808 {}
10809};
10810
10811/* mute/unmute internal speaker according to the hp jack and mute state */
10812static void alc262_ultra_automute(struct hda_codec *codec)
10813{
10814 struct alc_spec *spec = codec->spec;
10815 unsigned int mute;
10816
10817 mute = 0;
10818 /* auto-mute only when HP is used as HP */
10819 if (!spec->cur_mux[0]) {
10820 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10821 if (spec->jack_present)
10822 mute = HDA_AMP_MUTE;
10823 }
10824 /* mute/unmute internal speaker */
10825 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10826 HDA_AMP_MUTE, mute);
10827 /* mute/unmute HP */
10828 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10829 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10830}
10831
10832/* unsolicited event for HP jack sensing */
10833static void alc262_ultra_unsol_event(struct hda_codec *codec,
10834 unsigned int res)
10835{
10836 if ((res >> 26) != ALC880_HP_EVENT)
10837 return;
10838 alc262_ultra_automute(codec);
10839}
10840
10841static struct hda_input_mux alc262_ultra_capture_source = {
10842 .num_items = 2,
10843 .items = {
10844 { "Mic", 0x1 },
10845 { "Headphone", 0x7 },
10846 },
10847};
10848
10849static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10850 struct snd_ctl_elem_value *ucontrol)
10851{
10852 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10853 struct alc_spec *spec = codec->spec;
10854 int ret;
10855
10856 ret = alc_mux_enum_put(kcontrol, ucontrol);
10857 if (!ret)
10858 return 0;
10859 /* reprogram the HP pin as mic or HP according to the input source */
10860 snd_hda_codec_write_cache(codec, 0x15, 0,
10861 AC_VERB_SET_PIN_WIDGET_CONTROL,
10862 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10863 alc262_ultra_automute(codec); /* mute/unmute HP */
10864 return ret;
10865}
10866
10867static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10868 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10869 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10870 {
10871 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10872 .name = "Capture Source",
10873 .info = alc_mux_enum_info,
10874 .get = alc_mux_enum_get,
10875 .put = alc262_ultra_mux_enum_put,
10876 },
10877 { } /* end */
10878};
10879
10880/* We use two mixers depending on the output pin; 0x16 is a mono output
10881 * and thus it's bound with a different mixer.
10882 * This function returns which mixer amp should be used.
10883 */
10884static int alc262_check_volbit(hda_nid_t nid)
10885{
10886 if (!nid)
10887 return 0;
10888 else if (nid == 0x16)
10889 return 2;
10890 else
10891 return 1;
10892}
10893
10894static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
10895 const char *pfx, int *vbits)
10896{
10897 unsigned long val;
10898 int vbit;
10899
10900 vbit = alc262_check_volbit(nid);
10901 if (!vbit)
10902 return 0;
10903 if (*vbits & vbit) /* a volume control for this mixer already there */
10904 return 0;
10905 *vbits |= vbit;
10906 if (vbit == 2)
10907 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
10908 else
10909 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
10910 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
10911}
10912
10913static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
10914 const char *pfx)
10915{
10916 unsigned long val;
10917
10918 if (!nid)
10919 return 0;
10920 if (nid == 0x16)
10921 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
10922 else
10923 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
10924 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
10925}
10926
10927/* add playback controls from the parsed DAC table */
10928static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10929 const struct auto_pin_cfg *cfg)
10930{
10931 const char *pfx;
10932 int vbits;
10933 int err;
10934
10935 spec->multiout.num_dacs = 1; /* only use one dac */
10936 spec->multiout.dac_nids = spec->private_dac_nids;
10937 spec->multiout.dac_nids[0] = 2;
10938
10939 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
10940 pfx = "Master";
10941 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
10942 pfx = "Speaker";
10943 else
10944 pfx = "Front";
10945 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
10946 if (err < 0)
10947 return err;
10948 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
10949 if (err < 0)
10950 return err;
10951 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
10952 if (err < 0)
10953 return err;
10954
10955 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
10956 alc262_check_volbit(cfg->speaker_pins[0]) |
10957 alc262_check_volbit(cfg->hp_pins[0]);
10958 if (vbits == 1 || vbits == 2)
10959 pfx = "Master"; /* only one mixer is used */
10960 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
10961 pfx = "Speaker";
10962 else
10963 pfx = "Front";
10964 vbits = 0;
10965 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
10966 if (err < 0)
10967 return err;
10968 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
10969 &vbits);
10970 if (err < 0)
10971 return err;
10972 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
10973 &vbits);
10974 if (err < 0)
10975 return err;
10976 return 0;
10977}
10978
10979#define alc262_auto_create_input_ctls \
10980 alc880_auto_create_input_ctls
10981
10982/*
10983 * generic initialization of ADC, input mixers and output mixers
10984 */
10985static struct hda_verb alc262_volume_init_verbs[] = {
10986 /*
10987 * Unmute ADC0-2 and set the default input to mic-in
10988 */
10989 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10990 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10991 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10992 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10993 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10994 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10995
10996 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10997 * mixer widget
10998 * Note: PASD motherboards uses the Line In 2 as the input for
10999 * front panel mic (mic 2)
11000 */
11001 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11002 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11003 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11004 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11005 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11006 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11007
11008 /*
11009 * Set up output mixers (0x0c - 0x0f)
11010 */
11011 /* set vol=0 to output mixers */
11012 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11013 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11014 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11015
11016 /* set up input amps for analog loopback */
11017 /* Amp Indices: DAC = 0, mixer = 1 */
11018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11019 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11020 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11021 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11023 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11024
11025 /* FIXME: use matrix-type input source selection */
11026 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11027 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11030 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11031 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11032 /* Input mixer2 */
11033 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11034 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11035 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11036 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11037 /* Input mixer3 */
11038 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11039 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11040 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11041 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11042
11043 { }
11044};
11045
11046static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11047 /*
11048 * Unmute ADC0-2 and set the default input to mic-in
11049 */
11050 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11052 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11053 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11054 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11055 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11056
11057 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11058 * mixer widget
11059 * Note: PASD motherboards uses the Line In 2 as the input for
11060 * front panel mic (mic 2)
11061 */
11062 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11070
11071 /*
11072 * Set up output mixers (0x0c - 0x0e)
11073 */
11074 /* set vol=0 to output mixers */
11075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11076 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11077 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11078
11079 /* set up input amps for analog loopback */
11080 /* Amp Indices: DAC = 0, mixer = 1 */
11081 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11082 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11083 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11084 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11085 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11086 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11087
11088 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11089 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11090 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11091
11092 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11093 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11094
11095 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11096 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11097
11098 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11099 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11100 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11101 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11102 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11103
11104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11105 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11106 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11107 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11108 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11109 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11110
11111
11112 /* FIXME: use matrix-type input source selection */
11113 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11114 /* Input mixer1: only unmute Mic */
11115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11117 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11118 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11119 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11124 /* Input mixer2 */
11125 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11128 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11129 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11130 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11131 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11132 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11133 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11134 /* Input mixer3 */
11135 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11136 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11137 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11138 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11139 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11144
11145 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11146
11147 { }
11148};
11149
11150static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11151 /*
11152 * Unmute ADC0-2 and set the default input to mic-in
11153 */
11154 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11156 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11157 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11158 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11160
11161 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11162 * mixer widget
11163 * Note: PASD motherboards uses the Line In 2 as the input for front
11164 * panel mic (mic 2)
11165 */
11166 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11168 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11170 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11171 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11172 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11174 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11175 /*
11176 * Set up output mixers (0x0c - 0x0e)
11177 */
11178 /* set vol=0 to output mixers */
11179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11180 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11182
11183 /* set up input amps for analog loopback */
11184 /* Amp Indices: DAC = 0, mixer = 1 */
11185 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11187 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11188 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11189 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11190 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11191
11192
11193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11194 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11195 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11196 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11197 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11198 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11199 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11200
11201 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11202 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11203
11204 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11205 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11206
11207 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11208 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11209 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11210 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11211 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11212 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11213
11214 /* FIXME: use matrix-type input source selection */
11215 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11216 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11218 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11219 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11220 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11222 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11223 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11224 /* Input mixer2 */
11225 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11226 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11227 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11228 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11229 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11230 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11231 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11232 /* Input mixer3 */
11233 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11234 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11235 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11236 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11237 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11238 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11240
11241 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11242
11243 { }
11244};
11245
11246static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11247
11248 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11250 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11251
11252 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11253 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11254 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11255 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11256
11257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11258 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11259 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11260 {}
11261};
11262
11263
11264#ifdef CONFIG_SND_HDA_POWER_SAVE
11265#define alc262_loopbacks alc880_loopbacks
11266#endif
11267
11268/* pcm configuration: identical with ALC880 */
11269#define alc262_pcm_analog_playback alc880_pcm_analog_playback
11270#define alc262_pcm_analog_capture alc880_pcm_analog_capture
11271#define alc262_pcm_digital_playback alc880_pcm_digital_playback
11272#define alc262_pcm_digital_capture alc880_pcm_digital_capture
11273
11274/*
11275 * BIOS auto configuration
11276 */
11277static int alc262_parse_auto_config(struct hda_codec *codec)
11278{
11279 struct alc_spec *spec = codec->spec;
11280 int err;
11281 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11282
11283 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11284 alc262_ignore);
11285 if (err < 0)
11286 return err;
11287 if (!spec->autocfg.line_outs) {
11288 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11289 spec->multiout.max_channels = 2;
11290 spec->no_analog = 1;
11291 goto dig_only;
11292 }
11293 return 0; /* can't find valid BIOS pin config */
11294 }
11295 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11296 if (err < 0)
11297 return err;
11298 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
11299 if (err < 0)
11300 return err;
11301
11302 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11303
11304 dig_only:
11305 if (spec->autocfg.dig_outs) {
11306 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
11307 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11308 }
11309 if (spec->autocfg.dig_in_pin)
11310 spec->dig_in_nid = ALC262_DIGIN_NID;
11311
11312 if (spec->kctls.list)
11313 add_mixer(spec, spec->kctls.list);
11314
11315 add_verb(spec, alc262_volume_init_verbs);
11316 spec->num_mux_defs = 1;
11317 spec->input_mux = &spec->private_imux[0];
11318
11319 err = alc_auto_add_mic_boost(codec);
11320 if (err < 0)
11321 return err;
11322
11323 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11324
11325 return 1;
11326}
11327
11328#define alc262_auto_init_multi_out alc882_auto_init_multi_out
11329#define alc262_auto_init_hp_out alc882_auto_init_hp_out
11330#define alc262_auto_init_analog_input alc882_auto_init_analog_input
11331#define alc262_auto_init_input_src alc882_auto_init_input_src
11332
11333
11334/* init callback for auto-configuration model -- overriding the default init */
11335static void alc262_auto_init(struct hda_codec *codec)
11336{
11337 struct alc_spec *spec = codec->spec;
11338 alc262_auto_init_multi_out(codec);
11339 alc262_auto_init_hp_out(codec);
11340 alc262_auto_init_analog_input(codec);
11341 alc262_auto_init_input_src(codec);
11342 if (spec->unsol_event)
11343 alc_inithook(codec);
11344}
11345
11346/*
11347 * configuration and preset
11348 */
11349static const char *alc262_models[ALC262_MODEL_LAST] = {
11350 [ALC262_BASIC] = "basic",
11351 [ALC262_HIPPO] = "hippo",
11352 [ALC262_HIPPO_1] = "hippo_1",
11353 [ALC262_FUJITSU] = "fujitsu",
11354 [ALC262_HP_BPC] = "hp-bpc",
11355 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
11356 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
11357 [ALC262_HP_RP5700] = "hp-rp5700",
11358 [ALC262_BENQ_ED8] = "benq",
11359 [ALC262_BENQ_T31] = "benq-t31",
11360 [ALC262_SONY_ASSAMD] = "sony-assamd",
11361 [ALC262_TOSHIBA_S06] = "toshiba-s06",
11362 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
11363 [ALC262_ULTRA] = "ultra",
11364 [ALC262_LENOVO_3000] = "lenovo-3000",
11365 [ALC262_NEC] = "nec",
11366 [ALC262_TYAN] = "tyan",
11367 [ALC262_AUTO] = "auto",
11368};
11369
11370static struct snd_pci_quirk alc262_cfg_tbl[] = {
11371 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
11372 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
11373 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11374 ALC262_HP_BPC),
11375 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11376 ALC262_HP_BPC),
11377 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11378 ALC262_HP_BPC),
11379 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
11380 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
11381 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
11382 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
11383 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
11384 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
11385 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
11386 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
11387 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11388 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11389 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
11390 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11391 ALC262_HP_TC_T5735),
11392 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
11393 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11394 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
11395 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11396 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
11397 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
11398 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
11399 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
11400#if 0 /* disable the quirk since model=auto works better in recent versions */
11401 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11402 ALC262_SONY_ASSAMD),
11403#endif
11404 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
11405 ALC262_TOSHIBA_RX1),
11406 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
11407 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
11408 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
11409 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
11410 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11411 ALC262_ULTRA),
11412 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
11413 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
11414 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11415 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11416 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
11417 {}
11418};
11419
11420static struct alc_config_preset alc262_presets[] = {
11421 [ALC262_BASIC] = {
11422 .mixers = { alc262_base_mixer },
11423 .init_verbs = { alc262_init_verbs },
11424 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11425 .dac_nids = alc262_dac_nids,
11426 .hp_nid = 0x03,
11427 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11428 .channel_mode = alc262_modes,
11429 .input_mux = &alc262_capture_source,
11430 },
11431 [ALC262_HIPPO] = {
11432 .mixers = { alc262_hippo_mixer },
11433 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
11434 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11435 .dac_nids = alc262_dac_nids,
11436 .hp_nid = 0x03,
11437 .dig_out_nid = ALC262_DIGOUT_NID,
11438 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11439 .channel_mode = alc262_modes,
11440 .input_mux = &alc262_capture_source,
11441 .unsol_event = alc262_hippo_unsol_event,
11442 .setup = alc262_hippo_setup,
11443 .init_hook = alc262_hippo_automute,
11444 },
11445 [ALC262_HIPPO_1] = {
11446 .mixers = { alc262_hippo1_mixer },
11447 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11448 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11449 .dac_nids = alc262_dac_nids,
11450 .hp_nid = 0x02,
11451 .dig_out_nid = ALC262_DIGOUT_NID,
11452 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11453 .channel_mode = alc262_modes,
11454 .input_mux = &alc262_capture_source,
11455 .unsol_event = alc262_hippo_unsol_event,
11456 .setup = alc262_hippo1_setup,
11457 .init_hook = alc262_hippo_automute,
11458 },
11459 [ALC262_FUJITSU] = {
11460 .mixers = { alc262_fujitsu_mixer },
11461 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11462 alc262_fujitsu_unsol_verbs },
11463 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11464 .dac_nids = alc262_dac_nids,
11465 .hp_nid = 0x03,
11466 .dig_out_nid = ALC262_DIGOUT_NID,
11467 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11468 .channel_mode = alc262_modes,
11469 .input_mux = &alc262_fujitsu_capture_source,
11470 .unsol_event = alc262_fujitsu_unsol_event,
11471 .init_hook = alc262_fujitsu_init_hook,
11472 },
11473 [ALC262_HP_BPC] = {
11474 .mixers = { alc262_HP_BPC_mixer },
11475 .init_verbs = { alc262_HP_BPC_init_verbs },
11476 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11477 .dac_nids = alc262_dac_nids,
11478 .hp_nid = 0x03,
11479 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11480 .channel_mode = alc262_modes,
11481 .input_mux = &alc262_HP_capture_source,
11482 .unsol_event = alc262_hp_bpc_unsol_event,
11483 .init_hook = alc262_hp_bpc_automute,
11484 },
11485 [ALC262_HP_BPC_D7000_WF] = {
11486 .mixers = { alc262_HP_BPC_WildWest_mixer },
11487 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11488 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11489 .dac_nids = alc262_dac_nids,
11490 .hp_nid = 0x03,
11491 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11492 .channel_mode = alc262_modes,
11493 .input_mux = &alc262_HP_D7000_capture_source,
11494 .unsol_event = alc262_hp_wildwest_unsol_event,
11495 .init_hook = alc262_hp_wildwest_automute,
11496 },
11497 [ALC262_HP_BPC_D7000_WL] = {
11498 .mixers = { alc262_HP_BPC_WildWest_mixer,
11499 alc262_HP_BPC_WildWest_option_mixer },
11500 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11501 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11502 .dac_nids = alc262_dac_nids,
11503 .hp_nid = 0x03,
11504 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11505 .channel_mode = alc262_modes,
11506 .input_mux = &alc262_HP_D7000_capture_source,
11507 .unsol_event = alc262_hp_wildwest_unsol_event,
11508 .init_hook = alc262_hp_wildwest_automute,
11509 },
11510 [ALC262_HP_TC_T5735] = {
11511 .mixers = { alc262_hp_t5735_mixer },
11512 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11513 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11514 .dac_nids = alc262_dac_nids,
11515 .hp_nid = 0x03,
11516 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11517 .channel_mode = alc262_modes,
11518 .input_mux = &alc262_capture_source,
11519 .unsol_event = alc_automute_amp_unsol_event,
11520 .setup = alc262_hp_t5735_setup,
11521 .init_hook = alc_automute_amp,
11522 },
11523 [ALC262_HP_RP5700] = {
11524 .mixers = { alc262_hp_rp5700_mixer },
11525 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11526 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11527 .dac_nids = alc262_dac_nids,
11528 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11529 .channel_mode = alc262_modes,
11530 .input_mux = &alc262_hp_rp5700_capture_source,
11531 },
11532 [ALC262_BENQ_ED8] = {
11533 .mixers = { alc262_base_mixer },
11534 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11535 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11536 .dac_nids = alc262_dac_nids,
11537 .hp_nid = 0x03,
11538 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11539 .channel_mode = alc262_modes,
11540 .input_mux = &alc262_capture_source,
11541 },
11542 [ALC262_SONY_ASSAMD] = {
11543 .mixers = { alc262_sony_mixer },
11544 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11545 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11546 .dac_nids = alc262_dac_nids,
11547 .hp_nid = 0x02,
11548 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11549 .channel_mode = alc262_modes,
11550 .input_mux = &alc262_capture_source,
11551 .unsol_event = alc262_hippo_unsol_event,
11552 .setup = alc262_hippo_setup,
11553 .init_hook = alc262_hippo_automute,
11554 },
11555 [ALC262_BENQ_T31] = {
11556 .mixers = { alc262_benq_t31_mixer },
11557 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
11558 alc_hp15_unsol_verbs },
11559 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11560 .dac_nids = alc262_dac_nids,
11561 .hp_nid = 0x03,
11562 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11563 .channel_mode = alc262_modes,
11564 .input_mux = &alc262_capture_source,
11565 .unsol_event = alc262_hippo_unsol_event,
11566 .setup = alc262_hippo_setup,
11567 .init_hook = alc262_hippo_automute,
11568 },
11569 [ALC262_ULTRA] = {
11570 .mixers = { alc262_ultra_mixer },
11571 .cap_mixer = alc262_ultra_capture_mixer,
11572 .init_verbs = { alc262_ultra_verbs },
11573 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11574 .dac_nids = alc262_dac_nids,
11575 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11576 .channel_mode = alc262_modes,
11577 .input_mux = &alc262_ultra_capture_source,
11578 .adc_nids = alc262_adc_nids, /* ADC0 */
11579 .capsrc_nids = alc262_capsrc_nids,
11580 .num_adc_nids = 1, /* single ADC */
11581 .unsol_event = alc262_ultra_unsol_event,
11582 .init_hook = alc262_ultra_automute,
11583 },
11584 [ALC262_LENOVO_3000] = {
11585 .mixers = { alc262_lenovo_3000_mixer },
11586 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11587 alc262_lenovo_3000_unsol_verbs },
11588 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11589 .dac_nids = alc262_dac_nids,
11590 .hp_nid = 0x03,
11591 .dig_out_nid = ALC262_DIGOUT_NID,
11592 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11593 .channel_mode = alc262_modes,
11594 .input_mux = &alc262_fujitsu_capture_source,
11595 .unsol_event = alc262_lenovo_3000_unsol_event,
11596 },
11597 [ALC262_NEC] = {
11598 .mixers = { alc262_nec_mixer },
11599 .init_verbs = { alc262_nec_verbs },
11600 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11601 .dac_nids = alc262_dac_nids,
11602 .hp_nid = 0x03,
11603 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11604 .channel_mode = alc262_modes,
11605 .input_mux = &alc262_capture_source,
11606 },
11607 [ALC262_TOSHIBA_S06] = {
11608 .mixers = { alc262_toshiba_s06_mixer },
11609 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11610 alc262_eapd_verbs },
11611 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11612 .capsrc_nids = alc262_dmic_capsrc_nids,
11613 .dac_nids = alc262_dac_nids,
11614 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11615 .num_adc_nids = 1, /* single ADC */
11616 .dig_out_nid = ALC262_DIGOUT_NID,
11617 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11618 .channel_mode = alc262_modes,
11619 .unsol_event = alc_sku_unsol_event,
11620 .setup = alc262_toshiba_s06_setup,
11621 .init_hook = alc_inithook,
11622 },
11623 [ALC262_TOSHIBA_RX1] = {
11624 .mixers = { alc262_toshiba_rx1_mixer },
11625 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11626 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11627 .dac_nids = alc262_dac_nids,
11628 .hp_nid = 0x03,
11629 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11630 .channel_mode = alc262_modes,
11631 .input_mux = &alc262_capture_source,
11632 .unsol_event = alc262_hippo_unsol_event,
11633 .setup = alc262_hippo_setup,
11634 .init_hook = alc262_hippo_automute,
11635 },
11636 [ALC262_TYAN] = {
11637 .mixers = { alc262_tyan_mixer },
11638 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11639 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11640 .dac_nids = alc262_dac_nids,
11641 .hp_nid = 0x02,
11642 .dig_out_nid = ALC262_DIGOUT_NID,
11643 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11644 .channel_mode = alc262_modes,
11645 .input_mux = &alc262_capture_source,
11646 .unsol_event = alc_automute_amp_unsol_event,
11647 .setup = alc262_tyan_setup,
11648 .init_hook = alc_automute_amp,
11649 },
11650};
11651
11652static int patch_alc262(struct hda_codec *codec)
11653{
11654 struct alc_spec *spec;
11655 int board_config;
11656 int err;
11657
11658 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11659 if (spec == NULL)
11660 return -ENOMEM;
11661
11662 codec->spec = spec;
11663#if 0
11664 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11665 * under-run
11666 */
11667 {
11668 int tmp;
11669 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11670 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11671 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11672 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11673 }
11674#endif
11675
11676 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11677
11678 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11679 alc262_models,
11680 alc262_cfg_tbl);
11681
11682 if (board_config < 0) {
11683 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11684 codec->chip_name);
11685 board_config = ALC262_AUTO;
11686 }
11687
11688 if (board_config == ALC262_AUTO) {
11689 /* automatic parse from the BIOS config */
11690 err = alc262_parse_auto_config(codec);
11691 if (err < 0) {
11692 alc_free(codec);
11693 return err;
11694 } else if (!err) {
11695 printk(KERN_INFO
11696 "hda_codec: Cannot set up configuration "
11697 "from BIOS. Using base mode...\n");
11698 board_config = ALC262_BASIC;
11699 }
11700 }
11701
11702 if (!spec->no_analog) {
11703 err = snd_hda_attach_beep_device(codec, 0x1);
11704 if (err < 0) {
11705 alc_free(codec);
11706 return err;
11707 }
11708 }
11709
11710 if (board_config != ALC262_AUTO)
11711 setup_preset(codec, &alc262_presets[board_config]);
11712
11713 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11714 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11715
11716 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11717 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11718
11719 if (!spec->adc_nids && spec->input_mux) {
11720 int i;
11721 /* check whether the digital-mic has to be supported */
11722 for (i = 0; i < spec->input_mux->num_items; i++) {
11723 if (spec->input_mux->items[i].index >= 9)
11724 break;
11725 }
11726 if (i < spec->input_mux->num_items) {
11727 /* use only ADC0 */
11728 spec->adc_nids = alc262_dmic_adc_nids;
11729 spec->num_adc_nids = 1;
11730 spec->capsrc_nids = alc262_dmic_capsrc_nids;
11731 } else {
11732 /* all analog inputs */
11733 /* check whether NID 0x07 is valid */
11734 unsigned int wcap = get_wcaps(codec, 0x07);
11735
11736 /* get type */
11737 wcap = get_wcaps_type(wcap);
11738 if (wcap != AC_WID_AUD_IN) {
11739 spec->adc_nids = alc262_adc_nids_alt;
11740 spec->num_adc_nids =
11741 ARRAY_SIZE(alc262_adc_nids_alt);
11742 spec->capsrc_nids = alc262_capsrc_nids_alt;
11743 } else {
11744 spec->adc_nids = alc262_adc_nids;
11745 spec->num_adc_nids =
11746 ARRAY_SIZE(alc262_adc_nids);
11747 spec->capsrc_nids = alc262_capsrc_nids;
11748 }
11749 }
11750 }
11751 if (!spec->cap_mixer && !spec->no_analog)
11752 set_capture_mixer(codec);
11753 if (!spec->no_analog)
11754 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11755
11756 spec->vmaster_nid = 0x0c;
11757
11758 codec->patch_ops = alc_patch_ops;
11759 if (board_config == ALC262_AUTO)
11760 spec->init_hook = alc262_auto_init;
11761#ifdef CONFIG_SND_HDA_POWER_SAVE
11762 if (!spec->loopback.amplist)
11763 spec->loopback.amplist = alc262_loopbacks;
11764#endif
11765 codec->proc_widget_hook = print_realtek_coef;
11766
11767 return 0;
11768}
11769
11770/*
11771 * ALC268 channel source setting (2 channel)
11772 */
11773#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11774#define alc268_modes alc260_modes
11775
11776static hda_nid_t alc268_dac_nids[2] = {
11777 /* front, hp */
11778 0x02, 0x03
11779};
11780
11781static hda_nid_t alc268_adc_nids[2] = {
11782 /* ADC0-1 */
11783 0x08, 0x07
11784};
11785
11786static hda_nid_t alc268_adc_nids_alt[1] = {
11787 /* ADC0 */
11788 0x08
11789};
11790
11791static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11792
11793static struct snd_kcontrol_new alc268_base_mixer[] = {
11794 /* output mixer control */
11795 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11796 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11797 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11798 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11799 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11800 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11801 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11802 { }
11803};
11804
11805static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11806 /* output mixer control */
11807 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11808 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11809 ALC262_HIPPO_MASTER_SWITCH,
11810 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11811 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11812 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11813 { }
11814};
11815
11816/* bind Beep switches of both NID 0x0f and 0x10 */
11817static struct hda_bind_ctls alc268_bind_beep_sw = {
11818 .ops = &snd_hda_bind_sw,
11819 .values = {
11820 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11821 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11822 0
11823 },
11824};
11825
11826static struct snd_kcontrol_new alc268_beep_mixer[] = {
11827 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11828 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11829 { }
11830};
11831
11832static struct hda_verb alc268_eapd_verbs[] = {
11833 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11834 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11835 { }
11836};
11837
11838/* Toshiba specific */
11839static struct hda_verb alc268_toshiba_verbs[] = {
11840 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11841 { } /* end */
11842};
11843
11844/* Acer specific */
11845/* bind volumes of both NID 0x02 and 0x03 */
11846static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11847 .ops = &snd_hda_bind_vol,
11848 .values = {
11849 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11850 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11851 0
11852 },
11853};
11854
11855/* mute/unmute internal speaker according to the hp jack and mute state */
11856static void alc268_acer_automute(struct hda_codec *codec, int force)
11857{
11858 struct alc_spec *spec = codec->spec;
11859 unsigned int mute;
11860
11861 if (force || !spec->sense_updated) {
11862 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
11863 spec->sense_updated = 1;
11864 }
11865 if (spec->jack_present)
11866 mute = HDA_AMP_MUTE; /* mute internal speaker */
11867 else /* unmute internal speaker if necessary */
11868 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11869 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11870 HDA_AMP_MUTE, mute);
11871}
11872
11873
11874/* bind hp and internal speaker mute (with plug check) */
11875static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11876 struct snd_ctl_elem_value *ucontrol)
11877{
11878 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11879 long *valp = ucontrol->value.integer.value;
11880 int change;
11881
11882 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11883 if (change)
11884 alc268_acer_automute(codec, 0);
11885 return change;
11886}
11887
11888static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11889 /* output mixer control */
11890 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11891 {
11892 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11893 .name = "Master Playback Switch",
11894 .info = snd_hda_mixer_amp_switch_info,
11895 .get = snd_hda_mixer_amp_switch_get,
11896 .put = alc268_acer_master_sw_put,
11897 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11898 },
11899 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11900 { }
11901};
11902
11903static struct snd_kcontrol_new alc268_acer_mixer[] = {
11904 /* output mixer control */
11905 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11906 {
11907 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11908 .name = "Master Playback Switch",
11909 .info = snd_hda_mixer_amp_switch_info,
11910 .get = snd_hda_mixer_amp_switch_get,
11911 .put = alc268_acer_master_sw_put,
11912 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11913 },
11914 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11915 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11916 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11917 { }
11918};
11919
11920static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11921 /* output mixer control */
11922 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11923 {
11924 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11925 .name = "Master Playback Switch",
11926 .info = snd_hda_mixer_amp_switch_info,
11927 .get = snd_hda_mixer_amp_switch_get,
11928 .put = alc268_acer_master_sw_put,
11929 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11930 },
11931 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11932 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11933 { }
11934};
11935
11936static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11937 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11938 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11939 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11940 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11941 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11942 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11943 { }
11944};
11945
11946static struct hda_verb alc268_acer_verbs[] = {
11947 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11948 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11949 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11950 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11952 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11953 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11954 { }
11955};
11956
11957/* unsolicited event for HP jack sensing */
11958#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11959#define alc268_toshiba_setup alc262_hippo_setup
11960#define alc268_toshiba_automute alc262_hippo_automute
11961
11962static void alc268_acer_unsol_event(struct hda_codec *codec,
11963 unsigned int res)
11964{
11965 if ((res >> 26) != ALC880_HP_EVENT)
11966 return;
11967 alc268_acer_automute(codec, 1);
11968}
11969
11970static void alc268_acer_init_hook(struct hda_codec *codec)
11971{
11972 alc268_acer_automute(codec, 1);
11973}
11974
11975/* toggle speaker-output according to the hp-jack state */
11976static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11977{
11978 unsigned int present;
11979 unsigned char bits;
11980
11981 present = snd_hda_jack_detect(codec, 0x15);
11982 bits = present ? AMP_IN_MUTE(0) : 0;
11983 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11984 AMP_IN_MUTE(0), bits);
11985 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11986 AMP_IN_MUTE(0), bits);
11987}
11988
11989static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11990 unsigned int res)
11991{
11992 switch (res >> 26) {
11993 case ALC880_HP_EVENT:
11994 alc268_aspire_one_speaker_automute(codec);
11995 break;
11996 case ALC880_MIC_EVENT:
11997 alc_mic_automute(codec);
11998 break;
11999 }
12000}
12001
12002static void alc268_acer_lc_setup(struct hda_codec *codec)
12003{
12004 struct alc_spec *spec = codec->spec;
12005 spec->ext_mic.pin = 0x18;
12006 spec->ext_mic.mux_idx = 0;
12007 spec->int_mic.pin = 0x12;
12008 spec->int_mic.mux_idx = 6;
12009 spec->auto_mic = 1;
12010}
12011
12012static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12013{
12014 alc268_aspire_one_speaker_automute(codec);
12015 alc_mic_automute(codec);
12016}
12017
12018static struct snd_kcontrol_new alc268_dell_mixer[] = {
12019 /* output mixer control */
12020 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12021 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12022 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12023 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12024 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12025 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12026 { }
12027};
12028
12029static struct hda_verb alc268_dell_verbs[] = {
12030 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12031 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12032 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12033 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12034 { }
12035};
12036
12037/* mute/unmute internal speaker according to the hp jack and mute state */
12038static void alc268_dell_setup(struct hda_codec *codec)
12039{
12040 struct alc_spec *spec = codec->spec;
12041
12042 spec->autocfg.hp_pins[0] = 0x15;
12043 spec->autocfg.speaker_pins[0] = 0x14;
12044 spec->ext_mic.pin = 0x18;
12045 spec->ext_mic.mux_idx = 0;
12046 spec->int_mic.pin = 0x19;
12047 spec->int_mic.mux_idx = 1;
12048 spec->auto_mic = 1;
12049}
12050
12051static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12052 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12053 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12054 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12055 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12056 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12057 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12058 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12059 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12060 { }
12061};
12062
12063static struct hda_verb alc267_quanta_il1_verbs[] = {
12064 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12065 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12066 { }
12067};
12068
12069static void alc267_quanta_il1_setup(struct hda_codec *codec)
12070{
12071 struct alc_spec *spec = codec->spec;
12072 spec->autocfg.hp_pins[0] = 0x15;
12073 spec->autocfg.speaker_pins[0] = 0x14;
12074 spec->ext_mic.pin = 0x18;
12075 spec->ext_mic.mux_idx = 0;
12076 spec->int_mic.pin = 0x19;
12077 spec->int_mic.mux_idx = 1;
12078 spec->auto_mic = 1;
12079}
12080
12081/*
12082 * generic initialization of ADC, input mixers and output mixers
12083 */
12084static struct hda_verb alc268_base_init_verbs[] = {
12085 /* Unmute DAC0-1 and set vol = 0 */
12086 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12087 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12088
12089 /*
12090 * Set up output mixers (0x0c - 0x0e)
12091 */
12092 /* set vol=0 to output mixers */
12093 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12094 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12095
12096 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12097 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12098
12099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12101 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12102 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12103 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12104 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12105 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12106 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12107
12108 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12109 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12110 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12111 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12112 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12113
12114 /* set PCBEEP vol = 0, mute connections */
12115 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12116 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12117 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12118
12119 /* Unmute Selector 23h,24h and set the default input to mic-in */
12120
12121 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12123 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12125
12126 { }
12127};
12128
12129/*
12130 * generic initialization of ADC, input mixers and output mixers
12131 */
12132static struct hda_verb alc268_volume_init_verbs[] = {
12133 /* set output DAC */
12134 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12135 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12136
12137 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12138 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12139 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12140 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12141 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12142
12143 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12144 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12145 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12146
12147 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12148 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12149
12150 /* set PCBEEP vol = 0, mute connections */
12151 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12152 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12153 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12154
12155 { }
12156};
12157
12158static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12159 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12160 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12161 { } /* end */
12162};
12163
12164static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12165 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12166 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12167 _DEFINE_CAPSRC(1),
12168 { } /* end */
12169};
12170
12171static struct snd_kcontrol_new alc268_capture_mixer[] = {
12172 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12173 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12174 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12175 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12176 _DEFINE_CAPSRC(2),
12177 { } /* end */
12178};
12179
12180static struct hda_input_mux alc268_capture_source = {
12181 .num_items = 4,
12182 .items = {
12183 { "Mic", 0x0 },
12184 { "Front Mic", 0x1 },
12185 { "Line", 0x2 },
12186 { "CD", 0x3 },
12187 },
12188};
12189
12190static struct hda_input_mux alc268_acer_capture_source = {
12191 .num_items = 3,
12192 .items = {
12193 { "Mic", 0x0 },
12194 { "Internal Mic", 0x1 },
12195 { "Line", 0x2 },
12196 },
12197};
12198
12199static struct hda_input_mux alc268_acer_dmic_capture_source = {
12200 .num_items = 3,
12201 .items = {
12202 { "Mic", 0x0 },
12203 { "Internal Mic", 0x6 },
12204 { "Line", 0x2 },
12205 },
12206};
12207
12208#ifdef CONFIG_SND_DEBUG
12209static struct snd_kcontrol_new alc268_test_mixer[] = {
12210 /* Volume widgets */
12211 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12212 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12213 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12214 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12215 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12216 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12217 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12218 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12219 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12220 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12221 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12222 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12223 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
12224 /* The below appears problematic on some hardwares */
12225 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
12226 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12227 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12228 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12229 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12230
12231 /* Modes for retasking pin widgets */
12232 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12233 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12234 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12235 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12236
12237 /* Controls for GPIO pins, assuming they are configured as outputs */
12238 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12239 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12240 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12241 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12242
12243 /* Switches to allow the digital SPDIF output pin to be enabled.
12244 * The ALC268 does not have an SPDIF input.
12245 */
12246 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12247
12248 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12249 * this output to turn on an external amplifier.
12250 */
12251 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12252 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12253
12254 { } /* end */
12255};
12256#endif
12257
12258/* create input playback/capture controls for the given pin */
12259static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12260 const char *ctlname, int idx)
12261{
12262 hda_nid_t dac;
12263 int err;
12264
12265 switch (nid) {
12266 case 0x14:
12267 case 0x16:
12268 dac = 0x02;
12269 break;
12270 case 0x15:
12271 dac = 0x03;
12272 break;
12273 default:
12274 return 0;
12275 }
12276 if (spec->multiout.dac_nids[0] != dac &&
12277 spec->multiout.dac_nids[1] != dac) {
12278 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
12279 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12280 HDA_OUTPUT));
12281 if (err < 0)
12282 return err;
12283 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12284 }
12285
12286 if (nid != 0x16)
12287 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12288 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12289 else /* mono */
12290 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12291 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12292 if (err < 0)
12293 return err;
12294 return 0;
12295}
12296
12297/* add playback controls from the parsed DAC table */
12298static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12299 const struct auto_pin_cfg *cfg)
12300{
12301 hda_nid_t nid;
12302 int err;
12303
12304 spec->multiout.dac_nids = spec->private_dac_nids;
12305
12306 nid = cfg->line_out_pins[0];
12307 if (nid) {
12308 const char *name;
12309 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12310 name = "Speaker";
12311 else
12312 name = "Front";
12313 err = alc268_new_analog_output(spec, nid, name, 0);
12314 if (err < 0)
12315 return err;
12316 }
12317
12318 nid = cfg->speaker_pins[0];
12319 if (nid == 0x1d) {
12320 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
12321 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12322 if (err < 0)
12323 return err;
12324 } else {
12325 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12326 if (err < 0)
12327 return err;
12328 }
12329 nid = cfg->hp_pins[0];
12330 if (nid) {
12331 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12332 if (err < 0)
12333 return err;
12334 }
12335
12336 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12337 if (nid == 0x16) {
12338 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
12339 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12340 if (err < 0)
12341 return err;
12342 }
12343 return 0;
12344}
12345
12346/* create playback/capture controls for input pins */
12347static int alc268_auto_create_input_ctls(struct hda_codec *codec,
12348 const struct auto_pin_cfg *cfg)
12349{
12350 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
12351}
12352
12353static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12354 hda_nid_t nid, int pin_type)
12355{
12356 int idx;
12357
12358 alc_set_pin_output(codec, nid, pin_type);
12359 if (nid == 0x14 || nid == 0x16)
12360 idx = 0;
12361 else
12362 idx = 1;
12363 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
12364}
12365
12366static void alc268_auto_init_multi_out(struct hda_codec *codec)
12367{
12368 struct alc_spec *spec = codec->spec;
12369 hda_nid_t nid = spec->autocfg.line_out_pins[0];
12370 if (nid) {
12371 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12372 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
12373 }
12374}
12375
12376static void alc268_auto_init_hp_out(struct hda_codec *codec)
12377{
12378 struct alc_spec *spec = codec->spec;
12379 hda_nid_t pin;
12380
12381 pin = spec->autocfg.hp_pins[0];
12382 if (pin)
12383 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
12384 pin = spec->autocfg.speaker_pins[0];
12385 if (pin)
12386 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
12387}
12388
12389static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12390{
12391 struct alc_spec *spec = codec->spec;
12392 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12393 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12394 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12395 unsigned int dac_vol1, dac_vol2;
12396
12397 if (line_nid == 0x1d || speaker_nid == 0x1d) {
12398 snd_hda_codec_write(codec, speaker_nid, 0,
12399 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12400 /* mute mixer inputs from 0x1d */
12401 snd_hda_codec_write(codec, 0x0f, 0,
12402 AC_VERB_SET_AMP_GAIN_MUTE,
12403 AMP_IN_UNMUTE(1));
12404 snd_hda_codec_write(codec, 0x10, 0,
12405 AC_VERB_SET_AMP_GAIN_MUTE,
12406 AMP_IN_UNMUTE(1));
12407 } else {
12408 /* unmute mixer inputs from 0x1d */
12409 snd_hda_codec_write(codec, 0x0f, 0,
12410 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12411 snd_hda_codec_write(codec, 0x10, 0,
12412 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12413 }
12414
12415 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
12416 if (line_nid == 0x14)
12417 dac_vol2 = AMP_OUT_ZERO;
12418 else if (line_nid == 0x15)
12419 dac_vol1 = AMP_OUT_ZERO;
12420 if (hp_nid == 0x14)
12421 dac_vol2 = AMP_OUT_ZERO;
12422 else if (hp_nid == 0x15)
12423 dac_vol1 = AMP_OUT_ZERO;
12424 if (line_nid != 0x16 || hp_nid != 0x16 ||
12425 spec->autocfg.line_out_pins[1] != 0x16 ||
12426 spec->autocfg.line_out_pins[2] != 0x16)
12427 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12428
12429 snd_hda_codec_write(codec, 0x02, 0,
12430 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12431 snd_hda_codec_write(codec, 0x03, 0,
12432 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12433}
12434
12435/* pcm configuration: identical with ALC880 */
12436#define alc268_pcm_analog_playback alc880_pcm_analog_playback
12437#define alc268_pcm_analog_capture alc880_pcm_analog_capture
12438#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
12439#define alc268_pcm_digital_playback alc880_pcm_digital_playback
12440
12441/*
12442 * BIOS auto configuration
12443 */
12444static int alc268_parse_auto_config(struct hda_codec *codec)
12445{
12446 struct alc_spec *spec = codec->spec;
12447 int err;
12448 static hda_nid_t alc268_ignore[] = { 0 };
12449
12450 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12451 alc268_ignore);
12452 if (err < 0)
12453 return err;
12454 if (!spec->autocfg.line_outs) {
12455 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12456 spec->multiout.max_channels = 2;
12457 spec->no_analog = 1;
12458 goto dig_only;
12459 }
12460 return 0; /* can't find valid BIOS pin config */
12461 }
12462 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12463 if (err < 0)
12464 return err;
12465 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
12466 if (err < 0)
12467 return err;
12468
12469 spec->multiout.max_channels = 2;
12470
12471 dig_only:
12472 /* digital only support output */
12473 if (spec->autocfg.dig_outs) {
12474 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12475 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12476 }
12477 if (spec->kctls.list)
12478 add_mixer(spec, spec->kctls.list);
12479
12480 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12481 add_mixer(spec, alc268_beep_mixer);
12482
12483 add_verb(spec, alc268_volume_init_verbs);
12484 spec->num_mux_defs = 2;
12485 spec->input_mux = &spec->private_imux[0];
12486
12487 err = alc_auto_add_mic_boost(codec);
12488 if (err < 0)
12489 return err;
12490
12491 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12492
12493 return 1;
12494}
12495
12496#define alc268_auto_init_analog_input alc882_auto_init_analog_input
12497
12498/* init callback for auto-configuration model -- overriding the default init */
12499static void alc268_auto_init(struct hda_codec *codec)
12500{
12501 struct alc_spec *spec = codec->spec;
12502 alc268_auto_init_multi_out(codec);
12503 alc268_auto_init_hp_out(codec);
12504 alc268_auto_init_mono_speaker_out(codec);
12505 alc268_auto_init_analog_input(codec);
12506 if (spec->unsol_event)
12507 alc_inithook(codec);
12508}
12509
12510/*
12511 * configuration and preset
12512 */
12513static const char *alc268_models[ALC268_MODEL_LAST] = {
12514 [ALC267_QUANTA_IL1] = "quanta-il1",
12515 [ALC268_3ST] = "3stack",
12516 [ALC268_TOSHIBA] = "toshiba",
12517 [ALC268_ACER] = "acer",
12518 [ALC268_ACER_DMIC] = "acer-dmic",
12519 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12520 [ALC268_DELL] = "dell",
12521 [ALC268_ZEPTO] = "zepto",
12522#ifdef CONFIG_SND_DEBUG
12523 [ALC268_TEST] = "test",
12524#endif
12525 [ALC268_AUTO] = "auto",
12526};
12527
12528static struct snd_pci_quirk alc268_cfg_tbl[] = {
12529 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12530 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12531 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12532 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12533 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12534 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12535 ALC268_ACER_ASPIRE_ONE),
12536 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12537 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
12538 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
12539 /* almost compatible with toshiba but with optional digital outs;
12540 * auto-probing seems working fine
12541 */
12542 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12543 ALC268_AUTO),
12544 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12545 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12546 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12547 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12548 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12549 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12550 {}
12551};
12552
12553/* Toshiba laptops have no unique PCI SSID but only codec SSID */
12554static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
12555 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
12556 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
12557 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12558 ALC268_TOSHIBA),
12559 {}
12560};
12561
12562static struct alc_config_preset alc268_presets[] = {
12563 [ALC267_QUANTA_IL1] = {
12564 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
12565 alc268_capture_nosrc_mixer },
12566 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12567 alc267_quanta_il1_verbs },
12568 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12569 .dac_nids = alc268_dac_nids,
12570 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12571 .adc_nids = alc268_adc_nids_alt,
12572 .hp_nid = 0x03,
12573 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12574 .channel_mode = alc268_modes,
12575 .unsol_event = alc_sku_unsol_event,
12576 .setup = alc267_quanta_il1_setup,
12577 .init_hook = alc_inithook,
12578 },
12579 [ALC268_3ST] = {
12580 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12581 alc268_beep_mixer },
12582 .init_verbs = { alc268_base_init_verbs },
12583 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12584 .dac_nids = alc268_dac_nids,
12585 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12586 .adc_nids = alc268_adc_nids_alt,
12587 .capsrc_nids = alc268_capsrc_nids,
12588 .hp_nid = 0x03,
12589 .dig_out_nid = ALC268_DIGOUT_NID,
12590 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12591 .channel_mode = alc268_modes,
12592 .input_mux = &alc268_capture_source,
12593 },
12594 [ALC268_TOSHIBA] = {
12595 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12596 alc268_beep_mixer },
12597 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12598 alc268_toshiba_verbs },
12599 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12600 .dac_nids = alc268_dac_nids,
12601 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12602 .adc_nids = alc268_adc_nids_alt,
12603 .capsrc_nids = alc268_capsrc_nids,
12604 .hp_nid = 0x03,
12605 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12606 .channel_mode = alc268_modes,
12607 .input_mux = &alc268_capture_source,
12608 .unsol_event = alc268_toshiba_unsol_event,
12609 .setup = alc268_toshiba_setup,
12610 .init_hook = alc268_toshiba_automute,
12611 },
12612 [ALC268_ACER] = {
12613 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12614 alc268_beep_mixer },
12615 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12616 alc268_acer_verbs },
12617 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12618 .dac_nids = alc268_dac_nids,
12619 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12620 .adc_nids = alc268_adc_nids_alt,
12621 .capsrc_nids = alc268_capsrc_nids,
12622 .hp_nid = 0x02,
12623 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12624 .channel_mode = alc268_modes,
12625 .input_mux = &alc268_acer_capture_source,
12626 .unsol_event = alc268_acer_unsol_event,
12627 .init_hook = alc268_acer_init_hook,
12628 },
12629 [ALC268_ACER_DMIC] = {
12630 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12631 alc268_beep_mixer },
12632 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12633 alc268_acer_verbs },
12634 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12635 .dac_nids = alc268_dac_nids,
12636 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12637 .adc_nids = alc268_adc_nids_alt,
12638 .capsrc_nids = alc268_capsrc_nids,
12639 .hp_nid = 0x02,
12640 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12641 .channel_mode = alc268_modes,
12642 .input_mux = &alc268_acer_dmic_capture_source,
12643 .unsol_event = alc268_acer_unsol_event,
12644 .init_hook = alc268_acer_init_hook,
12645 },
12646 [ALC268_ACER_ASPIRE_ONE] = {
12647 .mixers = { alc268_acer_aspire_one_mixer,
12648 alc268_beep_mixer,
12649 alc268_capture_nosrc_mixer },
12650 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12651 alc268_acer_aspire_one_verbs },
12652 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12653 .dac_nids = alc268_dac_nids,
12654 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12655 .adc_nids = alc268_adc_nids_alt,
12656 .capsrc_nids = alc268_capsrc_nids,
12657 .hp_nid = 0x03,
12658 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12659 .channel_mode = alc268_modes,
12660 .unsol_event = alc268_acer_lc_unsol_event,
12661 .setup = alc268_acer_lc_setup,
12662 .init_hook = alc268_acer_lc_init_hook,
12663 },
12664 [ALC268_DELL] = {
12665 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
12666 alc268_capture_nosrc_mixer },
12667 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12668 alc268_dell_verbs },
12669 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12670 .dac_nids = alc268_dac_nids,
12671 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12672 .adc_nids = alc268_adc_nids_alt,
12673 .capsrc_nids = alc268_capsrc_nids,
12674 .hp_nid = 0x02,
12675 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12676 .channel_mode = alc268_modes,
12677 .unsol_event = alc_sku_unsol_event,
12678 .setup = alc268_dell_setup,
12679 .init_hook = alc_inithook,
12680 },
12681 [ALC268_ZEPTO] = {
12682 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12683 alc268_beep_mixer },
12684 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12685 alc268_toshiba_verbs },
12686 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12687 .dac_nids = alc268_dac_nids,
12688 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12689 .adc_nids = alc268_adc_nids_alt,
12690 .capsrc_nids = alc268_capsrc_nids,
12691 .hp_nid = 0x03,
12692 .dig_out_nid = ALC268_DIGOUT_NID,
12693 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12694 .channel_mode = alc268_modes,
12695 .input_mux = &alc268_capture_source,
12696 .setup = alc268_toshiba_setup,
12697 .init_hook = alc268_toshiba_automute,
12698 },
12699#ifdef CONFIG_SND_DEBUG
12700 [ALC268_TEST] = {
12701 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12702 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12703 alc268_volume_init_verbs },
12704 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12705 .dac_nids = alc268_dac_nids,
12706 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12707 .adc_nids = alc268_adc_nids_alt,
12708 .capsrc_nids = alc268_capsrc_nids,
12709 .hp_nid = 0x03,
12710 .dig_out_nid = ALC268_DIGOUT_NID,
12711 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12712 .channel_mode = alc268_modes,
12713 .input_mux = &alc268_capture_source,
12714 },
12715#endif
12716};
12717
12718static int patch_alc268(struct hda_codec *codec)
12719{
12720 struct alc_spec *spec;
12721 int board_config;
12722 int i, has_beep, err;
12723
12724 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12725 if (spec == NULL)
12726 return -ENOMEM;
12727
12728 codec->spec = spec;
12729
12730 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12731 alc268_models,
12732 alc268_cfg_tbl);
12733
12734 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
12735 board_config = snd_hda_check_board_codec_sid_config(codec,
12736 ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
12737
12738 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12739 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12740 codec->chip_name);
12741 board_config = ALC268_AUTO;
12742 }
12743
12744 if (board_config == ALC268_AUTO) {
12745 /* automatic parse from the BIOS config */
12746 err = alc268_parse_auto_config(codec);
12747 if (err < 0) {
12748 alc_free(codec);
12749 return err;
12750 } else if (!err) {
12751 printk(KERN_INFO
12752 "hda_codec: Cannot set up configuration "
12753 "from BIOS. Using base mode...\n");
12754 board_config = ALC268_3ST;
12755 }
12756 }
12757
12758 if (board_config != ALC268_AUTO)
12759 setup_preset(codec, &alc268_presets[board_config]);
12760
12761 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12762 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12763 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12764
12765 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12766
12767 has_beep = 0;
12768 for (i = 0; i < spec->num_mixers; i++) {
12769 if (spec->mixers[i] == alc268_beep_mixer) {
12770 has_beep = 1;
12771 break;
12772 }
12773 }
12774
12775 if (has_beep) {
12776 err = snd_hda_attach_beep_device(codec, 0x1);
12777 if (err < 0) {
12778 alc_free(codec);
12779 return err;
12780 }
12781 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12782 /* override the amp caps for beep generator */
12783 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12784 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12785 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12786 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12787 (0 << AC_AMPCAP_MUTE_SHIFT));
12788 }
12789
12790 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12791 /* check whether NID 0x07 is valid */
12792 unsigned int wcap = get_wcaps(codec, 0x07);
12793 int i;
12794
12795 spec->capsrc_nids = alc268_capsrc_nids;
12796 /* get type */
12797 wcap = get_wcaps_type(wcap);
12798 if (spec->auto_mic ||
12799 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12800 spec->adc_nids = alc268_adc_nids_alt;
12801 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12802 if (spec->auto_mic)
12803 fixup_automic_adc(codec);
12804 if (spec->auto_mic || spec->input_mux->num_items == 1)
12805 add_mixer(spec, alc268_capture_nosrc_mixer);
12806 else
12807 add_mixer(spec, alc268_capture_alt_mixer);
12808 } else {
12809 spec->adc_nids = alc268_adc_nids;
12810 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12811 add_mixer(spec, alc268_capture_mixer);
12812 }
12813 /* set default input source */
12814 for (i = 0; i < spec->num_adc_nids; i++)
12815 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12816 0, AC_VERB_SET_CONNECT_SEL,
12817 i < spec->num_mux_defs ?
12818 spec->input_mux[i].items[0].index :
12819 spec->input_mux->items[0].index);
12820 }
12821
12822 spec->vmaster_nid = 0x02;
12823
12824 codec->patch_ops = alc_patch_ops;
12825 if (board_config == ALC268_AUTO)
12826 spec->init_hook = alc268_auto_init;
12827
12828 codec->proc_widget_hook = print_realtek_coef;
12829
12830 return 0;
12831}
12832
12833/*
12834 * ALC269 channel source setting (2 channel)
12835 */
12836#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12837
12838#define alc269_dac_nids alc260_dac_nids
12839
12840static hda_nid_t alc269_adc_nids[1] = {
12841 /* ADC1 */
12842 0x08,
12843};
12844
12845static hda_nid_t alc269_capsrc_nids[1] = {
12846 0x23,
12847};
12848
12849/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12850 * not a mux!
12851 */
12852
12853#define alc269_modes alc260_modes
12854#define alc269_capture_source alc880_lg_lw_capture_source
12855
12856static struct snd_kcontrol_new alc269_base_mixer[] = {
12857 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12858 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12859 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12860 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12863 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12864 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12865 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12866 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12867 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12868 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12869 { } /* end */
12870};
12871
12872static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12873 /* output mixer control */
12874 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12875 {
12876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12877 .name = "Master Playback Switch",
12878 .info = snd_hda_mixer_amp_switch_info,
12879 .get = snd_hda_mixer_amp_switch_get,
12880 .put = alc268_acer_master_sw_put,
12881 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12882 },
12883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12885 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12886 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12887 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12888 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12889 { }
12890};
12891
12892static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12893 /* output mixer control */
12894 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12895 {
12896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12897 .name = "Master Playback Switch",
12898 .info = snd_hda_mixer_amp_switch_info,
12899 .get = snd_hda_mixer_amp_switch_get,
12900 .put = alc268_acer_master_sw_put,
12901 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12902 },
12903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12905 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12906 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12907 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12908 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12909 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12910 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12911 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12912 { }
12913};
12914
12915static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12916 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12917 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12919 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12920 { } /* end */
12921};
12922
12923/* capture mixer elements */
12924static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12925 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12926 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12927 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12928 { } /* end */
12929};
12930
12931/* FSC amilo */
12932#define alc269_fujitsu_mixer alc269_eeepc_mixer
12933
12934static struct hda_verb alc269_quanta_fl1_verbs[] = {
12935 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12936 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12937 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12938 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12939 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12940 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12941 { }
12942};
12943
12944static struct hda_verb alc269_lifebook_verbs[] = {
12945 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12946 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12947 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12949 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12950 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12951 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12952 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12953 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12954 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12955 { }
12956};
12957
12958/* toggle speaker-output according to the hp-jack state */
12959static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12960{
12961 unsigned int present;
12962 unsigned char bits;
12963
12964 present = snd_hda_jack_detect(codec, 0x15);
12965 bits = present ? AMP_IN_MUTE(0) : 0;
12966 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12967 AMP_IN_MUTE(0), bits);
12968 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12969 AMP_IN_MUTE(0), bits);
12970
12971 snd_hda_codec_write(codec, 0x20, 0,
12972 AC_VERB_SET_COEF_INDEX, 0x0c);
12973 snd_hda_codec_write(codec, 0x20, 0,
12974 AC_VERB_SET_PROC_COEF, 0x680);
12975
12976 snd_hda_codec_write(codec, 0x20, 0,
12977 AC_VERB_SET_COEF_INDEX, 0x0c);
12978 snd_hda_codec_write(codec, 0x20, 0,
12979 AC_VERB_SET_PROC_COEF, 0x480);
12980}
12981
12982/* toggle speaker-output according to the hp-jacks state */
12983static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12984{
12985 unsigned int present;
12986 unsigned char bits;
12987
12988 /* Check laptop headphone socket */
12989 present = snd_hda_jack_detect(codec, 0x15);
12990
12991 /* Check port replicator headphone socket */
12992 present |= snd_hda_jack_detect(codec, 0x1a);
12993
12994 bits = present ? AMP_IN_MUTE(0) : 0;
12995 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12996 AMP_IN_MUTE(0), bits);
12997 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12998 AMP_IN_MUTE(0), bits);
12999
13000 snd_hda_codec_write(codec, 0x20, 0,
13001 AC_VERB_SET_COEF_INDEX, 0x0c);
13002 snd_hda_codec_write(codec, 0x20, 0,
13003 AC_VERB_SET_PROC_COEF, 0x680);
13004
13005 snd_hda_codec_write(codec, 0x20, 0,
13006 AC_VERB_SET_COEF_INDEX, 0x0c);
13007 snd_hda_codec_write(codec, 0x20, 0,
13008 AC_VERB_SET_PROC_COEF, 0x480);
13009}
13010
13011static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13012{
13013 unsigned int present_laptop;
13014 unsigned int present_dock;
13015
13016 present_laptop = snd_hda_jack_detect(codec, 0x18);
13017 present_dock = snd_hda_jack_detect(codec, 0x1b);
13018
13019 /* Laptop mic port overrides dock mic port, design decision */
13020 if (present_dock)
13021 snd_hda_codec_write(codec, 0x23, 0,
13022 AC_VERB_SET_CONNECT_SEL, 0x3);
13023 if (present_laptop)
13024 snd_hda_codec_write(codec, 0x23, 0,
13025 AC_VERB_SET_CONNECT_SEL, 0x0);
13026 if (!present_dock && !present_laptop)
13027 snd_hda_codec_write(codec, 0x23, 0,
13028 AC_VERB_SET_CONNECT_SEL, 0x1);
13029}
13030
13031static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13032 unsigned int res)
13033{
13034 switch (res >> 26) {
13035 case ALC880_HP_EVENT:
13036 alc269_quanta_fl1_speaker_automute(codec);
13037 break;
13038 case ALC880_MIC_EVENT:
13039 alc_mic_automute(codec);
13040 break;
13041 }
13042}
13043
13044static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13045 unsigned int res)
13046{
13047 if ((res >> 26) == ALC880_HP_EVENT)
13048 alc269_lifebook_speaker_automute(codec);
13049 if ((res >> 26) == ALC880_MIC_EVENT)
13050 alc269_lifebook_mic_autoswitch(codec);
13051}
13052
13053static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13054{
13055 struct alc_spec *spec = codec->spec;
13056 spec->ext_mic.pin = 0x18;
13057 spec->ext_mic.mux_idx = 0;
13058 spec->int_mic.pin = 0x19;
13059 spec->int_mic.mux_idx = 1;
13060 spec->auto_mic = 1;
13061}
13062
13063static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13064{
13065 alc269_quanta_fl1_speaker_automute(codec);
13066 alc_mic_automute(codec);
13067}
13068
13069static void alc269_lifebook_init_hook(struct hda_codec *codec)
13070{
13071 alc269_lifebook_speaker_automute(codec);
13072 alc269_lifebook_mic_autoswitch(codec);
13073}
13074
13075static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13076 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13077 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13078 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13079 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13080 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13081 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13082 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13083 {}
13084};
13085
13086static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13087 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13088 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13089 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13090 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13091 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13092 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13093 {}
13094};
13095
13096/* toggle speaker-output according to the hp-jack state */
13097static void alc269_speaker_automute(struct hda_codec *codec)
13098{
13099 unsigned int present;
13100 unsigned char bits;
13101
13102 present = snd_hda_jack_detect(codec, 0x15);
13103 bits = present ? AMP_IN_MUTE(0) : 0;
13104 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13105 AMP_IN_MUTE(0), bits);
13106 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13107 AMP_IN_MUTE(0), bits);
13108}
13109
13110/* unsolicited event for HP jack sensing */
13111static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13112 unsigned int res)
13113{
13114 switch (res >> 26) {
13115 case ALC880_HP_EVENT:
13116 alc269_speaker_automute(codec);
13117 break;
13118 case ALC880_MIC_EVENT:
13119 alc_mic_automute(codec);
13120 break;
13121 }
13122}
13123
13124static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13125{
13126 struct alc_spec *spec = codec->spec;
13127 spec->ext_mic.pin = 0x18;
13128 spec->ext_mic.mux_idx = 0;
13129 spec->int_mic.pin = 0x12;
13130 spec->int_mic.mux_idx = 5;
13131 spec->auto_mic = 1;
13132}
13133
13134static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13135{
13136 struct alc_spec *spec = codec->spec;
13137 spec->ext_mic.pin = 0x18;
13138 spec->ext_mic.mux_idx = 0;
13139 spec->int_mic.pin = 0x19;
13140 spec->int_mic.mux_idx = 1;
13141 spec->auto_mic = 1;
13142}
13143
13144static void alc269_eeepc_inithook(struct hda_codec *codec)
13145{
13146 alc269_speaker_automute(codec);
13147 alc_mic_automute(codec);
13148}
13149
13150/*
13151 * generic initialization of ADC, input mixers and output mixers
13152 */
13153static struct hda_verb alc269_init_verbs[] = {
13154 /*
13155 * Unmute ADC0 and set the default input to mic-in
13156 */
13157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13158
13159 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13160 * analog-loopback mixer widget
13161 * Note: PASD motherboards uses the Line In 2 as the input for
13162 * front panel mic (mic 2)
13163 */
13164 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13165 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13166 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13168 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13170
13171 /*
13172 * Set up output mixers (0x0c - 0x0e)
13173 */
13174 /* set vol=0 to output mixers */
13175 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13176 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13177
13178 /* set up input amps for analog loopback */
13179 /* Amp Indices: DAC = 0, mixer = 1 */
13180 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13182 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13183 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13184 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13185 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13186
13187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13188 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13189 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13190 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13191 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13192 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13193 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13194
13195 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13196 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13197 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13200 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13201 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13202
13203 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
13205
13206 /* FIXME: use matrix-type input source selection */
13207 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13208 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13212 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13213
13214 /* set EAPD */
13215 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13216 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13217 { }
13218};
13219
13220#define alc269_auto_create_multi_out_ctls \
13221 alc268_auto_create_multi_out_ctls
13222#define alc269_auto_create_input_ctls \
13223 alc268_auto_create_input_ctls
13224
13225#ifdef CONFIG_SND_HDA_POWER_SAVE
13226#define alc269_loopbacks alc880_loopbacks
13227#endif
13228
13229/* pcm configuration: identical with ALC880 */
13230#define alc269_pcm_analog_playback alc880_pcm_analog_playback
13231#define alc269_pcm_analog_capture alc880_pcm_analog_capture
13232#define alc269_pcm_digital_playback alc880_pcm_digital_playback
13233#define alc269_pcm_digital_capture alc880_pcm_digital_capture
13234
13235static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13236 .substreams = 1,
13237 .channels_min = 2,
13238 .channels_max = 8,
13239 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13240 /* NID is set in alc_build_pcms */
13241 .ops = {
13242 .open = alc880_playback_pcm_open,
13243 .prepare = alc880_playback_pcm_prepare,
13244 .cleanup = alc880_playback_pcm_cleanup
13245 },
13246};
13247
13248static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13249 .substreams = 1,
13250 .channels_min = 2,
13251 .channels_max = 2,
13252 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13253 /* NID is set in alc_build_pcms */
13254};
13255
13256/*
13257 * BIOS auto configuration
13258 */
13259static int alc269_parse_auto_config(struct hda_codec *codec)
13260{
13261 struct alc_spec *spec = codec->spec;
13262 int err;
13263 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13264
13265 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13266 alc269_ignore);
13267 if (err < 0)
13268 return err;
13269
13270 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13271 if (err < 0)
13272 return err;
13273 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
13274 if (err < 0)
13275 return err;
13276
13277 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13278
13279 if (spec->autocfg.dig_outs)
13280 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13281
13282 if (spec->kctls.list)
13283 add_mixer(spec, spec->kctls.list);
13284
13285 add_verb(spec, alc269_init_verbs);
13286 spec->num_mux_defs = 1;
13287 spec->input_mux = &spec->private_imux[0];
13288 /* set default input source */
13289 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13290 0, AC_VERB_SET_CONNECT_SEL,
13291 spec->input_mux->items[0].index);
13292
13293 err = alc_auto_add_mic_boost(codec);
13294 if (err < 0)
13295 return err;
13296
13297 if (!spec->cap_mixer && !spec->no_analog)
13298 set_capture_mixer(codec);
13299
13300 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13301
13302 return 1;
13303}
13304
13305#define alc269_auto_init_multi_out alc268_auto_init_multi_out
13306#define alc269_auto_init_hp_out alc268_auto_init_hp_out
13307#define alc269_auto_init_analog_input alc882_auto_init_analog_input
13308
13309
13310/* init callback for auto-configuration model -- overriding the default init */
13311static void alc269_auto_init(struct hda_codec *codec)
13312{
13313 struct alc_spec *spec = codec->spec;
13314 alc269_auto_init_multi_out(codec);
13315 alc269_auto_init_hp_out(codec);
13316 alc269_auto_init_analog_input(codec);
13317 if (spec->unsol_event)
13318 alc_inithook(codec);
13319}
13320
13321/*
13322 * configuration and preset
13323 */
13324static const char *alc269_models[ALC269_MODEL_LAST] = {
13325 [ALC269_BASIC] = "basic",
13326 [ALC269_QUANTA_FL1] = "quanta",
13327 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
13328 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
13329 [ALC269_FUJITSU] = "fujitsu",
13330 [ALC269_LIFEBOOK] = "lifebook",
13331 [ALC269_AUTO] = "auto",
13332};
13333
13334static struct snd_pci_quirk alc269_cfg_tbl[] = {
13335 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13336 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13337 ALC269_ASUS_EEEPC_P703),
13338 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13339 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13340 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13341 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13342 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13343 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
13344 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13345 ALC269_ASUS_EEEPC_P901),
13346 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13347 ALC269_ASUS_EEEPC_P901),
13348 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
13349 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13350 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13351 {}
13352};
13353
13354static struct alc_config_preset alc269_presets[] = {
13355 [ALC269_BASIC] = {
13356 .mixers = { alc269_base_mixer },
13357 .init_verbs = { alc269_init_verbs },
13358 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13359 .dac_nids = alc269_dac_nids,
13360 .hp_nid = 0x03,
13361 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13362 .channel_mode = alc269_modes,
13363 .input_mux = &alc269_capture_source,
13364 },
13365 [ALC269_QUANTA_FL1] = {
13366 .mixers = { alc269_quanta_fl1_mixer },
13367 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13368 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13369 .dac_nids = alc269_dac_nids,
13370 .hp_nid = 0x03,
13371 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13372 .channel_mode = alc269_modes,
13373 .input_mux = &alc269_capture_source,
13374 .unsol_event = alc269_quanta_fl1_unsol_event,
13375 .setup = alc269_quanta_fl1_setup,
13376 .init_hook = alc269_quanta_fl1_init_hook,
13377 },
13378 [ALC269_ASUS_EEEPC_P703] = {
13379 .mixers = { alc269_eeepc_mixer },
13380 .cap_mixer = alc269_epc_capture_mixer,
13381 .init_verbs = { alc269_init_verbs,
13382 alc269_eeepc_amic_init_verbs },
13383 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13384 .dac_nids = alc269_dac_nids,
13385 .hp_nid = 0x03,
13386 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13387 .channel_mode = alc269_modes,
13388 .unsol_event = alc269_eeepc_unsol_event,
13389 .setup = alc269_eeepc_amic_setup,
13390 .init_hook = alc269_eeepc_inithook,
13391 },
13392 [ALC269_ASUS_EEEPC_P901] = {
13393 .mixers = { alc269_eeepc_mixer },
13394 .cap_mixer = alc269_epc_capture_mixer,
13395 .init_verbs = { alc269_init_verbs,
13396 alc269_eeepc_dmic_init_verbs },
13397 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13398 .dac_nids = alc269_dac_nids,
13399 .hp_nid = 0x03,
13400 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13401 .channel_mode = alc269_modes,
13402 .unsol_event = alc269_eeepc_unsol_event,
13403 .setup = alc269_eeepc_dmic_setup,
13404 .init_hook = alc269_eeepc_inithook,
13405 },
13406 [ALC269_FUJITSU] = {
13407 .mixers = { alc269_fujitsu_mixer },
13408 .cap_mixer = alc269_epc_capture_mixer,
13409 .init_verbs = { alc269_init_verbs,
13410 alc269_eeepc_dmic_init_verbs },
13411 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13412 .dac_nids = alc269_dac_nids,
13413 .hp_nid = 0x03,
13414 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13415 .channel_mode = alc269_modes,
13416 .unsol_event = alc269_eeepc_unsol_event,
13417 .setup = alc269_eeepc_dmic_setup,
13418 .init_hook = alc269_eeepc_inithook,
13419 },
13420 [ALC269_LIFEBOOK] = {
13421 .mixers = { alc269_lifebook_mixer },
13422 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13423 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13424 .dac_nids = alc269_dac_nids,
13425 .hp_nid = 0x03,
13426 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13427 .channel_mode = alc269_modes,
13428 .input_mux = &alc269_capture_source,
13429 .unsol_event = alc269_lifebook_unsol_event,
13430 .init_hook = alc269_lifebook_init_hook,
13431 },
13432};
13433
13434static int patch_alc269(struct hda_codec *codec)
13435{
13436 struct alc_spec *spec;
13437 int board_config;
13438 int err;
13439
13440 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13441 if (spec == NULL)
13442 return -ENOMEM;
13443
13444 codec->spec = spec;
13445
13446 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13447
13448 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13449 alc269_models,
13450 alc269_cfg_tbl);
13451
13452 if (board_config < 0) {
13453 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13454 codec->chip_name);
13455 board_config = ALC269_AUTO;
13456 }
13457
13458 if (board_config == ALC269_AUTO) {
13459 /* automatic parse from the BIOS config */
13460 err = alc269_parse_auto_config(codec);
13461 if (err < 0) {
13462 alc_free(codec);
13463 return err;
13464 } else if (!err) {
13465 printk(KERN_INFO
13466 "hda_codec: Cannot set up configuration "
13467 "from BIOS. Using base mode...\n");
13468 board_config = ALC269_BASIC;
13469 }
13470 }
13471
13472 err = snd_hda_attach_beep_device(codec, 0x1);
13473 if (err < 0) {
13474 alc_free(codec);
13475 return err;
13476 }
13477
13478 if (board_config != ALC269_AUTO)
13479 setup_preset(codec, &alc269_presets[board_config]);
13480
13481 if (codec->subsystem_id == 0x17aa3bf8) {
13482 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13483 * fix the sample rate of analog I/O to 44.1kHz
13484 */
13485 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13486 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13487 } else {
13488 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13489 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13490 }
13491 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13492 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13493
13494 spec->adc_nids = alc269_adc_nids;
13495 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13496 spec->capsrc_nids = alc269_capsrc_nids;
13497 if (!spec->cap_mixer)
13498 set_capture_mixer(codec);
13499 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13500
13501 spec->vmaster_nid = 0x02;
13502
13503 codec->patch_ops = alc_patch_ops;
13504 if (board_config == ALC269_AUTO)
13505 spec->init_hook = alc269_auto_init;
13506#ifdef CONFIG_SND_HDA_POWER_SAVE
13507 if (!spec->loopback.amplist)
13508 spec->loopback.amplist = alc269_loopbacks;
13509#endif
13510 codec->proc_widget_hook = print_realtek_coef;
13511
13512 return 0;
13513}
13514
13515/*
13516 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13517 */
13518
13519/*
13520 * set the path ways for 2 channel output
13521 * need to set the codec line out and mic 1 pin widgets to inputs
13522 */
13523static struct hda_verb alc861_threestack_ch2_init[] = {
13524 /* set pin widget 1Ah (line in) for input */
13525 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13526 /* set pin widget 18h (mic1/2) for input, for mic also enable
13527 * the vref
13528 */
13529 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13530
13531 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13532#if 0
13533 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13534 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13535#endif
13536 { } /* end */
13537};
13538/*
13539 * 6ch mode
13540 * need to set the codec line out and mic 1 pin widgets to outputs
13541 */
13542static struct hda_verb alc861_threestack_ch6_init[] = {
13543 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13544 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13545 /* set pin widget 18h (mic1) for output (CLFE)*/
13546 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13547
13548 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13549 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13550
13551 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13552#if 0
13553 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13554 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13555#endif
13556 { } /* end */
13557};
13558
13559static struct hda_channel_mode alc861_threestack_modes[2] = {
13560 { 2, alc861_threestack_ch2_init },
13561 { 6, alc861_threestack_ch6_init },
13562};
13563/* Set mic1 as input and unmute the mixer */
13564static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13565 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13566 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13567 { } /* end */
13568};
13569/* Set mic1 as output and mute mixer */
13570static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13571 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13572 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13573 { } /* end */
13574};
13575
13576static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13577 { 2, alc861_uniwill_m31_ch2_init },
13578 { 4, alc861_uniwill_m31_ch4_init },
13579};
13580
13581/* Set mic1 and line-in as input and unmute the mixer */
13582static struct hda_verb alc861_asus_ch2_init[] = {
13583 /* set pin widget 1Ah (line in) for input */
13584 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13585 /* set pin widget 18h (mic1/2) for input, for mic also enable
13586 * the vref
13587 */
13588 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13589
13590 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13591#if 0
13592 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13593 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13594#endif
13595 { } /* end */
13596};
13597/* Set mic1 nad line-in as output and mute mixer */
13598static struct hda_verb alc861_asus_ch6_init[] = {
13599 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13600 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13601 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13602 /* set pin widget 18h (mic1) for output (CLFE)*/
13603 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13604 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13605 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13606 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13607
13608 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13609#if 0
13610 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13611 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13612#endif
13613 { } /* end */
13614};
13615
13616static struct hda_channel_mode alc861_asus_modes[2] = {
13617 { 2, alc861_asus_ch2_init },
13618 { 6, alc861_asus_ch6_init },
13619};
13620
13621/* patch-ALC861 */
13622
13623static struct snd_kcontrol_new alc861_base_mixer[] = {
13624 /* output mixer control */
13625 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13626 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13627 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13628 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13629 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13630
13631 /*Input mixer control */
13632 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13633 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13634 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13635 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13636 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13637 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13639 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13640 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13642
13643 { } /* end */
13644};
13645
13646static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13647 /* output mixer control */
13648 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13649 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13650 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13651 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13652 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13653
13654 /* Input mixer control */
13655 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13656 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13657 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13658 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13659 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13660 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13662 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13663 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13665
13666 {
13667 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13668 .name = "Channel Mode",
13669 .info = alc_ch_mode_info,
13670 .get = alc_ch_mode_get,
13671 .put = alc_ch_mode_put,
13672 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13673 },
13674 { } /* end */
13675};
13676
13677static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13678 /* output mixer control */
13679 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13681 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13682
13683 { } /* end */
13684};
13685
13686static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13687 /* output mixer control */
13688 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13689 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13690 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13691 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13692 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13693
13694 /* Input mixer control */
13695 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13696 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13697 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13698 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13699 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13700 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13702 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13703 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13705
13706 {
13707 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13708 .name = "Channel Mode",
13709 .info = alc_ch_mode_info,
13710 .get = alc_ch_mode_get,
13711 .put = alc_ch_mode_put,
13712 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13713 },
13714 { } /* end */
13715};
13716
13717static struct snd_kcontrol_new alc861_asus_mixer[] = {
13718 /* output mixer control */
13719 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13720 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13721 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13722 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13723 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13724
13725 /* Input mixer control */
13726 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13727 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13728 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13729 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13730 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13731 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13733 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13734 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13735 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13736
13737 {
13738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13739 .name = "Channel Mode",
13740 .info = alc_ch_mode_info,
13741 .get = alc_ch_mode_get,
13742 .put = alc_ch_mode_put,
13743 .private_value = ARRAY_SIZE(alc861_asus_modes),
13744 },
13745 { }
13746};
13747
13748/* additional mixer */
13749static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13750 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13751 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13752 { }
13753};
13754
13755/*
13756 * generic initialization of ADC, input mixers and output mixers
13757 */
13758static struct hda_verb alc861_base_init_verbs[] = {
13759 /*
13760 * Unmute ADC0 and set the default input to mic-in
13761 */
13762 /* port-A for surround (rear panel) */
13763 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13764 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13765 /* port-B for mic-in (rear panel) with vref */
13766 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13767 /* port-C for line-in (rear panel) */
13768 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13769 /* port-D for Front */
13770 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13771 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13772 /* port-E for HP out (front panel) */
13773 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13774 /* route front PCM to HP */
13775 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13776 /* port-F for mic-in (front panel) with vref */
13777 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13778 /* port-G for CLFE (rear panel) */
13779 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13780 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13781 /* port-H for side (rear panel) */
13782 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13783 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13784 /* CD-in */
13785 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13786 /* route front mic to ADC1*/
13787 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13789
13790 /* Unmute DAC0~3 & spdif out*/
13791 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13792 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13793 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13794 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13795 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13796
13797 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13798 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13799 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13800 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13801 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13802
13803 /* Unmute Stereo Mixer 15 */
13804 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13806 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13808
13809 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13810 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13811 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13812 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13813 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13814 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13815 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13816 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13817 /* hp used DAC 3 (Front) */
13818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13819 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13820
13821 { }
13822};
13823
13824static struct hda_verb alc861_threestack_init_verbs[] = {
13825 /*
13826 * Unmute ADC0 and set the default input to mic-in
13827 */
13828 /* port-A for surround (rear panel) */
13829 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13830 /* port-B for mic-in (rear panel) with vref */
13831 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13832 /* port-C for line-in (rear panel) */
13833 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13834 /* port-D for Front */
13835 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13836 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13837 /* port-E for HP out (front panel) */
13838 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13839 /* route front PCM to HP */
13840 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13841 /* port-F for mic-in (front panel) with vref */
13842 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13843 /* port-G for CLFE (rear panel) */
13844 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13845 /* port-H for side (rear panel) */
13846 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13847 /* CD-in */
13848 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13849 /* route front mic to ADC1*/
13850 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13851 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13852 /* Unmute DAC0~3 & spdif out*/
13853 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13854 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13855 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13856 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13857 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13858
13859 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13860 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13861 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13862 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13863 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13864
13865 /* Unmute Stereo Mixer 15 */
13866 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13868 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13869 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13870
13871 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13872 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13873 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13874 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13876 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13877 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13878 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13879 /* hp used DAC 3 (Front) */
13880 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13881 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13882 { }
13883};
13884
13885static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13886 /*
13887 * Unmute ADC0 and set the default input to mic-in
13888 */
13889 /* port-A for surround (rear panel) */
13890 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13891 /* port-B for mic-in (rear panel) with vref */
13892 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13893 /* port-C for line-in (rear panel) */
13894 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13895 /* port-D for Front */
13896 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13897 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13898 /* port-E for HP out (front panel) */
13899 /* this has to be set to VREF80 */
13900 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13901 /* route front PCM to HP */
13902 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13903 /* port-F for mic-in (front panel) with vref */
13904 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13905 /* port-G for CLFE (rear panel) */
13906 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13907 /* port-H for side (rear panel) */
13908 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13909 /* CD-in */
13910 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13911 /* route front mic to ADC1*/
13912 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13913 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13914 /* Unmute DAC0~3 & spdif out*/
13915 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13916 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13917 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13918 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13920
13921 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13922 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13923 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13924 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13925 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13926
13927 /* Unmute Stereo Mixer 15 */
13928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13929 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13930 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13931 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13932
13933 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13934 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13935 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13936 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13937 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13938 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13939 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13940 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13941 /* hp used DAC 3 (Front) */
13942 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13943 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13944 { }
13945};
13946
13947static struct hda_verb alc861_asus_init_verbs[] = {
13948 /*
13949 * Unmute ADC0 and set the default input to mic-in
13950 */
13951 /* port-A for surround (rear panel)
13952 * according to codec#0 this is the HP jack
13953 */
13954 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13955 /* route front PCM to HP */
13956 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13957 /* port-B for mic-in (rear panel) with vref */
13958 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13959 /* port-C for line-in (rear panel) */
13960 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13961 /* port-D for Front */
13962 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13963 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13964 /* port-E for HP out (front panel) */
13965 /* this has to be set to VREF80 */
13966 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13967 /* route front PCM to HP */
13968 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13969 /* port-F for mic-in (front panel) with vref */
13970 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13971 /* port-G for CLFE (rear panel) */
13972 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13973 /* port-H for side (rear panel) */
13974 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13975 /* CD-in */
13976 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13977 /* route front mic to ADC1*/
13978 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13979 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13980 /* Unmute DAC0~3 & spdif out*/
13981 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13982 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13983 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13984 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13985 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13986 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13987 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13988 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13989 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13990 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13991
13992 /* Unmute Stereo Mixer 15 */
13993 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13995 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13996 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13997
13998 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13999 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14000 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14001 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14002 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14003 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14004 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14005 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14006 /* hp used DAC 3 (Front) */
14007 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14008 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14009 { }
14010};
14011
14012/* additional init verbs for ASUS laptops */
14013static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14014 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14015 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14016 { }
14017};
14018
14019/*
14020 * generic initialization of ADC, input mixers and output mixers
14021 */
14022static struct hda_verb alc861_auto_init_verbs[] = {
14023 /*
14024 * Unmute ADC0 and set the default input to mic-in
14025 */
14026 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
14027 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14028
14029 /* Unmute DAC0~3 & spdif out*/
14030 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14031 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14032 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14033 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14034 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14035
14036 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14037 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14038 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14039 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14040 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14041
14042 /* Unmute Stereo Mixer 15 */
14043 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14044 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14045 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14046 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14047
14048 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14049 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14050 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14051 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14053 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14054 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14055 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14056
14057 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14058 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14059 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14060 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14061 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14062 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14063 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14064 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14065
14066 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
14067
14068 { }
14069};
14070
14071static struct hda_verb alc861_toshiba_init_verbs[] = {
14072 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14073
14074 { }
14075};
14076
14077/* toggle speaker-output according to the hp-jack state */
14078static void alc861_toshiba_automute(struct hda_codec *codec)
14079{
14080 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
14081
14082 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14083 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14084 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14085 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
14086}
14087
14088static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14089 unsigned int res)
14090{
14091 if ((res >> 26) == ALC880_HP_EVENT)
14092 alc861_toshiba_automute(codec);
14093}
14094
14095/* pcm configuration: identical with ALC880 */
14096#define alc861_pcm_analog_playback alc880_pcm_analog_playback
14097#define alc861_pcm_analog_capture alc880_pcm_analog_capture
14098#define alc861_pcm_digital_playback alc880_pcm_digital_playback
14099#define alc861_pcm_digital_capture alc880_pcm_digital_capture
14100
14101
14102#define ALC861_DIGOUT_NID 0x07
14103
14104static struct hda_channel_mode alc861_8ch_modes[1] = {
14105 { 8, NULL }
14106};
14107
14108static hda_nid_t alc861_dac_nids[4] = {
14109 /* front, surround, clfe, side */
14110 0x03, 0x06, 0x05, 0x04
14111};
14112
14113static hda_nid_t alc660_dac_nids[3] = {
14114 /* front, clfe, surround */
14115 0x03, 0x05, 0x06
14116};
14117
14118static hda_nid_t alc861_adc_nids[1] = {
14119 /* ADC0-2 */
14120 0x08,
14121};
14122
14123static struct hda_input_mux alc861_capture_source = {
14124 .num_items = 5,
14125 .items = {
14126 { "Mic", 0x0 },
14127 { "Front Mic", 0x3 },
14128 { "Line", 0x1 },
14129 { "CD", 0x4 },
14130 { "Mixer", 0x5 },
14131 },
14132};
14133
14134static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14135{
14136 struct alc_spec *spec = codec->spec;
14137 hda_nid_t mix, srcs[5];
14138 int i, j, num;
14139
14140 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14141 return 0;
14142 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14143 if (num < 0)
14144 return 0;
14145 for (i = 0; i < num; i++) {
14146 unsigned int type;
14147 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
14148 if (type != AC_WID_AUD_OUT)
14149 continue;
14150 for (j = 0; j < spec->multiout.num_dacs; j++)
14151 if (spec->multiout.dac_nids[j] == srcs[i])
14152 break;
14153 if (j >= spec->multiout.num_dacs)
14154 return srcs[i];
14155 }
14156 return 0;
14157}
14158
14159/* fill in the dac_nids table from the parsed pin configuration */
14160static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
14161 const struct auto_pin_cfg *cfg)
14162{
14163 struct alc_spec *spec = codec->spec;
14164 int i;
14165 hda_nid_t nid, dac;
14166
14167 spec->multiout.dac_nids = spec->private_dac_nids;
14168 for (i = 0; i < cfg->line_outs; i++) {
14169 nid = cfg->line_out_pins[i];
14170 dac = alc861_look_for_dac(codec, nid);
14171 if (!dac)
14172 continue;
14173 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
14174 }
14175 return 0;
14176}
14177
14178static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14179 hda_nid_t nid, unsigned int chs)
14180{
14181 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
14182 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14183}
14184
14185/* add playback controls from the parsed DAC table */
14186static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
14187 const struct auto_pin_cfg *cfg)
14188{
14189 struct alc_spec *spec = codec->spec;
14190 static const char *chname[4] = {
14191 "Front", "Surround", NULL /*CLFE*/, "Side"
14192 };
14193 hda_nid_t nid;
14194 int i, err;
14195
14196 if (cfg->line_outs == 1) {
14197 const char *pfx = NULL;
14198 if (!cfg->hp_outs)
14199 pfx = "Master";
14200 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14201 pfx = "Speaker";
14202 if (pfx) {
14203 nid = spec->multiout.dac_nids[0];
14204 return alc861_create_out_sw(codec, pfx, nid, 3);
14205 }
14206 }
14207
14208 for (i = 0; i < cfg->line_outs; i++) {
14209 nid = spec->multiout.dac_nids[i];
14210 if (!nid)
14211 continue;
14212 if (i == 2) {
14213 /* Center/LFE */
14214 err = alc861_create_out_sw(codec, "Center", nid, 1);
14215 if (err < 0)
14216 return err;
14217 err = alc861_create_out_sw(codec, "LFE", nid, 2);
14218 if (err < 0)
14219 return err;
14220 } else {
14221 err = alc861_create_out_sw(codec, chname[i], nid, 3);
14222 if (err < 0)
14223 return err;
14224 }
14225 }
14226 return 0;
14227}
14228
14229static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
14230{
14231 struct alc_spec *spec = codec->spec;
14232 int err;
14233 hda_nid_t nid;
14234
14235 if (!pin)
14236 return 0;
14237
14238 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14239 nid = alc861_look_for_dac(codec, pin);
14240 if (nid) {
14241 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14242 if (err < 0)
14243 return err;
14244 spec->multiout.hp_nid = nid;
14245 }
14246 }
14247 return 0;
14248}
14249
14250/* create playback/capture controls for input pins */
14251static int alc861_auto_create_input_ctls(struct hda_codec *codec,
14252 const struct auto_pin_cfg *cfg)
14253{
14254 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
14255}
14256
14257static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14258 hda_nid_t nid,
14259 int pin_type, hda_nid_t dac)
14260{
14261 hda_nid_t mix, srcs[5];
14262 int i, num;
14263
14264 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14265 pin_type);
14266 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14267 AMP_OUT_UNMUTE);
14268 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14269 return;
14270 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14271 if (num < 0)
14272 return;
14273 for (i = 0; i < num; i++) {
14274 unsigned int mute;
14275 if (srcs[i] == dac || srcs[i] == 0x15)
14276 mute = AMP_IN_UNMUTE(i);
14277 else
14278 mute = AMP_IN_MUTE(i);
14279 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14280 mute);
14281 }
14282}
14283
14284static void alc861_auto_init_multi_out(struct hda_codec *codec)
14285{
14286 struct alc_spec *spec = codec->spec;
14287 int i;
14288
14289 for (i = 0; i < spec->autocfg.line_outs; i++) {
14290 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14291 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14292 if (nid)
14293 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
14294 spec->multiout.dac_nids[i]);
14295 }
14296}
14297
14298static void alc861_auto_init_hp_out(struct hda_codec *codec)
14299{
14300 struct alc_spec *spec = codec->spec;
14301
14302 if (spec->autocfg.hp_outs)
14303 alc861_auto_set_output_and_unmute(codec,
14304 spec->autocfg.hp_pins[0],
14305 PIN_HP,
14306 spec->multiout.hp_nid);
14307 if (spec->autocfg.speaker_outs)
14308 alc861_auto_set_output_and_unmute(codec,
14309 spec->autocfg.speaker_pins[0],
14310 PIN_OUT,
14311 spec->multiout.dac_nids[0]);
14312}
14313
14314static void alc861_auto_init_analog_input(struct hda_codec *codec)
14315{
14316 struct alc_spec *spec = codec->spec;
14317 int i;
14318
14319 for (i = 0; i < AUTO_PIN_LAST; i++) {
14320 hda_nid_t nid = spec->autocfg.input_pins[i];
14321 if (nid >= 0x0c && nid <= 0x11)
14322 alc_set_input_pin(codec, nid, i);
14323 }
14324}
14325
14326/* parse the BIOS configuration and set up the alc_spec */
14327/* return 1 if successful, 0 if the proper config is not found,
14328 * or a negative error code
14329 */
14330static int alc861_parse_auto_config(struct hda_codec *codec)
14331{
14332 struct alc_spec *spec = codec->spec;
14333 int err;
14334 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14335
14336 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14337 alc861_ignore);
14338 if (err < 0)
14339 return err;
14340 if (!spec->autocfg.line_outs)
14341 return 0; /* can't find valid BIOS pin config */
14342
14343 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
14344 if (err < 0)
14345 return err;
14346 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
14347 if (err < 0)
14348 return err;
14349 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
14350 if (err < 0)
14351 return err;
14352 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
14353 if (err < 0)
14354 return err;
14355
14356 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14357
14358 if (spec->autocfg.dig_outs)
14359 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14360
14361 if (spec->kctls.list)
14362 add_mixer(spec, spec->kctls.list);
14363
14364 add_verb(spec, alc861_auto_init_verbs);
14365
14366 spec->num_mux_defs = 1;
14367 spec->input_mux = &spec->private_imux[0];
14368
14369 spec->adc_nids = alc861_adc_nids;
14370 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14371 set_capture_mixer(codec);
14372
14373 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14374
14375 return 1;
14376}
14377
14378/* additional initialization for auto-configuration model */
14379static void alc861_auto_init(struct hda_codec *codec)
14380{
14381 struct alc_spec *spec = codec->spec;
14382 alc861_auto_init_multi_out(codec);
14383 alc861_auto_init_hp_out(codec);
14384 alc861_auto_init_analog_input(codec);
14385 if (spec->unsol_event)
14386 alc_inithook(codec);
14387}
14388
14389#ifdef CONFIG_SND_HDA_POWER_SAVE
14390static struct hda_amp_list alc861_loopbacks[] = {
14391 { 0x15, HDA_INPUT, 0 },
14392 { 0x15, HDA_INPUT, 1 },
14393 { 0x15, HDA_INPUT, 2 },
14394 { 0x15, HDA_INPUT, 3 },
14395 { } /* end */
14396};
14397#endif
14398
14399
14400/*
14401 * configuration and preset
14402 */
14403static const char *alc861_models[ALC861_MODEL_LAST] = {
14404 [ALC861_3ST] = "3stack",
14405 [ALC660_3ST] = "3stack-660",
14406 [ALC861_3ST_DIG] = "3stack-dig",
14407 [ALC861_6ST_DIG] = "6stack-dig",
14408 [ALC861_UNIWILL_M31] = "uniwill-m31",
14409 [ALC861_TOSHIBA] = "toshiba",
14410 [ALC861_ASUS] = "asus",
14411 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14412 [ALC861_AUTO] = "auto",
14413};
14414
14415static struct snd_pci_quirk alc861_cfg_tbl[] = {
14416 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14417 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14418 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14419 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14420 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14421 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14422 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14423 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14424 * Any other models that need this preset?
14425 */
14426 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14427 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14428 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14429 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14430 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14431 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14432 /* FIXME: the below seems conflict */
14433 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14434 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14435 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14436 {}
14437};
14438
14439static struct alc_config_preset alc861_presets[] = {
14440 [ALC861_3ST] = {
14441 .mixers = { alc861_3ST_mixer },
14442 .init_verbs = { alc861_threestack_init_verbs },
14443 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14444 .dac_nids = alc861_dac_nids,
14445 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14446 .channel_mode = alc861_threestack_modes,
14447 .need_dac_fix = 1,
14448 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14449 .adc_nids = alc861_adc_nids,
14450 .input_mux = &alc861_capture_source,
14451 },
14452 [ALC861_3ST_DIG] = {
14453 .mixers = { alc861_base_mixer },
14454 .init_verbs = { alc861_threestack_init_verbs },
14455 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14456 .dac_nids = alc861_dac_nids,
14457 .dig_out_nid = ALC861_DIGOUT_NID,
14458 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14459 .channel_mode = alc861_threestack_modes,
14460 .need_dac_fix = 1,
14461 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14462 .adc_nids = alc861_adc_nids,
14463 .input_mux = &alc861_capture_source,
14464 },
14465 [ALC861_6ST_DIG] = {
14466 .mixers = { alc861_base_mixer },
14467 .init_verbs = { alc861_base_init_verbs },
14468 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14469 .dac_nids = alc861_dac_nids,
14470 .dig_out_nid = ALC861_DIGOUT_NID,
14471 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14472 .channel_mode = alc861_8ch_modes,
14473 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14474 .adc_nids = alc861_adc_nids,
14475 .input_mux = &alc861_capture_source,
14476 },
14477 [ALC660_3ST] = {
14478 .mixers = { alc861_3ST_mixer },
14479 .init_verbs = { alc861_threestack_init_verbs },
14480 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14481 .dac_nids = alc660_dac_nids,
14482 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14483 .channel_mode = alc861_threestack_modes,
14484 .need_dac_fix = 1,
14485 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14486 .adc_nids = alc861_adc_nids,
14487 .input_mux = &alc861_capture_source,
14488 },
14489 [ALC861_UNIWILL_M31] = {
14490 .mixers = { alc861_uniwill_m31_mixer },
14491 .init_verbs = { alc861_uniwill_m31_init_verbs },
14492 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14493 .dac_nids = alc861_dac_nids,
14494 .dig_out_nid = ALC861_DIGOUT_NID,
14495 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14496 .channel_mode = alc861_uniwill_m31_modes,
14497 .need_dac_fix = 1,
14498 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14499 .adc_nids = alc861_adc_nids,
14500 .input_mux = &alc861_capture_source,
14501 },
14502 [ALC861_TOSHIBA] = {
14503 .mixers = { alc861_toshiba_mixer },
14504 .init_verbs = { alc861_base_init_verbs,
14505 alc861_toshiba_init_verbs },
14506 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14507 .dac_nids = alc861_dac_nids,
14508 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14509 .channel_mode = alc883_3ST_2ch_modes,
14510 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14511 .adc_nids = alc861_adc_nids,
14512 .input_mux = &alc861_capture_source,
14513 .unsol_event = alc861_toshiba_unsol_event,
14514 .init_hook = alc861_toshiba_automute,
14515 },
14516 [ALC861_ASUS] = {
14517 .mixers = { alc861_asus_mixer },
14518 .init_verbs = { alc861_asus_init_verbs },
14519 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14520 .dac_nids = alc861_dac_nids,
14521 .dig_out_nid = ALC861_DIGOUT_NID,
14522 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14523 .channel_mode = alc861_asus_modes,
14524 .need_dac_fix = 1,
14525 .hp_nid = 0x06,
14526 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14527 .adc_nids = alc861_adc_nids,
14528 .input_mux = &alc861_capture_source,
14529 },
14530 [ALC861_ASUS_LAPTOP] = {
14531 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14532 .init_verbs = { alc861_asus_init_verbs,
14533 alc861_asus_laptop_init_verbs },
14534 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14535 .dac_nids = alc861_dac_nids,
14536 .dig_out_nid = ALC861_DIGOUT_NID,
14537 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14538 .channel_mode = alc883_3ST_2ch_modes,
14539 .need_dac_fix = 1,
14540 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14541 .adc_nids = alc861_adc_nids,
14542 .input_mux = &alc861_capture_source,
14543 },
14544};
14545
14546
14547static int patch_alc861(struct hda_codec *codec)
14548{
14549 struct alc_spec *spec;
14550 int board_config;
14551 int err;
14552
14553 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14554 if (spec == NULL)
14555 return -ENOMEM;
14556
14557 codec->spec = spec;
14558
14559 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14560 alc861_models,
14561 alc861_cfg_tbl);
14562
14563 if (board_config < 0) {
14564 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14565 codec->chip_name);
14566 board_config = ALC861_AUTO;
14567 }
14568
14569 if (board_config == ALC861_AUTO) {
14570 /* automatic parse from the BIOS config */
14571 err = alc861_parse_auto_config(codec);
14572 if (err < 0) {
14573 alc_free(codec);
14574 return err;
14575 } else if (!err) {
14576 printk(KERN_INFO
14577 "hda_codec: Cannot set up configuration "
14578 "from BIOS. Using base mode...\n");
14579 board_config = ALC861_3ST_DIG;
14580 }
14581 }
14582
14583 err = snd_hda_attach_beep_device(codec, 0x23);
14584 if (err < 0) {
14585 alc_free(codec);
14586 return err;
14587 }
14588
14589 if (board_config != ALC861_AUTO)
14590 setup_preset(codec, &alc861_presets[board_config]);
14591
14592 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14593 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14594
14595 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14596 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14597
14598 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14599
14600 spec->vmaster_nid = 0x03;
14601
14602 codec->patch_ops = alc_patch_ops;
14603 if (board_config == ALC861_AUTO)
14604 spec->init_hook = alc861_auto_init;
14605#ifdef CONFIG_SND_HDA_POWER_SAVE
14606 if (!spec->loopback.amplist)
14607 spec->loopback.amplist = alc861_loopbacks;
14608#endif
14609 codec->proc_widget_hook = print_realtek_coef;
14610
14611 return 0;
14612}
14613
14614/*
14615 * ALC861-VD support
14616 *
14617 * Based on ALC882
14618 *
14619 * In addition, an independent DAC
14620 */
14621#define ALC861VD_DIGOUT_NID 0x06
14622
14623static hda_nid_t alc861vd_dac_nids[4] = {
14624 /* front, surr, clfe, side surr */
14625 0x02, 0x03, 0x04, 0x05
14626};
14627
14628/* dac_nids for ALC660vd are in a different order - according to
14629 * Realtek's driver.
14630 * This should probably result in a different mixer for 6stack models
14631 * of ALC660vd codecs, but for now there is only 3stack mixer
14632 * - and it is the same as in 861vd.
14633 * adc_nids in ALC660vd are (is) the same as in 861vd
14634 */
14635static hda_nid_t alc660vd_dac_nids[3] = {
14636 /* front, rear, clfe, rear_surr */
14637 0x02, 0x04, 0x03
14638};
14639
14640static hda_nid_t alc861vd_adc_nids[1] = {
14641 /* ADC0 */
14642 0x09,
14643};
14644
14645static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14646
14647/* input MUX */
14648/* FIXME: should be a matrix-type input source selection */
14649static struct hda_input_mux alc861vd_capture_source = {
14650 .num_items = 4,
14651 .items = {
14652 { "Mic", 0x0 },
14653 { "Front Mic", 0x1 },
14654 { "Line", 0x2 },
14655 { "CD", 0x4 },
14656 },
14657};
14658
14659static struct hda_input_mux alc861vd_dallas_capture_source = {
14660 .num_items = 2,
14661 .items = {
14662 { "Ext Mic", 0x0 },
14663 { "Int Mic", 0x1 },
14664 },
14665};
14666
14667static struct hda_input_mux alc861vd_hp_capture_source = {
14668 .num_items = 2,
14669 .items = {
14670 { "Front Mic", 0x0 },
14671 { "ATAPI Mic", 0x1 },
14672 },
14673};
14674
14675/*
14676 * 2ch mode
14677 */
14678static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14679 { 2, NULL }
14680};
14681
14682/*
14683 * 6ch mode
14684 */
14685static struct hda_verb alc861vd_6stack_ch6_init[] = {
14686 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14687 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14688 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14689 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14690 { } /* end */
14691};
14692
14693/*
14694 * 8ch mode
14695 */
14696static struct hda_verb alc861vd_6stack_ch8_init[] = {
14697 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14698 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14699 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14700 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14701 { } /* end */
14702};
14703
14704static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14705 { 6, alc861vd_6stack_ch6_init },
14706 { 8, alc861vd_6stack_ch8_init },
14707};
14708
14709static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14710 {
14711 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14712 .name = "Channel Mode",
14713 .info = alc_ch_mode_info,
14714 .get = alc_ch_mode_get,
14715 .put = alc_ch_mode_put,
14716 },
14717 { } /* end */
14718};
14719
14720/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14721 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14722 */
14723static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14724 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14725 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14726
14727 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14728 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14729
14730 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14731 HDA_OUTPUT),
14732 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14733 HDA_OUTPUT),
14734 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14735 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14736
14737 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14738 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14739
14740 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14741
14742 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14745
14746 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14747 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14748 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14749
14750 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14751 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14752
14753 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14754 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14755
14756 { } /* end */
14757};
14758
14759static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14760 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14761 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14762
14763 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14764
14765 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14767 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14768
14769 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14770 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14771 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14772
14773 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14774 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14775
14776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14778
14779 { } /* end */
14780};
14781
14782static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14783 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14784 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14785 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14786
14787 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14788
14789 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14791 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14792
14793 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14794 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14795 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14796
14797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14799
14800 { } /* end */
14801};
14802
14803/* Pin assignment: Speaker=0x14, HP = 0x15,
14804 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14805 */
14806static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14807 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14808 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14809 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14810 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14811 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14812 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14813 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14814 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14815 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14816 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14817 { } /* end */
14818};
14819
14820/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14821 * Front Mic=0x18, ATAPI Mic = 0x19,
14822 */
14823static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14824 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14825 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14826 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14827 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14828 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14829 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14830 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14831 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14832
14833 { } /* end */
14834};
14835
14836/*
14837 * generic initialization of ADC, input mixers and output mixers
14838 */
14839static struct hda_verb alc861vd_volume_init_verbs[] = {
14840 /*
14841 * Unmute ADC0 and set the default input to mic-in
14842 */
14843 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14844 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14845
14846 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14847 * the analog-loopback mixer widget
14848 */
14849 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14852 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14853 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14854 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14855
14856 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14861
14862 /*
14863 * Set up output mixers (0x02 - 0x05)
14864 */
14865 /* set vol=0 to output mixers */
14866 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14867 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14868 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14869 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14870
14871 /* set up input amps for analog loopback */
14872 /* Amp Indices: DAC = 0, mixer = 1 */
14873 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14875 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14876 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14877 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14878 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14879 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14880 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14881
14882 { }
14883};
14884
14885/*
14886 * 3-stack pin configuration:
14887 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14888 */
14889static struct hda_verb alc861vd_3stack_init_verbs[] = {
14890 /*
14891 * Set pin mode and muting
14892 */
14893 /* set front pin widgets 0x14 for output */
14894 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14895 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14896 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14897
14898 /* Mic (rear) pin: input vref at 80% */
14899 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14900 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14901 /* Front Mic pin: input vref at 80% */
14902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14904 /* Line In pin: input */
14905 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14906 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14907 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14908 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14909 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14910 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14911 /* CD pin widget for input */
14912 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14913
14914 { }
14915};
14916
14917/*
14918 * 6-stack pin configuration:
14919 */
14920static struct hda_verb alc861vd_6stack_init_verbs[] = {
14921 /*
14922 * Set pin mode and muting
14923 */
14924 /* set front pin widgets 0x14 for output */
14925 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14926 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14927 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14928
14929 /* Rear Pin: output 1 (0x0d) */
14930 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14931 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14933 /* CLFE Pin: output 2 (0x0e) */
14934 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14935 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14936 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14937 /* Side Pin: output 3 (0x0f) */
14938 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14939 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14940 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14941
14942 /* Mic (rear) pin: input vref at 80% */
14943 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14944 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14945 /* Front Mic pin: input vref at 80% */
14946 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14947 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14948 /* Line In pin: input */
14949 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14950 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14951 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14952 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14953 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14954 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14955 /* CD pin widget for input */
14956 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14957
14958 { }
14959};
14960
14961static struct hda_verb alc861vd_eapd_verbs[] = {
14962 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14963 { }
14964};
14965
14966static struct hda_verb alc660vd_eapd_verbs[] = {
14967 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14968 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14969 { }
14970};
14971
14972static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14974 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14975 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14976 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14977 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14978 {}
14979};
14980
14981static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14982{
14983 unsigned int present;
14984 unsigned char bits;
14985
14986 present = snd_hda_jack_detect(codec, 0x18);
14987 bits = present ? HDA_AMP_MUTE : 0;
14988
14989 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14990 HDA_AMP_MUTE, bits);
14991}
14992
14993static void alc861vd_lenovo_setup(struct hda_codec *codec)
14994{
14995 struct alc_spec *spec = codec->spec;
14996 spec->autocfg.hp_pins[0] = 0x1b;
14997 spec->autocfg.speaker_pins[0] = 0x14;
14998}
14999
15000static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15001{
15002 alc_automute_amp(codec);
15003 alc861vd_lenovo_mic_automute(codec);
15004}
15005
15006static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15007 unsigned int res)
15008{
15009 switch (res >> 26) {
15010 case ALC880_MIC_EVENT:
15011 alc861vd_lenovo_mic_automute(codec);
15012 break;
15013 default:
15014 alc_automute_amp_unsol_event(codec, res);
15015 break;
15016 }
15017}
15018
15019static struct hda_verb alc861vd_dallas_verbs[] = {
15020 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15021 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15022 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15023 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15024
15025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15028 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15031 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15032 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15033
15034 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15035 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15038 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15039 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15040 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15041 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15042
15043 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15044 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15045 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15046 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15047 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15048 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15049 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15050 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15051
15052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15056
15057 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15058 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15059 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15060
15061 { } /* end */
15062};
15063
15064/* toggle speaker-output according to the hp-jack state */
15065static void alc861vd_dallas_setup(struct hda_codec *codec)
15066{
15067 struct alc_spec *spec = codec->spec;
15068
15069 spec->autocfg.hp_pins[0] = 0x15;
15070 spec->autocfg.speaker_pins[0] = 0x14;
15071}
15072
15073#ifdef CONFIG_SND_HDA_POWER_SAVE
15074#define alc861vd_loopbacks alc880_loopbacks
15075#endif
15076
15077/* pcm configuration: identical with ALC880 */
15078#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15079#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15080#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15081#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15082
15083/*
15084 * configuration and preset
15085 */
15086static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15087 [ALC660VD_3ST] = "3stack-660",
15088 [ALC660VD_3ST_DIG] = "3stack-660-digout",
15089 [ALC660VD_ASUS_V1S] = "asus-v1s",
15090 [ALC861VD_3ST] = "3stack",
15091 [ALC861VD_3ST_DIG] = "3stack-digout",
15092 [ALC861VD_6ST_DIG] = "6stack-digout",
15093 [ALC861VD_LENOVO] = "lenovo",
15094 [ALC861VD_DALLAS] = "dallas",
15095 [ALC861VD_HP] = "hp",
15096 [ALC861VD_AUTO] = "auto",
15097};
15098
15099static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
15100 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15101 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
15102 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
15103 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
15104 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
15105 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
15106 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
15107 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
15108 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
15109 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
15110 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
15111 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
15112 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
15113 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
15114 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
15115 {}
15116};
15117
15118static struct alc_config_preset alc861vd_presets[] = {
15119 [ALC660VD_3ST] = {
15120 .mixers = { alc861vd_3st_mixer },
15121 .init_verbs = { alc861vd_volume_init_verbs,
15122 alc861vd_3stack_init_verbs },
15123 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15124 .dac_nids = alc660vd_dac_nids,
15125 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15126 .channel_mode = alc861vd_3stack_2ch_modes,
15127 .input_mux = &alc861vd_capture_source,
15128 },
15129 [ALC660VD_3ST_DIG] = {
15130 .mixers = { alc861vd_3st_mixer },
15131 .init_verbs = { alc861vd_volume_init_verbs,
15132 alc861vd_3stack_init_verbs },
15133 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15134 .dac_nids = alc660vd_dac_nids,
15135 .dig_out_nid = ALC861VD_DIGOUT_NID,
15136 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15137 .channel_mode = alc861vd_3stack_2ch_modes,
15138 .input_mux = &alc861vd_capture_source,
15139 },
15140 [ALC861VD_3ST] = {
15141 .mixers = { alc861vd_3st_mixer },
15142 .init_verbs = { alc861vd_volume_init_verbs,
15143 alc861vd_3stack_init_verbs },
15144 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15145 .dac_nids = alc861vd_dac_nids,
15146 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15147 .channel_mode = alc861vd_3stack_2ch_modes,
15148 .input_mux = &alc861vd_capture_source,
15149 },
15150 [ALC861VD_3ST_DIG] = {
15151 .mixers = { alc861vd_3st_mixer },
15152 .init_verbs = { alc861vd_volume_init_verbs,
15153 alc861vd_3stack_init_verbs },
15154 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15155 .dac_nids = alc861vd_dac_nids,
15156 .dig_out_nid = ALC861VD_DIGOUT_NID,
15157 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15158 .channel_mode = alc861vd_3stack_2ch_modes,
15159 .input_mux = &alc861vd_capture_source,
15160 },
15161 [ALC861VD_6ST_DIG] = {
15162 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
15163 .init_verbs = { alc861vd_volume_init_verbs,
15164 alc861vd_6stack_init_verbs },
15165 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15166 .dac_nids = alc861vd_dac_nids,
15167 .dig_out_nid = ALC861VD_DIGOUT_NID,
15168 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
15169 .channel_mode = alc861vd_6stack_modes,
15170 .input_mux = &alc861vd_capture_source,
15171 },
15172 [ALC861VD_LENOVO] = {
15173 .mixers = { alc861vd_lenovo_mixer },
15174 .init_verbs = { alc861vd_volume_init_verbs,
15175 alc861vd_3stack_init_verbs,
15176 alc861vd_eapd_verbs,
15177 alc861vd_lenovo_unsol_verbs },
15178 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15179 .dac_nids = alc660vd_dac_nids,
15180 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15181 .channel_mode = alc861vd_3stack_2ch_modes,
15182 .input_mux = &alc861vd_capture_source,
15183 .unsol_event = alc861vd_lenovo_unsol_event,
15184 .setup = alc861vd_lenovo_setup,
15185 .init_hook = alc861vd_lenovo_init_hook,
15186 },
15187 [ALC861VD_DALLAS] = {
15188 .mixers = { alc861vd_dallas_mixer },
15189 .init_verbs = { alc861vd_dallas_verbs },
15190 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15191 .dac_nids = alc861vd_dac_nids,
15192 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15193 .channel_mode = alc861vd_3stack_2ch_modes,
15194 .input_mux = &alc861vd_dallas_capture_source,
15195 .unsol_event = alc_automute_amp_unsol_event,
15196 .setup = alc861vd_dallas_setup,
15197 .init_hook = alc_automute_amp,
15198 },
15199 [ALC861VD_HP] = {
15200 .mixers = { alc861vd_hp_mixer },
15201 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15202 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15203 .dac_nids = alc861vd_dac_nids,
15204 .dig_out_nid = ALC861VD_DIGOUT_NID,
15205 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15206 .channel_mode = alc861vd_3stack_2ch_modes,
15207 .input_mux = &alc861vd_hp_capture_source,
15208 .unsol_event = alc_automute_amp_unsol_event,
15209 .setup = alc861vd_dallas_setup,
15210 .init_hook = alc_automute_amp,
15211 },
15212 [ALC660VD_ASUS_V1S] = {
15213 .mixers = { alc861vd_lenovo_mixer },
15214 .init_verbs = { alc861vd_volume_init_verbs,
15215 alc861vd_3stack_init_verbs,
15216 alc861vd_eapd_verbs,
15217 alc861vd_lenovo_unsol_verbs },
15218 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15219 .dac_nids = alc660vd_dac_nids,
15220 .dig_out_nid = ALC861VD_DIGOUT_NID,
15221 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15222 .channel_mode = alc861vd_3stack_2ch_modes,
15223 .input_mux = &alc861vd_capture_source,
15224 .unsol_event = alc861vd_lenovo_unsol_event,
15225 .setup = alc861vd_lenovo_setup,
15226 .init_hook = alc861vd_lenovo_init_hook,
15227 },
15228};
15229
15230/*
15231 * BIOS auto configuration
15232 */
15233static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15234 const struct auto_pin_cfg *cfg)
15235{
15236 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15237}
15238
15239
15240static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15241 hda_nid_t nid, int pin_type, int dac_idx)
15242{
15243 alc_set_pin_output(codec, nid, pin_type);
15244}
15245
15246static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15247{
15248 struct alc_spec *spec = codec->spec;
15249 int i;
15250
15251 for (i = 0; i <= HDA_SIDE; i++) {
15252 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15253 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15254 if (nid)
15255 alc861vd_auto_set_output_and_unmute(codec, nid,
15256 pin_type, i);
15257 }
15258}
15259
15260
15261static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15262{
15263 struct alc_spec *spec = codec->spec;
15264 hda_nid_t pin;
15265
15266 pin = spec->autocfg.hp_pins[0];
15267 if (pin) /* connect to front and use dac 0 */
15268 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15269 pin = spec->autocfg.speaker_pins[0];
15270 if (pin)
15271 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15272}
15273
15274#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15275
15276static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15277{
15278 struct alc_spec *spec = codec->spec;
15279 int i;
15280
15281 for (i = 0; i < AUTO_PIN_LAST; i++) {
15282 hda_nid_t nid = spec->autocfg.input_pins[i];
15283 if (alc_is_input_pin(codec, nid)) {
15284 alc_set_input_pin(codec, nid, i);
15285 if (nid != ALC861VD_PIN_CD_NID &&
15286 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
15287 snd_hda_codec_write(codec, nid, 0,
15288 AC_VERB_SET_AMP_GAIN_MUTE,
15289 AMP_OUT_MUTE);
15290 }
15291 }
15292}
15293
15294#define alc861vd_auto_init_input_src alc882_auto_init_input_src
15295
15296#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15297#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15298
15299/* add playback controls from the parsed DAC table */
15300/* Based on ALC880 version. But ALC861VD has separate,
15301 * different NIDs for mute/unmute switch and volume control */
15302static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15303 const struct auto_pin_cfg *cfg)
15304{
15305 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15306 hda_nid_t nid_v, nid_s;
15307 int i, err;
15308
15309 for (i = 0; i < cfg->line_outs; i++) {
15310 if (!spec->multiout.dac_nids[i])
15311 continue;
15312 nid_v = alc861vd_idx_to_mixer_vol(
15313 alc880_dac_to_idx(
15314 spec->multiout.dac_nids[i]));
15315 nid_s = alc861vd_idx_to_mixer_switch(
15316 alc880_dac_to_idx(
15317 spec->multiout.dac_nids[i]));
15318
15319 if (i == 2) {
15320 /* Center/LFE */
15321 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
15322 "Center",
15323 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15324 HDA_OUTPUT));
15325 if (err < 0)
15326 return err;
15327 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
15328 "LFE",
15329 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15330 HDA_OUTPUT));
15331 if (err < 0)
15332 return err;
15333 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
15334 "Center",
15335 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15336 HDA_INPUT));
15337 if (err < 0)
15338 return err;
15339 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
15340 "LFE",
15341 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15342 HDA_INPUT));
15343 if (err < 0)
15344 return err;
15345 } else {
15346 const char *pfx;
15347 if (cfg->line_outs == 1 &&
15348 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
15349 if (!cfg->hp_pins)
15350 pfx = "Speaker";
15351 else
15352 pfx = "PCM";
15353 } else
15354 pfx = chname[i];
15355 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
15356 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15357 HDA_OUTPUT));
15358 if (err < 0)
15359 return err;
15360 if (cfg->line_outs == 1 &&
15361 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15362 pfx = "Speaker";
15363 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
15364 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15365 HDA_INPUT));
15366 if (err < 0)
15367 return err;
15368 }
15369 }
15370 return 0;
15371}
15372
15373/* add playback controls for speaker and HP outputs */
15374/* Based on ALC880 version. But ALC861VD has separate,
15375 * different NIDs for mute/unmute switch and volume control */
15376static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15377 hda_nid_t pin, const char *pfx)
15378{
15379 hda_nid_t nid_v, nid_s;
15380 int err;
15381
15382 if (!pin)
15383 return 0;
15384
15385 if (alc880_is_fixed_pin(pin)) {
15386 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15387 /* specify the DAC as the extra output */
15388 if (!spec->multiout.hp_nid)
15389 spec->multiout.hp_nid = nid_v;
15390 else
15391 spec->multiout.extra_out_nid[0] = nid_v;
15392 /* control HP volume/switch on the output mixer amp */
15393 nid_v = alc861vd_idx_to_mixer_vol(
15394 alc880_fixed_pin_idx(pin));
15395 nid_s = alc861vd_idx_to_mixer_switch(
15396 alc880_fixed_pin_idx(pin));
15397
15398 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
15399 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15400 if (err < 0)
15401 return err;
15402 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
15403 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15404 if (err < 0)
15405 return err;
15406 } else if (alc880_is_multi_pin(pin)) {
15407 /* set manual connection */
15408 /* we have only a switch on HP-out PIN */
15409 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
15410 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15411 if (err < 0)
15412 return err;
15413 }
15414 return 0;
15415}
15416
15417/* parse the BIOS configuration and set up the alc_spec
15418 * return 1 if successful, 0 if the proper config is not found,
15419 * or a negative error code
15420 * Based on ALC880 version - had to change it to override
15421 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15422static int alc861vd_parse_auto_config(struct hda_codec *codec)
15423{
15424 struct alc_spec *spec = codec->spec;
15425 int err;
15426 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15427
15428 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15429 alc861vd_ignore);
15430 if (err < 0)
15431 return err;
15432 if (!spec->autocfg.line_outs)
15433 return 0; /* can't find valid BIOS pin config */
15434
15435 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15436 if (err < 0)
15437 return err;
15438 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15439 if (err < 0)
15440 return err;
15441 err = alc861vd_auto_create_extra_out(spec,
15442 spec->autocfg.speaker_pins[0],
15443 "Speaker");
15444 if (err < 0)
15445 return err;
15446 err = alc861vd_auto_create_extra_out(spec,
15447 spec->autocfg.hp_pins[0],
15448 "Headphone");
15449 if (err < 0)
15450 return err;
15451 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
15452 if (err < 0)
15453 return err;
15454
15455 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15456
15457 if (spec->autocfg.dig_outs)
15458 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15459
15460 if (spec->kctls.list)
15461 add_mixer(spec, spec->kctls.list);
15462
15463 add_verb(spec, alc861vd_volume_init_verbs);
15464
15465 spec->num_mux_defs = 1;
15466 spec->input_mux = &spec->private_imux[0];
15467
15468 err = alc_auto_add_mic_boost(codec);
15469 if (err < 0)
15470 return err;
15471
15472 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15473
15474 return 1;
15475}
15476
15477/* additional initialization for auto-configuration model */
15478static void alc861vd_auto_init(struct hda_codec *codec)
15479{
15480 struct alc_spec *spec = codec->spec;
15481 alc861vd_auto_init_multi_out(codec);
15482 alc861vd_auto_init_hp_out(codec);
15483 alc861vd_auto_init_analog_input(codec);
15484 alc861vd_auto_init_input_src(codec);
15485 if (spec->unsol_event)
15486 alc_inithook(codec);
15487}
15488
15489enum {
15490 ALC660VD_FIX_ASUS_GPIO1
15491};
15492
15493/* reset GPIO1 */
15494static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
15495 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
15496 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
15497 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
15498 { }
15499};
15500
15501static const struct alc_fixup alc861vd_fixups[] = {
15502 [ALC660VD_FIX_ASUS_GPIO1] = {
15503 .verbs = alc660vd_fix_asus_gpio1_verbs,
15504 },
15505};
15506
15507static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
15508 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
15509 {}
15510};
15511
15512static int patch_alc861vd(struct hda_codec *codec)
15513{
15514 struct alc_spec *spec;
15515 int err, board_config;
15516
15517 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15518 if (spec == NULL)
15519 return -ENOMEM;
15520
15521 codec->spec = spec;
15522
15523 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15524 alc861vd_models,
15525 alc861vd_cfg_tbl);
15526
15527 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15528 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15529 codec->chip_name);
15530 board_config = ALC861VD_AUTO;
15531 }
15532
15533 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
15534
15535 if (board_config == ALC861VD_AUTO) {
15536 /* automatic parse from the BIOS config */
15537 err = alc861vd_parse_auto_config(codec);
15538 if (err < 0) {
15539 alc_free(codec);
15540 return err;
15541 } else if (!err) {
15542 printk(KERN_INFO
15543 "hda_codec: Cannot set up configuration "
15544 "from BIOS. Using base mode...\n");
15545 board_config = ALC861VD_3ST;
15546 }
15547 }
15548
15549 err = snd_hda_attach_beep_device(codec, 0x23);
15550 if (err < 0) {
15551 alc_free(codec);
15552 return err;
15553 }
15554
15555 if (board_config != ALC861VD_AUTO)
15556 setup_preset(codec, &alc861vd_presets[board_config]);
15557
15558 if (codec->vendor_id == 0x10ec0660) {
15559 /* always turn on EAPD */
15560 add_verb(spec, alc660vd_eapd_verbs);
15561 }
15562
15563 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15564 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15565
15566 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15567 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15568
15569 if (!spec->adc_nids) {
15570 spec->adc_nids = alc861vd_adc_nids;
15571 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15572 }
15573 if (!spec->capsrc_nids)
15574 spec->capsrc_nids = alc861vd_capsrc_nids;
15575
15576 set_capture_mixer(codec);
15577 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15578
15579 spec->vmaster_nid = 0x02;
15580
15581 codec->patch_ops = alc_patch_ops;
15582
15583 if (board_config == ALC861VD_AUTO)
15584 spec->init_hook = alc861vd_auto_init;
15585#ifdef CONFIG_SND_HDA_POWER_SAVE
15586 if (!spec->loopback.amplist)
15587 spec->loopback.amplist = alc861vd_loopbacks;
15588#endif
15589 codec->proc_widget_hook = print_realtek_coef;
15590
15591 return 0;
15592}
15593
15594/*
15595 * ALC662 support
15596 *
15597 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15598 * configuration. Each pin widget can choose any input DACs and a mixer.
15599 * Each ADC is connected from a mixer of all inputs. This makes possible
15600 * 6-channel independent captures.
15601 *
15602 * In addition, an independent DAC for the multi-playback (not used in this
15603 * driver yet).
15604 */
15605#define ALC662_DIGOUT_NID 0x06
15606#define ALC662_DIGIN_NID 0x0a
15607
15608static hda_nid_t alc662_dac_nids[4] = {
15609 /* front, rear, clfe, rear_surr */
15610 0x02, 0x03, 0x04
15611};
15612
15613static hda_nid_t alc272_dac_nids[2] = {
15614 0x02, 0x03
15615};
15616
15617static hda_nid_t alc662_adc_nids[2] = {
15618 /* ADC1-2 */
15619 0x09, 0x08
15620};
15621
15622static hda_nid_t alc272_adc_nids[1] = {
15623 /* ADC1-2 */
15624 0x08,
15625};
15626
15627static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
15628static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15629
15630
15631/* input MUX */
15632/* FIXME: should be a matrix-type input source selection */
15633static struct hda_input_mux alc662_capture_source = {
15634 .num_items = 4,
15635 .items = {
15636 { "Mic", 0x0 },
15637 { "Front Mic", 0x1 },
15638 { "Line", 0x2 },
15639 { "CD", 0x4 },
15640 },
15641};
15642
15643static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15644 .num_items = 2,
15645 .items = {
15646 { "Mic", 0x1 },
15647 { "Line", 0x2 },
15648 },
15649};
15650
15651static struct hda_input_mux alc663_capture_source = {
15652 .num_items = 3,
15653 .items = {
15654 { "Mic", 0x0 },
15655 { "Front Mic", 0x1 },
15656 { "Line", 0x2 },
15657 },
15658};
15659
15660#if 0 /* set to 1 for testing other input sources below */
15661static struct hda_input_mux alc272_nc10_capture_source = {
15662 .num_items = 16,
15663 .items = {
15664 { "Autoselect Mic", 0x0 },
15665 { "Internal Mic", 0x1 },
15666 { "In-0x02", 0x2 },
15667 { "In-0x03", 0x3 },
15668 { "In-0x04", 0x4 },
15669 { "In-0x05", 0x5 },
15670 { "In-0x06", 0x6 },
15671 { "In-0x07", 0x7 },
15672 { "In-0x08", 0x8 },
15673 { "In-0x09", 0x9 },
15674 { "In-0x0a", 0x0a },
15675 { "In-0x0b", 0x0b },
15676 { "In-0x0c", 0x0c },
15677 { "In-0x0d", 0x0d },
15678 { "In-0x0e", 0x0e },
15679 { "In-0x0f", 0x0f },
15680 },
15681};
15682#endif
15683
15684/*
15685 * 2ch mode
15686 */
15687static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15688 { 2, NULL }
15689};
15690
15691/*
15692 * 2ch mode
15693 */
15694static struct hda_verb alc662_3ST_ch2_init[] = {
15695 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15696 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15697 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15698 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15699 { } /* end */
15700};
15701
15702/*
15703 * 6ch mode
15704 */
15705static struct hda_verb alc662_3ST_ch6_init[] = {
15706 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15707 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15708 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15709 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15710 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15711 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15712 { } /* end */
15713};
15714
15715static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15716 { 2, alc662_3ST_ch2_init },
15717 { 6, alc662_3ST_ch6_init },
15718};
15719
15720/*
15721 * 2ch mode
15722 */
15723static struct hda_verb alc662_sixstack_ch6_init[] = {
15724 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15725 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15726 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15727 { } /* end */
15728};
15729
15730/*
15731 * 6ch mode
15732 */
15733static struct hda_verb alc662_sixstack_ch8_init[] = {
15734 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15735 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15736 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15737 { } /* end */
15738};
15739
15740static struct hda_channel_mode alc662_5stack_modes[2] = {
15741 { 2, alc662_sixstack_ch6_init },
15742 { 6, alc662_sixstack_ch8_init },
15743};
15744
15745/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15746 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15747 */
15748
15749static struct snd_kcontrol_new alc662_base_mixer[] = {
15750 /* output mixer control */
15751 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15752 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15753 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15754 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15755 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15756 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15757 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15758 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15759 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15760
15761 /*Input mixer control */
15762 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15763 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15764 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15765 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15766 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15767 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15768 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15769 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15770 { } /* end */
15771};
15772
15773static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15774 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15775 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15776 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15777 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15778 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15779 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15780 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15783 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15784 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15785 { } /* end */
15786};
15787
15788static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15789 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15790 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15791 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15792 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15793 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15794 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15795 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15796 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15797 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15798 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15799 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15800 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15801 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15802 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15803 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15804 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15805 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15806 { } /* end */
15807};
15808
15809static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15810 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15811 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15812 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15813 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15814 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15818 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15819 { } /* end */
15820};
15821
15822static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15823 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15824 ALC262_HIPPO_MASTER_SWITCH,
15825
15826 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15827 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15828 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15829
15830 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15831 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15832 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15833 { } /* end */
15834};
15835
15836static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15837 ALC262_HIPPO_MASTER_SWITCH,
15838 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15839 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15840 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15841 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15842 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15843 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15844 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15846 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15847 { } /* end */
15848};
15849
15850static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15851 .ops = &snd_hda_bind_vol,
15852 .values = {
15853 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15854 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15855 0
15856 },
15857};
15858
15859static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15860 .ops = &snd_hda_bind_sw,
15861 .values = {
15862 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15863 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15864 0
15865 },
15866};
15867
15868static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15869 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15870 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15871 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15873 { } /* end */
15874};
15875
15876static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15877 .ops = &snd_hda_bind_sw,
15878 .values = {
15879 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15880 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15881 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15882 0
15883 },
15884};
15885
15886static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15887 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15888 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15889 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15891 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15892 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15893
15894 { } /* end */
15895};
15896
15897static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15898 .ops = &snd_hda_bind_sw,
15899 .values = {
15900 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15901 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15902 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15903 0
15904 },
15905};
15906
15907static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15908 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15909 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15910 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15911 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15912 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15913 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15914 { } /* end */
15915};
15916
15917static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15918 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15919 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15920 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15923 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15924 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15925 { } /* end */
15926};
15927
15928static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15929 .ops = &snd_hda_bind_vol,
15930 .values = {
15931 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15932 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15933 0
15934 },
15935};
15936
15937static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15938 .ops = &snd_hda_bind_sw,
15939 .values = {
15940 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15941 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15942 0
15943 },
15944};
15945
15946static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15947 HDA_BIND_VOL("Master Playback Volume",
15948 &alc663_asus_two_bind_master_vol),
15949 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15950 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15951 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15954 { } /* end */
15955};
15956
15957static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15958 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15959 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15960 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15961 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15962 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15963 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15964 { } /* end */
15965};
15966
15967static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15968 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15969 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15970 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15971 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15972 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15973
15974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15976 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15977 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15978 { } /* end */
15979};
15980
15981static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15982 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15983 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15985
15986 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15987 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15988 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15989 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15991 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15992 { } /* end */
15993};
15994
15995static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15996 {
15997 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15998 .name = "Channel Mode",
15999 .info = alc_ch_mode_info,
16000 .get = alc_ch_mode_get,
16001 .put = alc_ch_mode_put,
16002 },
16003 { } /* end */
16004};
16005
16006static struct hda_verb alc662_init_verbs[] = {
16007 /* ADC: mute amp left and right */
16008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16009 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16010 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16011
16012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16017
16018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16019 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16020 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16021 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16023 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16024
16025 /* Front Pin: output 0 (0x0c) */
16026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16028
16029 /* Rear Pin: output 1 (0x0d) */
16030 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16031 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16032
16033 /* CLFE Pin: output 2 (0x0e) */
16034 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16035 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16036
16037 /* Mic (rear) pin: input vref at 80% */
16038 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16039 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16040 /* Front Mic pin: input vref at 80% */
16041 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16042 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16043 /* Line In pin: input */
16044 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16045 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16046 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16047 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16048 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16049 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16050 /* CD pin widget for input */
16051 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16052
16053 /* FIXME: use matrix-type input source selection */
16054 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16055 /* Input mixer */
16056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16057 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16058
16059 /* always trun on EAPD */
16060 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16061 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16062
16063 { }
16064};
16065
16066static struct hda_verb alc662_sue_init_verbs[] = {
16067 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16068 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16069 {}
16070};
16071
16072static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
16073 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16074 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16075 {}
16076};
16077
16078/* Set Unsolicited Event*/
16079static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16080 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16081 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16082 {}
16083};
16084
16085/*
16086 * generic initialization of ADC, input mixers and output mixers
16087 */
16088static struct hda_verb alc662_auto_init_verbs[] = {
16089 /*
16090 * Unmute ADC and set the default input to mic-in
16091 */
16092 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16093 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16094
16095 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16096 * mixer widget
16097 * Note: PASD motherboards uses the Line In 2 as the input for front
16098 * panel mic (mic 2)
16099 */
16100 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16106
16107 /*
16108 * Set up output mixers (0x0c - 0x0f)
16109 */
16110 /* set vol=0 to output mixers */
16111 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16112 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16113 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16114
16115 /* set up input amps for analog loopback */
16116 /* Amp Indices: DAC = 0, mixer = 1 */
16117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16123
16124
16125 /* FIXME: use matrix-type input source selection */
16126 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16127 /* Input mixer */
16128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16129 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16130 { }
16131};
16132
16133/* additional verbs for ALC663 */
16134static struct hda_verb alc663_auto_init_verbs[] = {
16135 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16136 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16137 { }
16138};
16139
16140static struct hda_verb alc663_m51va_init_verbs[] = {
16141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16142 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16143 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16144 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16145 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16148 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16149 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16150 {}
16151};
16152
16153static struct hda_verb alc663_21jd_amic_init_verbs[] = {
16154 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16155 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16156 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16158 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16159 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16160 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16161 {}
16162};
16163
16164static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
16165 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16166 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16167 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16168 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16170 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16171 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16172 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16173 {}
16174};
16175
16176static struct hda_verb alc663_15jd_amic_init_verbs[] = {
16177 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16178 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16179 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16181 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16182 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16183 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16184 {}
16185};
16186
16187static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
16188 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16189 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16190 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16191 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16192 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16193 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16194 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16195 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16196 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16197 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16198 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16199 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16200 {}
16201};
16202
16203static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
16204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16206 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16207 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16209 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16210 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16211 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16212 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16213 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16214 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16215 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16216 {}
16217};
16218
16219static struct hda_verb alc663_g71v_init_verbs[] = {
16220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16221 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16222 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16223
16224 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16225 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16226 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16227
16228 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16229 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16230 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16231 {}
16232};
16233
16234static struct hda_verb alc663_g50v_init_verbs[] = {
16235 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16236 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16237 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16238
16239 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16240 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16241 {}
16242};
16243
16244static struct hda_verb alc662_ecs_init_verbs[] = {
16245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16247 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16248 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16249 {}
16250};
16251
16252static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16253 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16254 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16255 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16256 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16257 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16258 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16259 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16262 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16263 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16264 {}
16265};
16266
16267static struct hda_verb alc272_dell_init_verbs[] = {
16268 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16269 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16271 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16272 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16273 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16274 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16275 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16276 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16277 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16278 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16279 {}
16280};
16281
16282static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16283 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16284 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16285 { } /* end */
16286};
16287
16288static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16289 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16290 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16291 { } /* end */
16292};
16293
16294static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16295{
16296 unsigned int present;
16297 unsigned char bits;
16298
16299 present = snd_hda_jack_detect(codec, 0x14);
16300 bits = present ? HDA_AMP_MUTE : 0;
16301
16302 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16303 HDA_AMP_MUTE, bits);
16304}
16305
16306static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16307{
16308 unsigned int present;
16309 unsigned char bits;
16310
16311 present = snd_hda_jack_detect(codec, 0x1b);
16312 bits = present ? HDA_AMP_MUTE : 0;
16313
16314 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16315 HDA_AMP_MUTE, bits);
16316 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16317 HDA_AMP_MUTE, bits);
16318}
16319
16320static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16321 unsigned int res)
16322{
16323 if ((res >> 26) == ALC880_HP_EVENT)
16324 alc662_lenovo_101e_all_automute(codec);
16325 if ((res >> 26) == ALC880_FRONT_EVENT)
16326 alc662_lenovo_101e_ispeaker_automute(codec);
16327}
16328
16329/* unsolicited event for HP jack sensing */
16330static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16331 unsigned int res)
16332{
16333 if ((res >> 26) == ALC880_MIC_EVENT)
16334 alc_mic_automute(codec);
16335 else
16336 alc262_hippo_unsol_event(codec, res);
16337}
16338
16339static void alc662_eeepc_setup(struct hda_codec *codec)
16340{
16341 struct alc_spec *spec = codec->spec;
16342
16343 alc262_hippo1_setup(codec);
16344 spec->ext_mic.pin = 0x18;
16345 spec->ext_mic.mux_idx = 0;
16346 spec->int_mic.pin = 0x19;
16347 spec->int_mic.mux_idx = 1;
16348 spec->auto_mic = 1;
16349}
16350
16351static void alc662_eeepc_inithook(struct hda_codec *codec)
16352{
16353 alc262_hippo_automute(codec);
16354 alc_mic_automute(codec);
16355}
16356
16357static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
16358{
16359 struct alc_spec *spec = codec->spec;
16360
16361 spec->autocfg.hp_pins[0] = 0x14;
16362 spec->autocfg.speaker_pins[0] = 0x1b;
16363}
16364
16365#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
16366
16367static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16368{
16369 unsigned int present;
16370 unsigned char bits;
16371
16372 present = snd_hda_jack_detect(codec, 0x21);
16373 bits = present ? HDA_AMP_MUTE : 0;
16374 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16375 AMP_IN_MUTE(0), bits);
16376 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16377 AMP_IN_MUTE(0), bits);
16378}
16379
16380static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16381{
16382 unsigned int present;
16383 unsigned char bits;
16384
16385 present = snd_hda_jack_detect(codec, 0x21);
16386 bits = present ? HDA_AMP_MUTE : 0;
16387 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16388 AMP_IN_MUTE(0), bits);
16389 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16390 AMP_IN_MUTE(0), bits);
16391 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16392 AMP_IN_MUTE(0), bits);
16393 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16394 AMP_IN_MUTE(0), bits);
16395}
16396
16397static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16398{
16399 unsigned int present;
16400 unsigned char bits;
16401
16402 present = snd_hda_jack_detect(codec, 0x15);
16403 bits = present ? HDA_AMP_MUTE : 0;
16404 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16405 AMP_IN_MUTE(0), bits);
16406 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16407 AMP_IN_MUTE(0), bits);
16408 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16409 AMP_IN_MUTE(0), bits);
16410 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16411 AMP_IN_MUTE(0), bits);
16412}
16413
16414static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16415{
16416 unsigned int present;
16417 unsigned char bits;
16418
16419 present = snd_hda_jack_detect(codec, 0x1b);
16420 bits = present ? 0 : PIN_OUT;
16421 snd_hda_codec_write(codec, 0x14, 0,
16422 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16423}
16424
16425static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16426{
16427 unsigned int present1, present2;
16428
16429 present1 = snd_hda_jack_detect(codec, 0x21);
16430 present2 = snd_hda_jack_detect(codec, 0x15);
16431
16432 if (present1 || present2) {
16433 snd_hda_codec_write_cache(codec, 0x14, 0,
16434 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16435 } else {
16436 snd_hda_codec_write_cache(codec, 0x14, 0,
16437 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16438 }
16439}
16440
16441static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16442{
16443 unsigned int present1, present2;
16444
16445 present1 = snd_hda_jack_detect(codec, 0x1b);
16446 present2 = snd_hda_jack_detect(codec, 0x15);
16447
16448 if (present1 || present2) {
16449 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16450 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16451 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16452 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16453 } else {
16454 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16455 AMP_IN_MUTE(0), 0);
16456 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16457 AMP_IN_MUTE(0), 0);
16458 }
16459}
16460
16461static void alc663_m51va_unsol_event(struct hda_codec *codec,
16462 unsigned int res)
16463{
16464 switch (res >> 26) {
16465 case ALC880_HP_EVENT:
16466 alc663_m51va_speaker_automute(codec);
16467 break;
16468 case ALC880_MIC_EVENT:
16469 alc_mic_automute(codec);
16470 break;
16471 }
16472}
16473
16474static void alc663_m51va_setup(struct hda_codec *codec)
16475{
16476 struct alc_spec *spec = codec->spec;
16477 spec->ext_mic.pin = 0x18;
16478 spec->ext_mic.mux_idx = 0;
16479 spec->int_mic.pin = 0x12;
16480 spec->int_mic.mux_idx = 1;
16481 spec->auto_mic = 1;
16482}
16483
16484static void alc663_m51va_inithook(struct hda_codec *codec)
16485{
16486 alc663_m51va_speaker_automute(codec);
16487 alc_mic_automute(codec);
16488}
16489
16490/* ***************** Mode1 ******************************/
16491#define alc663_mode1_unsol_event alc663_m51va_unsol_event
16492#define alc663_mode1_setup alc663_m51va_setup
16493#define alc663_mode1_inithook alc663_m51va_inithook
16494
16495/* ***************** Mode2 ******************************/
16496static void alc662_mode2_unsol_event(struct hda_codec *codec,
16497 unsigned int res)
16498{
16499 switch (res >> 26) {
16500 case ALC880_HP_EVENT:
16501 alc662_f5z_speaker_automute(codec);
16502 break;
16503 case ALC880_MIC_EVENT:
16504 alc_mic_automute(codec);
16505 break;
16506 }
16507}
16508
16509#define alc662_mode2_setup alc663_m51va_setup
16510
16511static void alc662_mode2_inithook(struct hda_codec *codec)
16512{
16513 alc662_f5z_speaker_automute(codec);
16514 alc_mic_automute(codec);
16515}
16516/* ***************** Mode3 ******************************/
16517static void alc663_mode3_unsol_event(struct hda_codec *codec,
16518 unsigned int res)
16519{
16520 switch (res >> 26) {
16521 case ALC880_HP_EVENT:
16522 alc663_two_hp_m1_speaker_automute(codec);
16523 break;
16524 case ALC880_MIC_EVENT:
16525 alc_mic_automute(codec);
16526 break;
16527 }
16528}
16529
16530#define alc663_mode3_setup alc663_m51va_setup
16531
16532static void alc663_mode3_inithook(struct hda_codec *codec)
16533{
16534 alc663_two_hp_m1_speaker_automute(codec);
16535 alc_mic_automute(codec);
16536}
16537/* ***************** Mode4 ******************************/
16538static void alc663_mode4_unsol_event(struct hda_codec *codec,
16539 unsigned int res)
16540{
16541 switch (res >> 26) {
16542 case ALC880_HP_EVENT:
16543 alc663_21jd_two_speaker_automute(codec);
16544 break;
16545 case ALC880_MIC_EVENT:
16546 alc_mic_automute(codec);
16547 break;
16548 }
16549}
16550
16551#define alc663_mode4_setup alc663_m51va_setup
16552
16553static void alc663_mode4_inithook(struct hda_codec *codec)
16554{
16555 alc663_21jd_two_speaker_automute(codec);
16556 alc_mic_automute(codec);
16557}
16558/* ***************** Mode5 ******************************/
16559static void alc663_mode5_unsol_event(struct hda_codec *codec,
16560 unsigned int res)
16561{
16562 switch (res >> 26) {
16563 case ALC880_HP_EVENT:
16564 alc663_15jd_two_speaker_automute(codec);
16565 break;
16566 case ALC880_MIC_EVENT:
16567 alc_mic_automute(codec);
16568 break;
16569 }
16570}
16571
16572#define alc663_mode5_setup alc663_m51va_setup
16573
16574static void alc663_mode5_inithook(struct hda_codec *codec)
16575{
16576 alc663_15jd_two_speaker_automute(codec);
16577 alc_mic_automute(codec);
16578}
16579/* ***************** Mode6 ******************************/
16580static void alc663_mode6_unsol_event(struct hda_codec *codec,
16581 unsigned int res)
16582{
16583 switch (res >> 26) {
16584 case ALC880_HP_EVENT:
16585 alc663_two_hp_m2_speaker_automute(codec);
16586 break;
16587 case ALC880_MIC_EVENT:
16588 alc_mic_automute(codec);
16589 break;
16590 }
16591}
16592
16593#define alc663_mode6_setup alc663_m51va_setup
16594
16595static void alc663_mode6_inithook(struct hda_codec *codec)
16596{
16597 alc663_two_hp_m2_speaker_automute(codec);
16598 alc_mic_automute(codec);
16599}
16600
16601static void alc663_g71v_hp_automute(struct hda_codec *codec)
16602{
16603 unsigned int present;
16604 unsigned char bits;
16605
16606 present = snd_hda_jack_detect(codec, 0x21);
16607 bits = present ? HDA_AMP_MUTE : 0;
16608 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16609 HDA_AMP_MUTE, bits);
16610 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16611 HDA_AMP_MUTE, bits);
16612}
16613
16614static void alc663_g71v_front_automute(struct hda_codec *codec)
16615{
16616 unsigned int present;
16617 unsigned char bits;
16618
16619 present = snd_hda_jack_detect(codec, 0x15);
16620 bits = present ? HDA_AMP_MUTE : 0;
16621 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16622 HDA_AMP_MUTE, bits);
16623}
16624
16625static void alc663_g71v_unsol_event(struct hda_codec *codec,
16626 unsigned int res)
16627{
16628 switch (res >> 26) {
16629 case ALC880_HP_EVENT:
16630 alc663_g71v_hp_automute(codec);
16631 break;
16632 case ALC880_FRONT_EVENT:
16633 alc663_g71v_front_automute(codec);
16634 break;
16635 case ALC880_MIC_EVENT:
16636 alc_mic_automute(codec);
16637 break;
16638 }
16639}
16640
16641#define alc663_g71v_setup alc663_m51va_setup
16642
16643static void alc663_g71v_inithook(struct hda_codec *codec)
16644{
16645 alc663_g71v_front_automute(codec);
16646 alc663_g71v_hp_automute(codec);
16647 alc_mic_automute(codec);
16648}
16649
16650static void alc663_g50v_unsol_event(struct hda_codec *codec,
16651 unsigned int res)
16652{
16653 switch (res >> 26) {
16654 case ALC880_HP_EVENT:
16655 alc663_m51va_speaker_automute(codec);
16656 break;
16657 case ALC880_MIC_EVENT:
16658 alc_mic_automute(codec);
16659 break;
16660 }
16661}
16662
16663#define alc663_g50v_setup alc663_m51va_setup
16664
16665static void alc663_g50v_inithook(struct hda_codec *codec)
16666{
16667 alc663_m51va_speaker_automute(codec);
16668 alc_mic_automute(codec);
16669}
16670
16671static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16672 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16673 ALC262_HIPPO_MASTER_SWITCH,
16674
16675 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16676 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16677 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16678
16679 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16680 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16681 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16682 { } /* end */
16683};
16684
16685static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16686 /* Master Playback automatically created from Speaker and Headphone */
16687 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16688 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16689 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16690 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16691
16692 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16693 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16694 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16695
16696 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16697 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16698 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16699 { } /* end */
16700};
16701
16702#ifdef CONFIG_SND_HDA_POWER_SAVE
16703#define alc662_loopbacks alc880_loopbacks
16704#endif
16705
16706
16707/* pcm configuration: identical with ALC880 */
16708#define alc662_pcm_analog_playback alc880_pcm_analog_playback
16709#define alc662_pcm_analog_capture alc880_pcm_analog_capture
16710#define alc662_pcm_digital_playback alc880_pcm_digital_playback
16711#define alc662_pcm_digital_capture alc880_pcm_digital_capture
16712
16713/*
16714 * configuration and preset
16715 */
16716static const char *alc662_models[ALC662_MODEL_LAST] = {
16717 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16718 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16719 [ALC662_3ST_6ch] = "3stack-6ch",
16720 [ALC662_5ST_DIG] = "6stack-dig",
16721 [ALC662_LENOVO_101E] = "lenovo-101e",
16722 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16723 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16724 [ALC662_ECS] = "ecs",
16725 [ALC663_ASUS_M51VA] = "m51va",
16726 [ALC663_ASUS_G71V] = "g71v",
16727 [ALC663_ASUS_H13] = "h13",
16728 [ALC663_ASUS_G50V] = "g50v",
16729 [ALC663_ASUS_MODE1] = "asus-mode1",
16730 [ALC662_ASUS_MODE2] = "asus-mode2",
16731 [ALC663_ASUS_MODE3] = "asus-mode3",
16732 [ALC663_ASUS_MODE4] = "asus-mode4",
16733 [ALC663_ASUS_MODE5] = "asus-mode5",
16734 [ALC663_ASUS_MODE6] = "asus-mode6",
16735 [ALC272_DELL] = "dell",
16736 [ALC272_DELL_ZM1] = "dell-zm1",
16737 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16738 [ALC662_AUTO] = "auto",
16739};
16740
16741static struct snd_pci_quirk alc662_cfg_tbl[] = {
16742 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16743 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16744 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16745 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16746 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16747 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16748 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16749 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16750 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16751 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16752 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16753 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16754 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16755 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16756 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16757 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16758 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16759 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16760 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16761 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16762 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16763 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16764 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16765 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16766 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16767 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16768 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16769 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16770 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16771 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16772 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16773 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16774 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16775 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16776 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16777 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16778 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16779 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16780 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16781 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16782 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16783 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16784 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16785 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16786 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16787 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16788 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16789 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16790 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16791 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16792 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16793 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16794 ALC662_3ST_6ch_DIG),
16795 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
16796 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16797 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16798 ALC662_3ST_6ch_DIG),
16799 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16800 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16801 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16802 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16803 ALC662_3ST_6ch_DIG),
16804 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16805 ALC663_ASUS_H13),
16806 {}
16807};
16808
16809static struct alc_config_preset alc662_presets[] = {
16810 [ALC662_3ST_2ch_DIG] = {
16811 .mixers = { alc662_3ST_2ch_mixer },
16812 .init_verbs = { alc662_init_verbs },
16813 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16814 .dac_nids = alc662_dac_nids,
16815 .dig_out_nid = ALC662_DIGOUT_NID,
16816 .dig_in_nid = ALC662_DIGIN_NID,
16817 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16818 .channel_mode = alc662_3ST_2ch_modes,
16819 .input_mux = &alc662_capture_source,
16820 },
16821 [ALC662_3ST_6ch_DIG] = {
16822 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16823 .init_verbs = { alc662_init_verbs },
16824 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16825 .dac_nids = alc662_dac_nids,
16826 .dig_out_nid = ALC662_DIGOUT_NID,
16827 .dig_in_nid = ALC662_DIGIN_NID,
16828 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16829 .channel_mode = alc662_3ST_6ch_modes,
16830 .need_dac_fix = 1,
16831 .input_mux = &alc662_capture_source,
16832 },
16833 [ALC662_3ST_6ch] = {
16834 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16835 .init_verbs = { alc662_init_verbs },
16836 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16837 .dac_nids = alc662_dac_nids,
16838 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16839 .channel_mode = alc662_3ST_6ch_modes,
16840 .need_dac_fix = 1,
16841 .input_mux = &alc662_capture_source,
16842 },
16843 [ALC662_5ST_DIG] = {
16844 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16845 .init_verbs = { alc662_init_verbs },
16846 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16847 .dac_nids = alc662_dac_nids,
16848 .dig_out_nid = ALC662_DIGOUT_NID,
16849 .dig_in_nid = ALC662_DIGIN_NID,
16850 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16851 .channel_mode = alc662_5stack_modes,
16852 .input_mux = &alc662_capture_source,
16853 },
16854 [ALC662_LENOVO_101E] = {
16855 .mixers = { alc662_lenovo_101e_mixer },
16856 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16857 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16858 .dac_nids = alc662_dac_nids,
16859 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16860 .channel_mode = alc662_3ST_2ch_modes,
16861 .input_mux = &alc662_lenovo_101e_capture_source,
16862 .unsol_event = alc662_lenovo_101e_unsol_event,
16863 .init_hook = alc662_lenovo_101e_all_automute,
16864 },
16865 [ALC662_ASUS_EEEPC_P701] = {
16866 .mixers = { alc662_eeepc_p701_mixer },
16867 .init_verbs = { alc662_init_verbs,
16868 alc662_eeepc_sue_init_verbs },
16869 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16870 .dac_nids = alc662_dac_nids,
16871 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16872 .channel_mode = alc662_3ST_2ch_modes,
16873 .unsol_event = alc662_eeepc_unsol_event,
16874 .setup = alc662_eeepc_setup,
16875 .init_hook = alc662_eeepc_inithook,
16876 },
16877 [ALC662_ASUS_EEEPC_EP20] = {
16878 .mixers = { alc662_eeepc_ep20_mixer,
16879 alc662_chmode_mixer },
16880 .init_verbs = { alc662_init_verbs,
16881 alc662_eeepc_ep20_sue_init_verbs },
16882 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16883 .dac_nids = alc662_dac_nids,
16884 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16885 .channel_mode = alc662_3ST_6ch_modes,
16886 .input_mux = &alc662_lenovo_101e_capture_source,
16887 .unsol_event = alc662_eeepc_unsol_event,
16888 .setup = alc662_eeepc_ep20_setup,
16889 .init_hook = alc662_eeepc_ep20_inithook,
16890 },
16891 [ALC662_ECS] = {
16892 .mixers = { alc662_ecs_mixer },
16893 .init_verbs = { alc662_init_verbs,
16894 alc662_ecs_init_verbs },
16895 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16896 .dac_nids = alc662_dac_nids,
16897 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16898 .channel_mode = alc662_3ST_2ch_modes,
16899 .unsol_event = alc662_eeepc_unsol_event,
16900 .setup = alc662_eeepc_setup,
16901 .init_hook = alc662_eeepc_inithook,
16902 },
16903 [ALC663_ASUS_M51VA] = {
16904 .mixers = { alc663_m51va_mixer },
16905 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16906 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16907 .dac_nids = alc662_dac_nids,
16908 .dig_out_nid = ALC662_DIGOUT_NID,
16909 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16910 .channel_mode = alc662_3ST_2ch_modes,
16911 .unsol_event = alc663_m51va_unsol_event,
16912 .setup = alc663_m51va_setup,
16913 .init_hook = alc663_m51va_inithook,
16914 },
16915 [ALC663_ASUS_G71V] = {
16916 .mixers = { alc663_g71v_mixer },
16917 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16918 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16919 .dac_nids = alc662_dac_nids,
16920 .dig_out_nid = ALC662_DIGOUT_NID,
16921 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16922 .channel_mode = alc662_3ST_2ch_modes,
16923 .unsol_event = alc663_g71v_unsol_event,
16924 .setup = alc663_g71v_setup,
16925 .init_hook = alc663_g71v_inithook,
16926 },
16927 [ALC663_ASUS_H13] = {
16928 .mixers = { alc663_m51va_mixer },
16929 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16930 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16931 .dac_nids = alc662_dac_nids,
16932 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16933 .channel_mode = alc662_3ST_2ch_modes,
16934 .unsol_event = alc663_m51va_unsol_event,
16935 .init_hook = alc663_m51va_inithook,
16936 },
16937 [ALC663_ASUS_G50V] = {
16938 .mixers = { alc663_g50v_mixer },
16939 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16940 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16941 .dac_nids = alc662_dac_nids,
16942 .dig_out_nid = ALC662_DIGOUT_NID,
16943 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16944 .channel_mode = alc662_3ST_6ch_modes,
16945 .input_mux = &alc663_capture_source,
16946 .unsol_event = alc663_g50v_unsol_event,
16947 .setup = alc663_g50v_setup,
16948 .init_hook = alc663_g50v_inithook,
16949 },
16950 [ALC663_ASUS_MODE1] = {
16951 .mixers = { alc663_m51va_mixer },
16952 .cap_mixer = alc662_auto_capture_mixer,
16953 .init_verbs = { alc662_init_verbs,
16954 alc663_21jd_amic_init_verbs },
16955 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16956 .hp_nid = 0x03,
16957 .dac_nids = alc662_dac_nids,
16958 .dig_out_nid = ALC662_DIGOUT_NID,
16959 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16960 .channel_mode = alc662_3ST_2ch_modes,
16961 .unsol_event = alc663_mode1_unsol_event,
16962 .setup = alc663_mode1_setup,
16963 .init_hook = alc663_mode1_inithook,
16964 },
16965 [ALC662_ASUS_MODE2] = {
16966 .mixers = { alc662_1bjd_mixer },
16967 .cap_mixer = alc662_auto_capture_mixer,
16968 .init_verbs = { alc662_init_verbs,
16969 alc662_1bjd_amic_init_verbs },
16970 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16971 .dac_nids = alc662_dac_nids,
16972 .dig_out_nid = ALC662_DIGOUT_NID,
16973 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16974 .channel_mode = alc662_3ST_2ch_modes,
16975 .unsol_event = alc662_mode2_unsol_event,
16976 .setup = alc662_mode2_setup,
16977 .init_hook = alc662_mode2_inithook,
16978 },
16979 [ALC663_ASUS_MODE3] = {
16980 .mixers = { alc663_two_hp_m1_mixer },
16981 .cap_mixer = alc662_auto_capture_mixer,
16982 .init_verbs = { alc662_init_verbs,
16983 alc663_two_hp_amic_m1_init_verbs },
16984 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16985 .hp_nid = 0x03,
16986 .dac_nids = alc662_dac_nids,
16987 .dig_out_nid = ALC662_DIGOUT_NID,
16988 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16989 .channel_mode = alc662_3ST_2ch_modes,
16990 .unsol_event = alc663_mode3_unsol_event,
16991 .setup = alc663_mode3_setup,
16992 .init_hook = alc663_mode3_inithook,
16993 },
16994 [ALC663_ASUS_MODE4] = {
16995 .mixers = { alc663_asus_21jd_clfe_mixer },
16996 .cap_mixer = alc662_auto_capture_mixer,
16997 .init_verbs = { alc662_init_verbs,
16998 alc663_21jd_amic_init_verbs},
16999 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17000 .hp_nid = 0x03,
17001 .dac_nids = alc662_dac_nids,
17002 .dig_out_nid = ALC662_DIGOUT_NID,
17003 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17004 .channel_mode = alc662_3ST_2ch_modes,
17005 .unsol_event = alc663_mode4_unsol_event,
17006 .setup = alc663_mode4_setup,
17007 .init_hook = alc663_mode4_inithook,
17008 },
17009 [ALC663_ASUS_MODE5] = {
17010 .mixers = { alc663_asus_15jd_clfe_mixer },
17011 .cap_mixer = alc662_auto_capture_mixer,
17012 .init_verbs = { alc662_init_verbs,
17013 alc663_15jd_amic_init_verbs },
17014 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17015 .hp_nid = 0x03,
17016 .dac_nids = alc662_dac_nids,
17017 .dig_out_nid = ALC662_DIGOUT_NID,
17018 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17019 .channel_mode = alc662_3ST_2ch_modes,
17020 .unsol_event = alc663_mode5_unsol_event,
17021 .setup = alc663_mode5_setup,
17022 .init_hook = alc663_mode5_inithook,
17023 },
17024 [ALC663_ASUS_MODE6] = {
17025 .mixers = { alc663_two_hp_m2_mixer },
17026 .cap_mixer = alc662_auto_capture_mixer,
17027 .init_verbs = { alc662_init_verbs,
17028 alc663_two_hp_amic_m2_init_verbs },
17029 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17030 .hp_nid = 0x03,
17031 .dac_nids = alc662_dac_nids,
17032 .dig_out_nid = ALC662_DIGOUT_NID,
17033 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17034 .channel_mode = alc662_3ST_2ch_modes,
17035 .unsol_event = alc663_mode6_unsol_event,
17036 .setup = alc663_mode6_setup,
17037 .init_hook = alc663_mode6_inithook,
17038 },
17039 [ALC272_DELL] = {
17040 .mixers = { alc663_m51va_mixer },
17041 .cap_mixer = alc272_auto_capture_mixer,
17042 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
17043 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17044 .dac_nids = alc662_dac_nids,
17045 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17046 .adc_nids = alc272_adc_nids,
17047 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17048 .capsrc_nids = alc272_capsrc_nids,
17049 .channel_mode = alc662_3ST_2ch_modes,
17050 .unsol_event = alc663_m51va_unsol_event,
17051 .setup = alc663_m51va_setup,
17052 .init_hook = alc663_m51va_inithook,
17053 },
17054 [ALC272_DELL_ZM1] = {
17055 .mixers = { alc663_m51va_mixer },
17056 .cap_mixer = alc662_auto_capture_mixer,
17057 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
17058 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17059 .dac_nids = alc662_dac_nids,
17060 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17061 .adc_nids = alc662_adc_nids,
17062 .num_adc_nids = 1,
17063 .capsrc_nids = alc662_capsrc_nids,
17064 .channel_mode = alc662_3ST_2ch_modes,
17065 .unsol_event = alc663_m51va_unsol_event,
17066 .setup = alc663_m51va_setup,
17067 .init_hook = alc663_m51va_inithook,
17068 },
17069 [ALC272_SAMSUNG_NC10] = {
17070 .mixers = { alc272_nc10_mixer },
17071 .init_verbs = { alc662_init_verbs,
17072 alc663_21jd_amic_init_verbs },
17073 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17074 .dac_nids = alc272_dac_nids,
17075 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17076 .channel_mode = alc662_3ST_2ch_modes,
17077 /*.input_mux = &alc272_nc10_capture_source,*/
17078 .unsol_event = alc663_mode4_unsol_event,
17079 .setup = alc663_mode4_setup,
17080 .init_hook = alc663_mode4_inithook,
17081 },
17082};
17083
17084
17085/*
17086 * BIOS auto configuration
17087 */
17088
17089/* convert from MIX nid to DAC */
17090static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17091{
17092 if (nid == 0x0f)
17093 return 0x02;
17094 else if (nid >= 0x0c && nid <= 0x0e)
17095 return nid - 0x0c + 0x02;
17096 else
17097 return 0;
17098}
17099
17100/* get MIX nid connected to the given pin targeted to DAC */
17101static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17102 hda_nid_t dac)
17103{
17104 hda_nid_t mix[4];
17105 int i, num;
17106
17107 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17108 for (i = 0; i < num; i++) {
17109 if (alc662_mix_to_dac(mix[i]) == dac)
17110 return mix[i];
17111 }
17112 return 0;
17113}
17114
17115/* look for an empty DAC slot */
17116static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17117{
17118 struct alc_spec *spec = codec->spec;
17119 hda_nid_t srcs[5];
17120 int i, j, num;
17121
17122 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
17123 if (num < 0)
17124 return 0;
17125 for (i = 0; i < num; i++) {
17126 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
17127 if (!nid)
17128 continue;
17129 for (j = 0; j < spec->multiout.num_dacs; j++)
17130 if (spec->multiout.dac_nids[j] == nid)
17131 break;
17132 if (j >= spec->multiout.num_dacs)
17133 return nid;
17134 }
17135 return 0;
17136}
17137
17138/* fill in the dac_nids table from the parsed pin configuration */
17139static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17140 const struct auto_pin_cfg *cfg)
17141{
17142 struct alc_spec *spec = codec->spec;
17143 int i;
17144 hda_nid_t dac;
17145
17146 spec->multiout.dac_nids = spec->private_dac_nids;
17147 for (i = 0; i < cfg->line_outs; i++) {
17148 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
17149 if (!dac)
17150 continue;
17151 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
17152 }
17153 return 0;
17154}
17155
17156static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17157 hda_nid_t nid, unsigned int chs)
17158{
17159 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17160 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17161}
17162
17163static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17164 hda_nid_t nid, unsigned int chs)
17165{
17166 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17167 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17168}
17169
17170#define alc662_add_stereo_vol(spec, pfx, nid) \
17171 alc662_add_vol_ctl(spec, pfx, nid, 3)
17172#define alc662_add_stereo_sw(spec, pfx, nid) \
17173 alc662_add_sw_ctl(spec, pfx, nid, 3)
17174
17175/* add playback controls from the parsed DAC table */
17176static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
17177 const struct auto_pin_cfg *cfg)
17178{
17179 struct alc_spec *spec = codec->spec;
17180 static const char *chname[4] = {
17181 "Front", "Surround", NULL /*CLFE*/, "Side"
17182 };
17183 hda_nid_t nid, mix;
17184 int i, err;
17185
17186 for (i = 0; i < cfg->line_outs; i++) {
17187 nid = spec->multiout.dac_nids[i];
17188 if (!nid)
17189 continue;
17190 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
17191 if (!mix)
17192 continue;
17193 if (i == 2) {
17194 /* Center/LFE */
17195 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
17196 if (err < 0)
17197 return err;
17198 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
17199 if (err < 0)
17200 return err;
17201 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
17202 if (err < 0)
17203 return err;
17204 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
17205 if (err < 0)
17206 return err;
17207 } else {
17208 const char *pfx;
17209 if (cfg->line_outs == 1 &&
17210 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17211 if (cfg->hp_outs)
17212 pfx = "Speaker";
17213 else
17214 pfx = "PCM";
17215 } else
17216 pfx = chname[i];
17217 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17218 if (err < 0)
17219 return err;
17220 if (cfg->line_outs == 1 &&
17221 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17222 pfx = "Speaker";
17223 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17224 if (err < 0)
17225 return err;
17226 }
17227 }
17228 return 0;
17229}
17230
17231/* add playback controls for speaker and HP outputs */
17232/* return DAC nid if any new DAC is assigned */
17233static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
17234 const char *pfx)
17235{
17236 struct alc_spec *spec = codec->spec;
17237 hda_nid_t nid, mix;
17238 int err;
17239
17240 if (!pin)
17241 return 0;
17242 nid = alc662_look_for_dac(codec, pin);
17243 if (!nid) {
17244 /* the corresponding DAC is already occupied */
17245 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
17246 return 0; /* no way */
17247 /* create a switch only */
17248 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17249 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17250 }
17251
17252 mix = alc662_dac_to_mix(codec, pin, nid);
17253 if (!mix)
17254 return 0;
17255 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17256 if (err < 0)
17257 return err;
17258 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17259 if (err < 0)
17260 return err;
17261 return nid;
17262}
17263
17264/* create playback/capture controls for input pins */
17265#define alc662_auto_create_input_ctls \
17266 alc882_auto_create_input_ctls
17267
17268static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17269 hda_nid_t nid, int pin_type,
17270 hda_nid_t dac)
17271{
17272 int i, num;
17273 hda_nid_t srcs[4];
17274
17275 alc_set_pin_output(codec, nid, pin_type);
17276 /* need the manual connection? */
17277 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
17278 if (num <= 1)
17279 return;
17280 for (i = 0; i < num; i++) {
17281 if (alc662_mix_to_dac(srcs[i]) != dac)
17282 continue;
17283 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
17284 return;
17285 }
17286}
17287
17288static void alc662_auto_init_multi_out(struct hda_codec *codec)
17289{
17290 struct alc_spec *spec = codec->spec;
17291 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17292 int i;
17293
17294 for (i = 0; i <= HDA_SIDE; i++) {
17295 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17296 if (nid)
17297 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17298 spec->multiout.dac_nids[i]);
17299 }
17300}
17301
17302static void alc662_auto_init_hp_out(struct hda_codec *codec)
17303{
17304 struct alc_spec *spec = codec->spec;
17305 hda_nid_t pin;
17306
17307 pin = spec->autocfg.hp_pins[0];
17308 if (pin)
17309 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
17310 spec->multiout.hp_nid);
17311 pin = spec->autocfg.speaker_pins[0];
17312 if (pin)
17313 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
17314 spec->multiout.extra_out_nid[0]);
17315}
17316
17317#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17318
17319static void alc662_auto_init_analog_input(struct hda_codec *codec)
17320{
17321 struct alc_spec *spec = codec->spec;
17322 int i;
17323
17324 for (i = 0; i < AUTO_PIN_LAST; i++) {
17325 hda_nid_t nid = spec->autocfg.input_pins[i];
17326 if (alc_is_input_pin(codec, nid)) {
17327 alc_set_input_pin(codec, nid, i);
17328 if (nid != ALC662_PIN_CD_NID &&
17329 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17330 snd_hda_codec_write(codec, nid, 0,
17331 AC_VERB_SET_AMP_GAIN_MUTE,
17332 AMP_OUT_MUTE);
17333 }
17334 }
17335}
17336
17337#define alc662_auto_init_input_src alc882_auto_init_input_src
17338
17339static int alc662_parse_auto_config(struct hda_codec *codec)
17340{
17341 struct alc_spec *spec = codec->spec;
17342 int err;
17343 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17344
17345 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17346 alc662_ignore);
17347 if (err < 0)
17348 return err;
17349 if (!spec->autocfg.line_outs)
17350 return 0; /* can't find valid BIOS pin config */
17351
17352 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
17353 if (err < 0)
17354 return err;
17355 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
17356 if (err < 0)
17357 return err;
17358 err = alc662_auto_create_extra_out(codec,
17359 spec->autocfg.speaker_pins[0],
17360 "Speaker");
17361 if (err < 0)
17362 return err;
17363 if (err)
17364 spec->multiout.extra_out_nid[0] = err;
17365 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
17366 "Headphone");
17367 if (err < 0)
17368 return err;
17369 if (err)
17370 spec->multiout.hp_nid = err;
17371 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
17372 if (err < 0)
17373 return err;
17374
17375 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17376
17377 if (spec->autocfg.dig_outs)
17378 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17379
17380 if (spec->kctls.list)
17381 add_mixer(spec, spec->kctls.list);
17382
17383 spec->num_mux_defs = 1;
17384 spec->input_mux = &spec->private_imux[0];
17385
17386 add_verb(spec, alc662_auto_init_verbs);
17387 if (codec->vendor_id == 0x10ec0663)
17388 add_verb(spec, alc663_auto_init_verbs);
17389
17390 err = alc_auto_add_mic_boost(codec);
17391 if (err < 0)
17392 return err;
17393
17394 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17395
17396 return 1;
17397}
17398
17399/* additional initialization for auto-configuration model */
17400static void alc662_auto_init(struct hda_codec *codec)
17401{
17402 struct alc_spec *spec = codec->spec;
17403 alc662_auto_init_multi_out(codec);
17404 alc662_auto_init_hp_out(codec);
17405 alc662_auto_init_analog_input(codec);
17406 alc662_auto_init_input_src(codec);
17407 if (spec->unsol_event)
17408 alc_inithook(codec);
17409}
17410
17411static int patch_alc662(struct hda_codec *codec)
17412{
17413 struct alc_spec *spec;
17414 int err, board_config;
17415
17416 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17417 if (!spec)
17418 return -ENOMEM;
17419
17420 codec->spec = spec;
17421
17422 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17423
17424 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17425 alc662_models,
17426 alc662_cfg_tbl);
17427 if (board_config < 0) {
17428 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17429 codec->chip_name);
17430 board_config = ALC662_AUTO;
17431 }
17432
17433 if (board_config == ALC662_AUTO) {
17434 /* automatic parse from the BIOS config */
17435 err = alc662_parse_auto_config(codec);
17436 if (err < 0) {
17437 alc_free(codec);
17438 return err;
17439 } else if (!err) {
17440 printk(KERN_INFO
17441 "hda_codec: Cannot set up configuration "
17442 "from BIOS. Using base mode...\n");
17443 board_config = ALC662_3ST_2ch_DIG;
17444 }
17445 }
17446
17447 err = snd_hda_attach_beep_device(codec, 0x1);
17448 if (err < 0) {
17449 alc_free(codec);
17450 return err;
17451 }
17452
17453 if (board_config != ALC662_AUTO)
17454 setup_preset(codec, &alc662_presets[board_config]);
17455
17456 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17457 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17458
17459 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17460 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17461
17462 if (!spec->adc_nids) {
17463 spec->adc_nids = alc662_adc_nids;
17464 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17465 }
17466 if (!spec->capsrc_nids)
17467 spec->capsrc_nids = alc662_capsrc_nids;
17468
17469 if (!spec->cap_mixer)
17470 set_capture_mixer(codec);
17471 if (codec->vendor_id == 0x10ec0662)
17472 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17473 else
17474 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17475
17476 spec->vmaster_nid = 0x02;
17477
17478 codec->patch_ops = alc_patch_ops;
17479 if (board_config == ALC662_AUTO)
17480 spec->init_hook = alc662_auto_init;
17481#ifdef CONFIG_SND_HDA_POWER_SAVE
17482 if (!spec->loopback.amplist)
17483 spec->loopback.amplist = alc662_loopbacks;
17484#endif
17485 codec->proc_widget_hook = print_realtek_coef;
17486
17487 return 0;
17488}
17489
17490/*
17491 * patch entries
17492 */
17493static struct hda_codec_preset snd_hda_preset_realtek[] = {
17494 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17495 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17496 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17497 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17498 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17499 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17500 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17501 .patch = patch_alc861 },
17502 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17503 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17504 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17505 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17506 .patch = patch_alc882 },
17507 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17508 .patch = patch_alc662 },
17509 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17510 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17511 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17512 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17513 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17514 .patch = patch_alc882 },
17515 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17516 .patch = patch_alc882 },
17517 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17518 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17519 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17520 .patch = patch_alc882 },
17521 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17522 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17523 {} /* terminator */
17524};
17525
17526MODULE_ALIAS("snd-hda-codec-id:10ec*");
17527
17528MODULE_LICENSE("GPL");
17529MODULE_DESCRIPTION("Realtek HD-audio codec");
17530
17531static struct hda_codec_preset_list realtek_list = {
17532 .preset = snd_hda_preset_realtek,
17533 .owner = THIS_MODULE,
17534};
17535
17536static int __init patch_realtek_init(void)
17537{
17538 return snd_hda_add_codec_preset(&realtek_list);
17539}
17540
17541static void __exit patch_realtek_exit(void)
17542{
17543 snd_hda_delete_codec_preset(&realtek_list);
17544}
17545
17546module_init(patch_realtek_init)
17547module_exit(patch_realtek_exit)