]> git.ipfire.org Git - thirdparty/linux.git/blob - sound/pci/hda/patch_realtek.c
ALSA: HDA: Add position_fix=3 module option, and refactor related code
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
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 <sound/jack.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34 #include "hda_beep.h"
35
36 #define ALC880_FRONT_EVENT 0x01
37 #define ALC880_DCVOL_EVENT 0x02
38 #define ALC880_HP_EVENT 0x04
39 #define ALC880_MIC_EVENT 0x08
40
41 /* ALC880 board config type */
42 enum {
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
48 ALC880_Z71V,
49 ALC880_6ST,
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
55 ALC880_ASUS_DIG2,
56 ALC880_FUJITSU,
57 ALC880_UNIWILL_DIG,
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
62 ALC880_LG,
63 ALC880_LG_LW,
64 ALC880_MEDION_RIM,
65 #ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67 #endif
68 ALC880_AUTO,
69 ALC880_MODEL_LAST /* last tag */
70 };
71
72 /* ALC260 models */
73 enum {
74 ALC260_BASIC,
75 ALC260_HP,
76 ALC260_HP_DC7600,
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
79 ALC260_ACER,
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
82 ALC260_FAVORIT100,
83 #ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85 #endif
86 ALC260_AUTO,
87 ALC260_MODEL_LAST /* last tag */
88 };
89
90 /* ALC262 models */
91 enum {
92 ALC262_BASIC,
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
95 ALC262_FUJITSU,
96 ALC262_HP_BPC,
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
99 ALC262_HP_TC_T5735,
100 ALC262_HP_RP5700,
101 ALC262_BENQ_ED8,
102 ALC262_SONY_ASSAMD,
103 ALC262_BENQ_T31,
104 ALC262_ULTRA,
105 ALC262_LENOVO_3000,
106 ALC262_NEC,
107 ALC262_TOSHIBA_S06,
108 ALC262_TOSHIBA_RX1,
109 ALC262_TYAN,
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112 };
113
114 /* ALC268 models */
115 enum {
116 ALC267_QUANTA_IL1,
117 ALC268_3ST,
118 ALC268_TOSHIBA,
119 ALC268_ACER,
120 ALC268_ACER_DMIC,
121 ALC268_ACER_ASPIRE_ONE,
122 ALC268_DELL,
123 ALC268_ZEPTO,
124 #ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126 #endif
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129 };
130
131 /* ALC269 models */
132 enum {
133 ALC269_BASIC,
134 ALC269_QUANTA_FL1,
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
139 ALC269_FUJITSU,
140 ALC269_LIFEBOOK,
141 ALC271_ACER,
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144 };
145
146 /* ALC861 models */
147 enum {
148 ALC861_3ST,
149 ALC660_3ST,
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
152 ALC861_UNIWILL_M31,
153 ALC861_TOSHIBA,
154 ALC861_ASUS,
155 ALC861_ASUS_LAPTOP,
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158 };
159
160 /* ALC861-VD models */
161 enum {
162 ALC660VD_3ST,
163 ALC660VD_3ST_DIG,
164 ALC660VD_ASUS_V1S,
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
168 ALC861VD_LENOVO,
169 ALC861VD_DALLAS,
170 ALC861VD_HP,
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173 };
174
175 /* ALC662 models */
176 enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
182 ALC662_ASUS_EEEPC_P701,
183 ALC662_ASUS_EEEPC_EP20,
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
199 ALC272_SAMSUNG_NC10,
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202 };
203
204 /* ALC882 models */
205 enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
208 ALC882_ARIMA,
209 ALC882_W2JC,
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
212 ALC882_ASUS_A7M,
213 ALC885_MACPRO,
214 ALC885_MBA21,
215 ALC885_MBP3,
216 ALC885_MB5,
217 ALC885_MACMINI3,
218 ALC885_IMAC24,
219 ALC885_IMAC91,
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
226 ALC883_TARGA_8ch_DIG,
227 ALC883_ACER,
228 ALC883_ACER_ASPIRE,
229 ALC888_ACER_ASPIRE_4930G,
230 ALC888_ACER_ASPIRE_6530G,
231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G,
233 ALC883_MEDION,
234 ALC883_MEDION_MD2,
235 ALC883_MEDION_WIM2160,
236 ALC883_LAPTOP_EAPD,
237 ALC883_LENOVO_101E_2ch,
238 ALC883_LENOVO_NB0763,
239 ALC888_LENOVO_MS7195_DIG,
240 ALC888_LENOVO_SKY,
241 ALC883_HAIER_W66,
242 ALC888_3ST_HP,
243 ALC888_6ST_DELL,
244 ALC883_MITAC,
245 ALC883_CLEVO_M540R,
246 ALC883_CLEVO_M720,
247 ALC883_FUJITSU_PI2515,
248 ALC888_FUJITSU_XA3530,
249 ALC883_3ST_6ch_INTEL,
250 ALC889A_INTEL,
251 ALC889_INTEL,
252 ALC888_ASUS_M90V,
253 ALC888_ASUS_EEE1601,
254 ALC889A_MB31,
255 ALC1200_ASUS_P5Q,
256 ALC883_SONY_VAIO_TT,
257 ALC882_AUTO,
258 ALC882_MODEL_LAST,
259 };
260
261 /* ALC680 models */
262 enum {
263 ALC680_BASE,
264 ALC680_AUTO,
265 ALC680_MODEL_LAST,
266 };
267
268 /* for GPIO Poll */
269 #define GPIO_MASK 0x03
270
271 /* extra amp-initialization sequence types */
272 enum {
273 ALC_INIT_NONE,
274 ALC_INIT_DEFAULT,
275 ALC_INIT_GPIO1,
276 ALC_INIT_GPIO2,
277 ALC_INIT_GPIO3,
278 };
279
280 struct alc_mic_route {
281 hda_nid_t pin;
282 unsigned char mux_idx;
283 unsigned char amix_idx;
284 };
285
286 struct alc_jack {
287 hda_nid_t nid;
288 int type;
289 struct snd_jack *jack;
290 };
291
292 #define MUX_IDX_UNDEF ((unsigned char)-1)
293
294 struct alc_customize_define {
295 unsigned int sku_cfg;
296 unsigned char port_connectivity;
297 unsigned char check_sum;
298 unsigned char customization;
299 unsigned char external_amp;
300 unsigned int enable_pcbeep:1;
301 unsigned int platform_type:1;
302 unsigned int swap:1;
303 unsigned int override:1;
304 };
305
306 struct alc_spec {
307 /* codec parameterization */
308 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
309 unsigned int num_mixers;
310 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
311 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
312
313 const struct hda_verb *init_verbs[10]; /* initialization verbs
314 * don't forget NULL
315 * termination!
316 */
317 unsigned int num_init_verbs;
318
319 char stream_name_analog[32]; /* analog PCM stream */
320 struct hda_pcm_stream *stream_analog_playback;
321 struct hda_pcm_stream *stream_analog_capture;
322 struct hda_pcm_stream *stream_analog_alt_playback;
323 struct hda_pcm_stream *stream_analog_alt_capture;
324
325 char stream_name_digital[32]; /* digital PCM stream */
326 struct hda_pcm_stream *stream_digital_playback;
327 struct hda_pcm_stream *stream_digital_capture;
328
329 /* playback */
330 struct hda_multi_out multiout; /* playback set-up
331 * max_channels, dacs must be set
332 * dig_out_nid and hp_nid are optional
333 */
334 hda_nid_t alt_dac_nid;
335 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
336 int dig_out_type;
337
338 /* capture */
339 unsigned int num_adc_nids;
340 hda_nid_t *adc_nids;
341 hda_nid_t *capsrc_nids;
342 hda_nid_t dig_in_nid; /* digital-in NID; optional */
343
344 /* capture setup for dynamic dual-adc switch */
345 unsigned int cur_adc_idx;
346 hda_nid_t cur_adc;
347 unsigned int cur_adc_stream_tag;
348 unsigned int cur_adc_format;
349
350 /* capture source */
351 unsigned int num_mux_defs;
352 const struct hda_input_mux *input_mux;
353 unsigned int cur_mux[3];
354 struct alc_mic_route ext_mic;
355 struct alc_mic_route int_mic;
356
357 /* channel model */
358 const struct hda_channel_mode *channel_mode;
359 int num_channel_mode;
360 int need_dac_fix;
361 int const_channel_count;
362 int ext_channel_count;
363
364 /* PCM information */
365 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
366
367 /* jack detection */
368 struct snd_array jacks;
369
370 /* dynamic controls, init_verbs and input_mux */
371 struct auto_pin_cfg autocfg;
372 struct alc_customize_define cdefine;
373 struct snd_array kctls;
374 struct hda_input_mux private_imux[3];
375 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
376 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
377 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
378
379 /* hooks */
380 void (*init_hook)(struct hda_codec *codec);
381 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
382 #ifdef CONFIG_SND_HDA_POWER_SAVE
383 void (*power_hook)(struct hda_codec *codec);
384 #endif
385
386 /* for pin sensing */
387 unsigned int sense_updated: 1;
388 unsigned int jack_present: 1;
389 unsigned int master_sw: 1;
390 unsigned int auto_mic:1;
391
392 /* other flags */
393 unsigned int no_analog :1; /* digital I/O only */
394 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
395 int init_amp;
396 int codec_variant; /* flag for other variants */
397
398 /* for virtual master */
399 hda_nid_t vmaster_nid;
400 #ifdef CONFIG_SND_HDA_POWER_SAVE
401 struct hda_loopback_check loopback;
402 #endif
403
404 /* for PLL fix */
405 hda_nid_t pll_nid;
406 unsigned int pll_coef_idx, pll_coef_bit;
407 };
408
409 /*
410 * configuration template - to be copied to the spec instance
411 */
412 struct alc_config_preset {
413 struct snd_kcontrol_new *mixers[5]; /* should be identical size
414 * with spec
415 */
416 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
417 const struct hda_verb *init_verbs[5];
418 unsigned int num_dacs;
419 hda_nid_t *dac_nids;
420 hda_nid_t dig_out_nid; /* optional */
421 hda_nid_t hp_nid; /* optional */
422 hda_nid_t *slave_dig_outs;
423 unsigned int num_adc_nids;
424 hda_nid_t *adc_nids;
425 hda_nid_t *capsrc_nids;
426 hda_nid_t dig_in_nid;
427 unsigned int num_channel_mode;
428 const struct hda_channel_mode *channel_mode;
429 int need_dac_fix;
430 int const_channel_count;
431 unsigned int num_mux_defs;
432 const struct hda_input_mux *input_mux;
433 void (*unsol_event)(struct hda_codec *, unsigned int);
434 void (*setup)(struct hda_codec *);
435 void (*init_hook)(struct hda_codec *);
436 #ifdef CONFIG_SND_HDA_POWER_SAVE
437 struct hda_amp_list *loopbacks;
438 void (*power_hook)(struct hda_codec *codec);
439 #endif
440 };
441
442
443 /*
444 * input MUX handling
445 */
446 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
447 struct snd_ctl_elem_info *uinfo)
448 {
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 struct alc_spec *spec = codec->spec;
451 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
452 if (mux_idx >= spec->num_mux_defs)
453 mux_idx = 0;
454 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
455 mux_idx = 0;
456 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
457 }
458
459 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_value *ucontrol)
461 {
462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
463 struct alc_spec *spec = codec->spec;
464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
465
466 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
467 return 0;
468 }
469
470 static int alc_mux_enum_put(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 const struct hda_input_mux *imux;
476 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
477 unsigned int mux_idx;
478 hda_nid_t nid = spec->capsrc_nids ?
479 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
480 unsigned int type;
481
482 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
483 imux = &spec->input_mux[mux_idx];
484 if (!imux->num_items && mux_idx > 0)
485 imux = &spec->input_mux[0];
486
487 type = get_wcaps_type(get_wcaps(codec, nid));
488 if (type == AC_WID_AUD_MIX) {
489 /* Matrix-mixer style (e.g. ALC882) */
490 unsigned int *cur_val = &spec->cur_mux[adc_idx];
491 unsigned int i, idx;
492
493 idx = ucontrol->value.enumerated.item[0];
494 if (idx >= imux->num_items)
495 idx = imux->num_items - 1;
496 if (*cur_val == idx)
497 return 0;
498 for (i = 0; i < imux->num_items; i++) {
499 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
501 imux->items[i].index,
502 HDA_AMP_MUTE, v);
503 }
504 *cur_val = idx;
505 return 1;
506 } else {
507 /* MUX style (e.g. ALC880) */
508 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
509 &spec->cur_mux[adc_idx]);
510 }
511 }
512
513 /*
514 * channel mode setting
515 */
516 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_info *uinfo)
518 {
519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
520 struct alc_spec *spec = codec->spec;
521 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
522 spec->num_channel_mode);
523 }
524
525 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
527 {
528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
529 struct alc_spec *spec = codec->spec;
530 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
531 spec->num_channel_mode,
532 spec->ext_channel_count);
533 }
534
535 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
536 struct snd_ctl_elem_value *ucontrol)
537 {
538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
539 struct alc_spec *spec = codec->spec;
540 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
541 spec->num_channel_mode,
542 &spec->ext_channel_count);
543 if (err >= 0 && !spec->const_channel_count) {
544 spec->multiout.max_channels = spec->ext_channel_count;
545 if (spec->need_dac_fix)
546 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
547 }
548 return err;
549 }
550
551 /*
552 * Control the mode of pin widget settings via the mixer. "pc" is used
553 * instead of "%" to avoid consequences of accidently treating the % as
554 * being part of a format specifier. Maximum allowed length of a value is
555 * 63 characters plus NULL terminator.
556 *
557 * Note: some retasking pin complexes seem to ignore requests for input
558 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
559 * are requested. Therefore order this list so that this behaviour will not
560 * cause problems when mixer clients move through the enum sequentially.
561 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
562 * March 2006.
563 */
564 static char *alc_pin_mode_names[] = {
565 "Mic 50pc bias", "Mic 80pc bias",
566 "Line in", "Line out", "Headphone out",
567 };
568 static unsigned char alc_pin_mode_values[] = {
569 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
570 };
571 /* The control can present all 5 options, or it can limit the options based
572 * in the pin being assumed to be exclusively an input or an output pin. In
573 * addition, "input" pins may or may not process the mic bias option
574 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
575 * accept requests for bias as of chip versions up to March 2006) and/or
576 * wiring in the computer.
577 */
578 #define ALC_PIN_DIR_IN 0x00
579 #define ALC_PIN_DIR_OUT 0x01
580 #define ALC_PIN_DIR_INOUT 0x02
581 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
582 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
583
584 /* Info about the pin modes supported by the different pin direction modes.
585 * For each direction the minimum and maximum values are given.
586 */
587 static signed char alc_pin_mode_dir_info[5][2] = {
588 { 0, 2 }, /* ALC_PIN_DIR_IN */
589 { 3, 4 }, /* ALC_PIN_DIR_OUT */
590 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
591 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
592 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
593 };
594 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
595 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
596 #define alc_pin_mode_n_items(_dir) \
597 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
598
599 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
600 struct snd_ctl_elem_info *uinfo)
601 {
602 unsigned int item_num = uinfo->value.enumerated.item;
603 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
604
605 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
606 uinfo->count = 1;
607 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
608
609 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
610 item_num = alc_pin_mode_min(dir);
611 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
612 return 0;
613 }
614
615 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
616 struct snd_ctl_elem_value *ucontrol)
617 {
618 unsigned int i;
619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
620 hda_nid_t nid = kcontrol->private_value & 0xffff;
621 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
622 long *valp = ucontrol->value.integer.value;
623 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
624 AC_VERB_GET_PIN_WIDGET_CONTROL,
625 0x00);
626
627 /* Find enumerated value for current pinctl setting */
628 i = alc_pin_mode_min(dir);
629 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
630 i++;
631 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
632 return 0;
633 }
634
635 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *ucontrol)
637 {
638 signed int change;
639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
640 hda_nid_t nid = kcontrol->private_value & 0xffff;
641 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
642 long val = *ucontrol->value.integer.value;
643 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
644 AC_VERB_GET_PIN_WIDGET_CONTROL,
645 0x00);
646
647 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
648 val = alc_pin_mode_min(dir);
649
650 change = pinctl != alc_pin_mode_values[val];
651 if (change) {
652 /* Set pin mode to that requested */
653 snd_hda_codec_write_cache(codec, nid, 0,
654 AC_VERB_SET_PIN_WIDGET_CONTROL,
655 alc_pin_mode_values[val]);
656
657 /* Also enable the retasking pin's input/output as required
658 * for the requested pin mode. Enum values of 2 or less are
659 * input modes.
660 *
661 * Dynamically switching the input/output buffers probably
662 * reduces noise slightly (particularly on input) so we'll
663 * do it. However, having both input and output buffers
664 * enabled simultaneously doesn't seem to be problematic if
665 * this turns out to be necessary in the future.
666 */
667 if (val <= 2) {
668 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
669 HDA_AMP_MUTE, HDA_AMP_MUTE);
670 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
671 HDA_AMP_MUTE, 0);
672 } else {
673 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
674 HDA_AMP_MUTE, HDA_AMP_MUTE);
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
676 HDA_AMP_MUTE, 0);
677 }
678 }
679 return change;
680 }
681
682 #define ALC_PIN_MODE(xname, nid, dir) \
683 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
684 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
685 .info = alc_pin_mode_info, \
686 .get = alc_pin_mode_get, \
687 .put = alc_pin_mode_put, \
688 .private_value = nid | (dir<<16) }
689
690 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
691 * together using a mask with more than one bit set. This control is
692 * currently used only by the ALC260 test model. At this stage they are not
693 * needed for any "production" models.
694 */
695 #ifdef CONFIG_SND_DEBUG
696 #define alc_gpio_data_info snd_ctl_boolean_mono_info
697
698 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
699 struct snd_ctl_elem_value *ucontrol)
700 {
701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
702 hda_nid_t nid = kcontrol->private_value & 0xffff;
703 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
704 long *valp = ucontrol->value.integer.value;
705 unsigned int val = snd_hda_codec_read(codec, nid, 0,
706 AC_VERB_GET_GPIO_DATA, 0x00);
707
708 *valp = (val & mask) != 0;
709 return 0;
710 }
711 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
713 {
714 signed int change;
715 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
716 hda_nid_t nid = kcontrol->private_value & 0xffff;
717 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
718 long val = *ucontrol->value.integer.value;
719 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
720 AC_VERB_GET_GPIO_DATA,
721 0x00);
722
723 /* Set/unset the masked GPIO bit(s) as needed */
724 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
725 if (val == 0)
726 gpio_data &= ~mask;
727 else
728 gpio_data |= mask;
729 snd_hda_codec_write_cache(codec, nid, 0,
730 AC_VERB_SET_GPIO_DATA, gpio_data);
731
732 return change;
733 }
734 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
735 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
737 .info = alc_gpio_data_info, \
738 .get = alc_gpio_data_get, \
739 .put = alc_gpio_data_put, \
740 .private_value = nid | (mask<<16) }
741 #endif /* CONFIG_SND_DEBUG */
742
743 /* A switch control to allow the enabling of the digital IO pins on the
744 * ALC260. This is incredibly simplistic; the intention of this control is
745 * to provide something in the test model allowing digital outputs to be
746 * identified if present. If models are found which can utilise these
747 * outputs a more complete mixer control can be devised for those models if
748 * necessary.
749 */
750 #ifdef CONFIG_SND_DEBUG
751 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
752
753 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
754 struct snd_ctl_elem_value *ucontrol)
755 {
756 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
757 hda_nid_t nid = kcontrol->private_value & 0xffff;
758 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
759 long *valp = ucontrol->value.integer.value;
760 unsigned int val = snd_hda_codec_read(codec, nid, 0,
761 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
762
763 *valp = (val & mask) != 0;
764 return 0;
765 }
766 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
767 struct snd_ctl_elem_value *ucontrol)
768 {
769 signed int change;
770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
771 hda_nid_t nid = kcontrol->private_value & 0xffff;
772 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
773 long val = *ucontrol->value.integer.value;
774 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
775 AC_VERB_GET_DIGI_CONVERT_1,
776 0x00);
777
778 /* Set/unset the masked control bit(s) as needed */
779 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
780 if (val==0)
781 ctrl_data &= ~mask;
782 else
783 ctrl_data |= mask;
784 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
785 ctrl_data);
786
787 return change;
788 }
789 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
791 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
792 .info = alc_spdif_ctrl_info, \
793 .get = alc_spdif_ctrl_get, \
794 .put = alc_spdif_ctrl_put, \
795 .private_value = nid | (mask<<16) }
796 #endif /* CONFIG_SND_DEBUG */
797
798 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
799 * Again, this is only used in the ALC26x test models to help identify when
800 * the EAPD line must be asserted for features to work.
801 */
802 #ifdef CONFIG_SND_DEBUG
803 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
804
805 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
806 struct snd_ctl_elem_value *ucontrol)
807 {
808 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
809 hda_nid_t nid = kcontrol->private_value & 0xffff;
810 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
811 long *valp = ucontrol->value.integer.value;
812 unsigned int val = snd_hda_codec_read(codec, nid, 0,
813 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
814
815 *valp = (val & mask) != 0;
816 return 0;
817 }
818
819 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
820 struct snd_ctl_elem_value *ucontrol)
821 {
822 int change;
823 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
824 hda_nid_t nid = kcontrol->private_value & 0xffff;
825 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
826 long val = *ucontrol->value.integer.value;
827 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
828 AC_VERB_GET_EAPD_BTLENABLE,
829 0x00);
830
831 /* Set/unset the masked control bit(s) as needed */
832 change = (!val ? 0 : mask) != (ctrl_data & mask);
833 if (!val)
834 ctrl_data &= ~mask;
835 else
836 ctrl_data |= mask;
837 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
838 ctrl_data);
839
840 return change;
841 }
842
843 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
844 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
845 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
846 .info = alc_eapd_ctrl_info, \
847 .get = alc_eapd_ctrl_get, \
848 .put = alc_eapd_ctrl_put, \
849 .private_value = nid | (mask<<16) }
850 #endif /* CONFIG_SND_DEBUG */
851
852 /*
853 * set up the input pin config (depending on the given auto-pin type)
854 */
855 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
856 int auto_pin_type)
857 {
858 unsigned int val = PIN_IN;
859
860 if (auto_pin_type == AUTO_PIN_MIC) {
861 unsigned int pincap;
862 unsigned int oldval;
863 oldval = snd_hda_codec_read(codec, nid, 0,
864 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
865 pincap = snd_hda_query_pin_caps(codec, nid);
866 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
867 /* if the default pin setup is vref50, we give it priority */
868 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
869 val = PIN_VREF80;
870 else if (pincap & AC_PINCAP_VREF_50)
871 val = PIN_VREF50;
872 else if (pincap & AC_PINCAP_VREF_100)
873 val = PIN_VREF100;
874 else if (pincap & AC_PINCAP_VREF_GRD)
875 val = PIN_VREFGRD;
876 }
877 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
878 }
879
880 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
881 {
882 struct alc_spec *spec = codec->spec;
883 struct auto_pin_cfg *cfg = &spec->autocfg;
884
885 if (!cfg->line_outs) {
886 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
887 cfg->line_out_pins[cfg->line_outs])
888 cfg->line_outs++;
889 }
890 if (!cfg->speaker_outs) {
891 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
892 cfg->speaker_pins[cfg->speaker_outs])
893 cfg->speaker_outs++;
894 }
895 if (!cfg->hp_outs) {
896 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
897 cfg->hp_pins[cfg->hp_outs])
898 cfg->hp_outs++;
899 }
900 }
901
902 /*
903 */
904 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
905 {
906 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
907 return;
908 spec->mixers[spec->num_mixers++] = mix;
909 }
910
911 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
912 {
913 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
914 return;
915 spec->init_verbs[spec->num_init_verbs++] = verb;
916 }
917
918 /*
919 * set up from the preset table
920 */
921 static void setup_preset(struct hda_codec *codec,
922 const struct alc_config_preset *preset)
923 {
924 struct alc_spec *spec = codec->spec;
925 int i;
926
927 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
928 add_mixer(spec, preset->mixers[i]);
929 spec->cap_mixer = preset->cap_mixer;
930 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
931 i++)
932 add_verb(spec, preset->init_verbs[i]);
933
934 spec->channel_mode = preset->channel_mode;
935 spec->num_channel_mode = preset->num_channel_mode;
936 spec->need_dac_fix = preset->need_dac_fix;
937 spec->const_channel_count = preset->const_channel_count;
938
939 if (preset->const_channel_count)
940 spec->multiout.max_channels = preset->const_channel_count;
941 else
942 spec->multiout.max_channels = spec->channel_mode[0].channels;
943 spec->ext_channel_count = spec->channel_mode[0].channels;
944
945 spec->multiout.num_dacs = preset->num_dacs;
946 spec->multiout.dac_nids = preset->dac_nids;
947 spec->multiout.dig_out_nid = preset->dig_out_nid;
948 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
949 spec->multiout.hp_nid = preset->hp_nid;
950
951 spec->num_mux_defs = preset->num_mux_defs;
952 if (!spec->num_mux_defs)
953 spec->num_mux_defs = 1;
954 spec->input_mux = preset->input_mux;
955
956 spec->num_adc_nids = preset->num_adc_nids;
957 spec->adc_nids = preset->adc_nids;
958 spec->capsrc_nids = preset->capsrc_nids;
959 spec->dig_in_nid = preset->dig_in_nid;
960
961 spec->unsol_event = preset->unsol_event;
962 spec->init_hook = preset->init_hook;
963 #ifdef CONFIG_SND_HDA_POWER_SAVE
964 spec->power_hook = preset->power_hook;
965 spec->loopback.amplist = preset->loopbacks;
966 #endif
967
968 if (preset->setup)
969 preset->setup(codec);
970
971 alc_fixup_autocfg_pin_nums(codec);
972 }
973
974 /* Enable GPIO mask and set output */
975 static struct hda_verb alc_gpio1_init_verbs[] = {
976 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
977 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
978 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
979 { }
980 };
981
982 static struct hda_verb alc_gpio2_init_verbs[] = {
983 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
985 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
986 { }
987 };
988
989 static struct hda_verb alc_gpio3_init_verbs[] = {
990 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
992 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
993 { }
994 };
995
996 /*
997 * Fix hardware PLL issue
998 * On some codecs, the analog PLL gating control must be off while
999 * the default value is 1.
1000 */
1001 static void alc_fix_pll(struct hda_codec *codec)
1002 {
1003 struct alc_spec *spec = codec->spec;
1004 unsigned int val;
1005
1006 if (!spec->pll_nid)
1007 return;
1008 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1009 spec->pll_coef_idx);
1010 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1011 AC_VERB_GET_PROC_COEF, 0);
1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1013 spec->pll_coef_idx);
1014 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1015 val & ~(1 << spec->pll_coef_bit));
1016 }
1017
1018 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1019 unsigned int coef_idx, unsigned int coef_bit)
1020 {
1021 struct alc_spec *spec = codec->spec;
1022 spec->pll_nid = nid;
1023 spec->pll_coef_idx = coef_idx;
1024 spec->pll_coef_bit = coef_bit;
1025 alc_fix_pll(codec);
1026 }
1027
1028 #ifdef CONFIG_SND_HDA_INPUT_JACK
1029 static void alc_free_jack_priv(struct snd_jack *jack)
1030 {
1031 struct alc_jack *jacks = jack->private_data;
1032 jacks->nid = 0;
1033 jacks->jack = NULL;
1034 }
1035
1036 static int alc_add_jack(struct hda_codec *codec,
1037 hda_nid_t nid, int type)
1038 {
1039 struct alc_spec *spec;
1040 struct alc_jack *jack;
1041 const char *name;
1042 int err;
1043
1044 spec = codec->spec;
1045 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1046 jack = snd_array_new(&spec->jacks);
1047 if (!jack)
1048 return -ENOMEM;
1049
1050 jack->nid = nid;
1051 jack->type = type;
1052 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1053
1054 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1055 if (err < 0)
1056 return err;
1057 jack->jack->private_data = jack;
1058 jack->jack->private_free = alc_free_jack_priv;
1059 return 0;
1060 }
1061
1062 static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1063 {
1064 struct alc_spec *spec = codec->spec;
1065 struct alc_jack *jacks = spec->jacks.list;
1066
1067 if (jacks) {
1068 int i;
1069 for (i = 0; i < spec->jacks.used; i++) {
1070 if (jacks->nid == nid) {
1071 unsigned int present;
1072 present = snd_hda_jack_detect(codec, nid);
1073
1074 present = (present) ? jacks->type : 0;
1075
1076 snd_jack_report(jacks->jack, present);
1077 }
1078 jacks++;
1079 }
1080 }
1081 }
1082
1083 static int alc_init_jacks(struct hda_codec *codec)
1084 {
1085 struct alc_spec *spec = codec->spec;
1086 int err;
1087 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1088 unsigned int mic_nid = spec->ext_mic.pin;
1089
1090 if (hp_nid) {
1091 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1092 if (err < 0)
1093 return err;
1094 alc_report_jack(codec, hp_nid);
1095 }
1096
1097 if (mic_nid) {
1098 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1099 if (err < 0)
1100 return err;
1101 alc_report_jack(codec, mic_nid);
1102 }
1103
1104 return 0;
1105 }
1106 #else
1107 static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1108 {
1109 }
1110
1111 static inline int alc_init_jacks(struct hda_codec *codec)
1112 {
1113 return 0;
1114 }
1115 #endif
1116
1117 static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1118 {
1119 struct alc_spec *spec = codec->spec;
1120 unsigned int mute;
1121 hda_nid_t nid;
1122 int i;
1123
1124 spec->jack_present = 0;
1125 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1126 nid = spec->autocfg.hp_pins[i];
1127 if (!nid)
1128 break;
1129 if (snd_hda_jack_detect(codec, nid)) {
1130 spec->jack_present = 1;
1131 break;
1132 }
1133 alc_report_jack(codec, spec->autocfg.hp_pins[i]);
1134 }
1135
1136 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1137 /* Toggle internal speakers muting */
1138 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1139 nid = spec->autocfg.speaker_pins[i];
1140 if (!nid)
1141 break;
1142 if (pinctl) {
1143 snd_hda_codec_write(codec, nid, 0,
1144 AC_VERB_SET_PIN_WIDGET_CONTROL,
1145 spec->jack_present ? 0 : PIN_OUT);
1146 } else {
1147 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1148 HDA_AMP_MUTE, mute);
1149 }
1150 }
1151 }
1152
1153 static void alc_automute_pin(struct hda_codec *codec)
1154 {
1155 alc_automute_speaker(codec, 1);
1156 }
1157
1158 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1159 hda_nid_t nid)
1160 {
1161 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1162 int i, nums;
1163
1164 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1165 for (i = 0; i < nums; i++)
1166 if (conn[i] == nid)
1167 return i;
1168 return -1;
1169 }
1170
1171 /* switch the current ADC according to the jack state */
1172 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1173 {
1174 struct alc_spec *spec = codec->spec;
1175 unsigned int present;
1176 hda_nid_t new_adc;
1177
1178 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1179 if (present)
1180 spec->cur_adc_idx = 1;
1181 else
1182 spec->cur_adc_idx = 0;
1183 new_adc = spec->adc_nids[spec->cur_adc_idx];
1184 if (spec->cur_adc && spec->cur_adc != new_adc) {
1185 /* stream is running, let's swap the current ADC */
1186 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1187 spec->cur_adc = new_adc;
1188 snd_hda_codec_setup_stream(codec, new_adc,
1189 spec->cur_adc_stream_tag, 0,
1190 spec->cur_adc_format);
1191 }
1192 }
1193
1194 static void alc_mic_automute(struct hda_codec *codec)
1195 {
1196 struct alc_spec *spec = codec->spec;
1197 struct alc_mic_route *dead, *alive;
1198 unsigned int present, type;
1199 hda_nid_t cap_nid;
1200
1201 if (!spec->auto_mic)
1202 return;
1203 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1204 return;
1205 if (snd_BUG_ON(!spec->adc_nids))
1206 return;
1207
1208 if (spec->dual_adc_switch) {
1209 alc_dual_mic_adc_auto_switch(codec);
1210 return;
1211 }
1212
1213 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1214
1215 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1216 if (present) {
1217 alive = &spec->ext_mic;
1218 dead = &spec->int_mic;
1219 } else {
1220 alive = &spec->int_mic;
1221 dead = &spec->ext_mic;
1222 }
1223
1224 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1225 if (type == AC_WID_AUD_MIX) {
1226 /* Matrix-mixer style (e.g. ALC882) */
1227 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1228 alive->mux_idx,
1229 HDA_AMP_MUTE, 0);
1230 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1231 dead->mux_idx,
1232 HDA_AMP_MUTE, HDA_AMP_MUTE);
1233 } else {
1234 /* MUX style (e.g. ALC880) */
1235 snd_hda_codec_write_cache(codec, cap_nid, 0,
1236 AC_VERB_SET_CONNECT_SEL,
1237 alive->mux_idx);
1238 }
1239 alc_report_jack(codec, spec->ext_mic.pin);
1240
1241 /* FIXME: analog mixer */
1242 }
1243
1244 /* unsolicited event for HP jack sensing */
1245 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1246 {
1247 if (codec->vendor_id == 0x10ec0880)
1248 res >>= 28;
1249 else
1250 res >>= 26;
1251 switch (res) {
1252 case ALC880_HP_EVENT:
1253 alc_automute_pin(codec);
1254 break;
1255 case ALC880_MIC_EVENT:
1256 alc_mic_automute(codec);
1257 break;
1258 }
1259 }
1260
1261 static void alc_inithook(struct hda_codec *codec)
1262 {
1263 alc_automute_pin(codec);
1264 alc_mic_automute(codec);
1265 }
1266
1267 /* additional initialization for ALC888 variants */
1268 static void alc888_coef_init(struct hda_codec *codec)
1269 {
1270 unsigned int tmp;
1271
1272 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1273 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1274 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1275 if ((tmp & 0xf0) == 0x20)
1276 /* alc888S-VC */
1277 snd_hda_codec_read(codec, 0x20, 0,
1278 AC_VERB_SET_PROC_COEF, 0x830);
1279 else
1280 /* alc888-VB */
1281 snd_hda_codec_read(codec, 0x20, 0,
1282 AC_VERB_SET_PROC_COEF, 0x3030);
1283 }
1284
1285 static void alc889_coef_init(struct hda_codec *codec)
1286 {
1287 unsigned int tmp;
1288
1289 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1290 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1291 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1292 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1293 }
1294
1295 /* turn on/off EAPD control (only if available) */
1296 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1297 {
1298 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1299 return;
1300 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1301 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1302 on ? 2 : 0);
1303 }
1304
1305 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1306 {
1307 unsigned int tmp;
1308
1309 switch (type) {
1310 case ALC_INIT_GPIO1:
1311 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1312 break;
1313 case ALC_INIT_GPIO2:
1314 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1315 break;
1316 case ALC_INIT_GPIO3:
1317 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1318 break;
1319 case ALC_INIT_DEFAULT:
1320 switch (codec->vendor_id) {
1321 case 0x10ec0260:
1322 set_eapd(codec, 0x0f, 1);
1323 set_eapd(codec, 0x10, 1);
1324 break;
1325 case 0x10ec0262:
1326 case 0x10ec0267:
1327 case 0x10ec0268:
1328 case 0x10ec0269:
1329 case 0x10ec0270:
1330 case 0x10ec0272:
1331 case 0x10ec0660:
1332 case 0x10ec0662:
1333 case 0x10ec0663:
1334 case 0x10ec0862:
1335 case 0x10ec0889:
1336 set_eapd(codec, 0x14, 1);
1337 set_eapd(codec, 0x15, 1);
1338 break;
1339 }
1340 switch (codec->vendor_id) {
1341 case 0x10ec0260:
1342 snd_hda_codec_write(codec, 0x1a, 0,
1343 AC_VERB_SET_COEF_INDEX, 7);
1344 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1345 AC_VERB_GET_PROC_COEF, 0);
1346 snd_hda_codec_write(codec, 0x1a, 0,
1347 AC_VERB_SET_COEF_INDEX, 7);
1348 snd_hda_codec_write(codec, 0x1a, 0,
1349 AC_VERB_SET_PROC_COEF,
1350 tmp | 0x2010);
1351 break;
1352 case 0x10ec0262:
1353 case 0x10ec0880:
1354 case 0x10ec0882:
1355 case 0x10ec0883:
1356 case 0x10ec0885:
1357 case 0x10ec0887:
1358 case 0x10ec0889:
1359 alc889_coef_init(codec);
1360 break;
1361 case 0x10ec0888:
1362 alc888_coef_init(codec);
1363 break;
1364 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1365 case 0x10ec0267:
1366 case 0x10ec0268:
1367 snd_hda_codec_write(codec, 0x20, 0,
1368 AC_VERB_SET_COEF_INDEX, 7);
1369 tmp = snd_hda_codec_read(codec, 0x20, 0,
1370 AC_VERB_GET_PROC_COEF, 0);
1371 snd_hda_codec_write(codec, 0x20, 0,
1372 AC_VERB_SET_COEF_INDEX, 7);
1373 snd_hda_codec_write(codec, 0x20, 0,
1374 AC_VERB_SET_PROC_COEF,
1375 tmp | 0x3000);
1376 break;
1377 #endif /* XXX */
1378 }
1379 break;
1380 }
1381 }
1382
1383 static void alc_init_auto_hp(struct hda_codec *codec)
1384 {
1385 struct alc_spec *spec = codec->spec;
1386 struct auto_pin_cfg *cfg = &spec->autocfg;
1387 int i;
1388
1389 if (!cfg->hp_pins[0]) {
1390 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1391 return;
1392 }
1393
1394 if (!cfg->speaker_pins[0]) {
1395 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1396 return;
1397 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1398 sizeof(cfg->speaker_pins));
1399 cfg->speaker_outs = cfg->line_outs;
1400 }
1401
1402 if (!cfg->hp_pins[0]) {
1403 memcpy(cfg->hp_pins, cfg->line_out_pins,
1404 sizeof(cfg->hp_pins));
1405 cfg->hp_outs = cfg->line_outs;
1406 }
1407
1408 for (i = 0; i < cfg->hp_outs; i++) {
1409 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1410 cfg->hp_pins[i]);
1411 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
1412 AC_VERB_SET_UNSOLICITED_ENABLE,
1413 AC_USRSP_EN | ALC880_HP_EVENT);
1414 }
1415 spec->unsol_event = alc_sku_unsol_event;
1416 }
1417
1418 static void alc_init_auto_mic(struct hda_codec *codec)
1419 {
1420 struct alc_spec *spec = codec->spec;
1421 struct auto_pin_cfg *cfg = &spec->autocfg;
1422 hda_nid_t fixed, ext;
1423 int i;
1424
1425 /* there must be only two mic inputs exclusively */
1426 for (i = 0; i < cfg->num_inputs; i++)
1427 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
1428 return;
1429
1430 fixed = ext = 0;
1431 for (i = 0; i < cfg->num_inputs; i++) {
1432 hda_nid_t nid = cfg->inputs[i].pin;
1433 unsigned int defcfg;
1434 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1435 switch (snd_hda_get_input_pin_attr(defcfg)) {
1436 case INPUT_PIN_ATTR_INT:
1437 if (fixed)
1438 return; /* already occupied */
1439 fixed = nid;
1440 break;
1441 case INPUT_PIN_ATTR_UNUSED:
1442 return; /* invalid entry */
1443 default:
1444 if (ext)
1445 return; /* already occupied */
1446 ext = nid;
1447 break;
1448 }
1449 }
1450 if (!ext || !fixed)
1451 return;
1452 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1453 return; /* no unsol support */
1454 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1455 ext, fixed);
1456 spec->ext_mic.pin = ext;
1457 spec->int_mic.pin = fixed;
1458 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1459 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1460 spec->auto_mic = 1;
1461 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1462 AC_VERB_SET_UNSOLICITED_ENABLE,
1463 AC_USRSP_EN | ALC880_MIC_EVENT);
1464 spec->unsol_event = alc_sku_unsol_event;
1465 }
1466
1467 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1468 {
1469 unsigned int ass, tmp, i;
1470 unsigned nid = 0;
1471 struct alc_spec *spec = codec->spec;
1472
1473 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1474
1475 ass = codec->subsystem_id & 0xffff;
1476 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1477 goto do_sku;
1478
1479 nid = 0x1d;
1480 if (codec->vendor_id == 0x10ec0260)
1481 nid = 0x17;
1482 ass = snd_hda_codec_get_pincfg(codec, nid);
1483
1484 if (!(ass & 1)) {
1485 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1486 codec->chip_name, ass);
1487 return -1;
1488 }
1489
1490 /* check sum */
1491 tmp = 0;
1492 for (i = 1; i < 16; i++) {
1493 if ((ass >> i) & 1)
1494 tmp++;
1495 }
1496 if (((ass >> 16) & 0xf) != tmp)
1497 return -1;
1498
1499 spec->cdefine.port_connectivity = ass >> 30;
1500 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1501 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1502 spec->cdefine.customization = ass >> 8;
1503 do_sku:
1504 spec->cdefine.sku_cfg = ass;
1505 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1506 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1507 spec->cdefine.swap = (ass & 0x2) >> 1;
1508 spec->cdefine.override = ass & 0x1;
1509
1510 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1511 nid, spec->cdefine.sku_cfg);
1512 snd_printd("SKU: port_connectivity=0x%x\n",
1513 spec->cdefine.port_connectivity);
1514 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1515 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1516 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1517 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1518 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1519 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1520 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1521
1522 return 0;
1523 }
1524
1525 /* check subsystem ID and set up device-specific initialization;
1526 * return 1 if initialized, 0 if invalid SSID
1527 */
1528 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1529 * 31 ~ 16 : Manufacture ID
1530 * 15 ~ 8 : SKU ID
1531 * 7 ~ 0 : Assembly ID
1532 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1533 */
1534 static int alc_subsystem_id(struct hda_codec *codec,
1535 hda_nid_t porta, hda_nid_t porte,
1536 hda_nid_t portd, hda_nid_t porti)
1537 {
1538 unsigned int ass, tmp, i;
1539 unsigned nid;
1540 struct alc_spec *spec = codec->spec;
1541
1542 ass = codec->subsystem_id & 0xffff;
1543 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1544 goto do_sku;
1545
1546 /* invalid SSID, check the special NID pin defcfg instead */
1547 /*
1548 * 31~30 : port connectivity
1549 * 29~21 : reserve
1550 * 20 : PCBEEP input
1551 * 19~16 : Check sum (15:1)
1552 * 15~1 : Custom
1553 * 0 : override
1554 */
1555 nid = 0x1d;
1556 if (codec->vendor_id == 0x10ec0260)
1557 nid = 0x17;
1558 ass = snd_hda_codec_get_pincfg(codec, nid);
1559 snd_printd("realtek: No valid SSID, "
1560 "checking pincfg 0x%08x for NID 0x%x\n",
1561 ass, nid);
1562 if (!(ass & 1))
1563 return 0;
1564 if ((ass >> 30) != 1) /* no physical connection */
1565 return 0;
1566
1567 /* check sum */
1568 tmp = 0;
1569 for (i = 1; i < 16; i++) {
1570 if ((ass >> i) & 1)
1571 tmp++;
1572 }
1573 if (((ass >> 16) & 0xf) != tmp)
1574 return 0;
1575 do_sku:
1576 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1577 ass & 0xffff, codec->vendor_id);
1578 /*
1579 * 0 : override
1580 * 1 : Swap Jack
1581 * 2 : 0 --> Desktop, 1 --> Laptop
1582 * 3~5 : External Amplifier control
1583 * 7~6 : Reserved
1584 */
1585 tmp = (ass & 0x38) >> 3; /* external Amp control */
1586 switch (tmp) {
1587 case 1:
1588 spec->init_amp = ALC_INIT_GPIO1;
1589 break;
1590 case 3:
1591 spec->init_amp = ALC_INIT_GPIO2;
1592 break;
1593 case 7:
1594 spec->init_amp = ALC_INIT_GPIO3;
1595 break;
1596 case 5:
1597 spec->init_amp = ALC_INIT_DEFAULT;
1598 break;
1599 }
1600
1601 /* is laptop or Desktop and enable the function "Mute internal speaker
1602 * when the external headphone out jack is plugged"
1603 */
1604 if (!(ass & 0x8000))
1605 return 1;
1606 /*
1607 * 10~8 : Jack location
1608 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1609 * 14~13: Resvered
1610 * 15 : 1 --> enable the function "Mute internal speaker
1611 * when the external headphone out jack is plugged"
1612 */
1613 if (!spec->autocfg.hp_pins[0]) {
1614 hda_nid_t nid;
1615 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1616 if (tmp == 0)
1617 nid = porta;
1618 else if (tmp == 1)
1619 nid = porte;
1620 else if (tmp == 2)
1621 nid = portd;
1622 else if (tmp == 3)
1623 nid = porti;
1624 else
1625 return 1;
1626 for (i = 0; i < spec->autocfg.line_outs; i++)
1627 if (spec->autocfg.line_out_pins[i] == nid)
1628 return 1;
1629 spec->autocfg.hp_pins[0] = nid;
1630 }
1631
1632 alc_init_auto_hp(codec);
1633 alc_init_auto_mic(codec);
1634 return 1;
1635 }
1636
1637 static void alc_ssid_check(struct hda_codec *codec,
1638 hda_nid_t porta, hda_nid_t porte,
1639 hda_nid_t portd, hda_nid_t porti)
1640 {
1641 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1642 struct alc_spec *spec = codec->spec;
1643 snd_printd("realtek: "
1644 "Enable default setup for auto mode as fallback\n");
1645 spec->init_amp = ALC_INIT_DEFAULT;
1646 alc_init_auto_hp(codec);
1647 alc_init_auto_mic(codec);
1648 }
1649 }
1650
1651 /*
1652 * Fix-up pin default configurations and add default verbs
1653 */
1654
1655 struct alc_pincfg {
1656 hda_nid_t nid;
1657 u32 val;
1658 };
1659
1660 struct alc_fixup {
1661 const struct alc_pincfg *pins;
1662 const struct hda_verb *verbs;
1663 };
1664
1665 static void alc_pick_fixup(struct hda_codec *codec,
1666 const struct snd_pci_quirk *quirk,
1667 const struct alc_fixup *fix,
1668 int pre_init)
1669 {
1670 const struct alc_pincfg *cfg;
1671
1672 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1673 if (!quirk)
1674 return;
1675 fix += quirk->value;
1676 cfg = fix->pins;
1677 if (pre_init && cfg) {
1678 #ifdef CONFIG_SND_DEBUG_VERBOSE
1679 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1680 codec->chip_name, quirk->name);
1681 #endif
1682 for (; cfg->nid; cfg++)
1683 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1684 }
1685 if (!pre_init && fix->verbs) {
1686 #ifdef CONFIG_SND_DEBUG_VERBOSE
1687 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1688 codec->chip_name, quirk->name);
1689 #endif
1690 add_verb(codec->spec, fix->verbs);
1691 }
1692 }
1693
1694 static int alc_read_coef_idx(struct hda_codec *codec,
1695 unsigned int coef_idx)
1696 {
1697 unsigned int val;
1698 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1699 coef_idx);
1700 val = snd_hda_codec_read(codec, 0x20, 0,
1701 AC_VERB_GET_PROC_COEF, 0);
1702 return val;
1703 }
1704
1705 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1706 unsigned int coef_val)
1707 {
1708 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1709 coef_idx);
1710 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1711 coef_val);
1712 }
1713
1714 /* set right pin controls for digital I/O */
1715 static void alc_auto_init_digital(struct hda_codec *codec)
1716 {
1717 struct alc_spec *spec = codec->spec;
1718 int i;
1719 hda_nid_t pin;
1720
1721 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1722 pin = spec->autocfg.dig_out_pins[i];
1723 if (pin) {
1724 snd_hda_codec_write(codec, pin, 0,
1725 AC_VERB_SET_PIN_WIDGET_CONTROL,
1726 PIN_OUT);
1727 }
1728 }
1729 pin = spec->autocfg.dig_in_pin;
1730 if (pin)
1731 snd_hda_codec_write(codec, pin, 0,
1732 AC_VERB_SET_PIN_WIDGET_CONTROL,
1733 PIN_IN);
1734 }
1735
1736 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1737 static void alc_auto_parse_digital(struct hda_codec *codec)
1738 {
1739 struct alc_spec *spec = codec->spec;
1740 int i, err;
1741 hda_nid_t dig_nid;
1742
1743 /* support multiple SPDIFs; the secondary is set up as a slave */
1744 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1745 err = snd_hda_get_connections(codec,
1746 spec->autocfg.dig_out_pins[i],
1747 &dig_nid, 1);
1748 if (err < 0)
1749 continue;
1750 if (!i) {
1751 spec->multiout.dig_out_nid = dig_nid;
1752 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1753 } else {
1754 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1755 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1756 break;
1757 spec->slave_dig_outs[i - 1] = dig_nid;
1758 }
1759 }
1760
1761 if (spec->autocfg.dig_in_pin) {
1762 dig_nid = codec->start_nid;
1763 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1764 unsigned int wcaps = get_wcaps(codec, dig_nid);
1765 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1766 continue;
1767 if (!(wcaps & AC_WCAP_DIGITAL))
1768 continue;
1769 if (!(wcaps & AC_WCAP_CONN_LIST))
1770 continue;
1771 err = get_connection_index(codec, dig_nid,
1772 spec->autocfg.dig_in_pin);
1773 if (err >= 0) {
1774 spec->dig_in_nid = dig_nid;
1775 break;
1776 }
1777 }
1778 }
1779 }
1780
1781 /*
1782 * ALC888
1783 */
1784
1785 /*
1786 * 2ch mode
1787 */
1788 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1789 /* Mic-in jack as mic in */
1790 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1791 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1792 /* Line-in jack as Line in */
1793 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1794 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1795 /* Line-Out as Front */
1796 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1797 { } /* end */
1798 };
1799
1800 /*
1801 * 4ch mode
1802 */
1803 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1804 /* Mic-in jack as mic in */
1805 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1806 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1807 /* Line-in jack as Surround */
1808 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1809 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1810 /* Line-Out as Front */
1811 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1812 { } /* end */
1813 };
1814
1815 /*
1816 * 6ch mode
1817 */
1818 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1819 /* Mic-in jack as CLFE */
1820 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1821 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1822 /* Line-in jack as Surround */
1823 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1824 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1825 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1826 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1827 { } /* end */
1828 };
1829
1830 /*
1831 * 8ch mode
1832 */
1833 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1834 /* Mic-in jack as CLFE */
1835 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1836 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1837 /* Line-in jack as Surround */
1838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1840 /* Line-Out as Side */
1841 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1842 { } /* end */
1843 };
1844
1845 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1846 { 2, alc888_4ST_ch2_intel_init },
1847 { 4, alc888_4ST_ch4_intel_init },
1848 { 6, alc888_4ST_ch6_intel_init },
1849 { 8, alc888_4ST_ch8_intel_init },
1850 };
1851
1852 /*
1853 * ALC888 Fujitsu Siemens Amillo xa3530
1854 */
1855
1856 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1857 /* Front Mic: set to PIN_IN (empty by default) */
1858 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1859 /* Connect Internal HP to Front */
1860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1862 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1863 /* Connect Bass HP to Front */
1864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1867 /* Connect Line-Out side jack (SPDIF) to Side */
1868 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1869 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1871 /* Connect Mic jack to CLFE */
1872 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1875 /* Connect Line-in jack to Surround */
1876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1878 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1879 /* Connect HP out jack to Front */
1880 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1882 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1883 /* Enable unsolicited event for HP jack and Line-out jack */
1884 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1885 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1886 {}
1887 };
1888
1889 static void alc_automute_amp(struct hda_codec *codec)
1890 {
1891 alc_automute_speaker(codec, 0);
1892 }
1893
1894 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1895 unsigned int res)
1896 {
1897 if (codec->vendor_id == 0x10ec0880)
1898 res >>= 28;
1899 else
1900 res >>= 26;
1901 if (res == ALC880_HP_EVENT)
1902 alc_automute_amp(codec);
1903 }
1904
1905 static void alc889_automute_setup(struct hda_codec *codec)
1906 {
1907 struct alc_spec *spec = codec->spec;
1908
1909 spec->autocfg.hp_pins[0] = 0x15;
1910 spec->autocfg.speaker_pins[0] = 0x14;
1911 spec->autocfg.speaker_pins[1] = 0x16;
1912 spec->autocfg.speaker_pins[2] = 0x17;
1913 spec->autocfg.speaker_pins[3] = 0x19;
1914 spec->autocfg.speaker_pins[4] = 0x1a;
1915 }
1916
1917 static void alc889_intel_init_hook(struct hda_codec *codec)
1918 {
1919 alc889_coef_init(codec);
1920 alc_automute_amp(codec);
1921 }
1922
1923 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1924 {
1925 struct alc_spec *spec = codec->spec;
1926
1927 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1928 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1929 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1930 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1931 }
1932
1933 /*
1934 * ALC888 Acer Aspire 4930G model
1935 */
1936
1937 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1938 /* Front Mic: set to PIN_IN (empty by default) */
1939 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1940 /* Unselect Front Mic by default in input mixer 3 */
1941 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1942 /* Enable unsolicited event for HP jack */
1943 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1944 /* Connect Internal HP to front */
1945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1946 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1947 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1948 /* Connect HP out to front */
1949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1951 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1952 { }
1953 };
1954
1955 /*
1956 * ALC888 Acer Aspire 6530G model
1957 */
1958
1959 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1960 /* Route to built-in subwoofer as well as speakers */
1961 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1963 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1964 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1965 /* Bias voltage on for external mic port */
1966 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1967 /* Front Mic: set to PIN_IN (empty by default) */
1968 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1969 /* Unselect Front Mic by default in input mixer 3 */
1970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1971 /* Enable unsolicited event for HP jack */
1972 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1973 /* Enable speaker output */
1974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1976 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1977 /* Enable headphone output */
1978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1979 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1980 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1981 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1982 { }
1983 };
1984
1985 /*
1986 * ALC889 Acer Aspire 8930G model
1987 */
1988
1989 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1990 /* Front Mic: set to PIN_IN (empty by default) */
1991 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1992 /* Unselect Front Mic by default in input mixer 3 */
1993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1994 /* Enable unsolicited event for HP jack */
1995 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1996 /* Connect Internal Front to Front */
1997 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1998 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1999 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2000 /* Connect Internal Rear to Rear */
2001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2003 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2004 /* Connect Internal CLFE to CLFE */
2005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2007 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2008 /* Connect HP out to Front */
2009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2010 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2011 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2012 /* Enable all DACs */
2013 /* DAC DISABLE/MUTE 1? */
2014 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2015 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2016 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2017 /* DAC DISABLE/MUTE 2? */
2018 /* some bit here disables the other DACs. Init=0x4900 */
2019 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2020 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2021 /* DMIC fix
2022 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2023 * which makes the stereo useless. However, either the mic or the ALC889
2024 * makes the signal become a difference/sum signal instead of standard
2025 * stereo, which is annoying. So instead we flip this bit which makes the
2026 * codec replicate the sum signal to both channels, turning it into a
2027 * normal mono mic.
2028 */
2029 /* DMIC_CONTROL? Init value = 0x0001 */
2030 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2031 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2032 { }
2033 };
2034
2035 static struct hda_input_mux alc888_2_capture_sources[2] = {
2036 /* Front mic only available on one ADC */
2037 {
2038 .num_items = 4,
2039 .items = {
2040 { "Mic", 0x0 },
2041 { "Line", 0x2 },
2042 { "CD", 0x4 },
2043 { "Front Mic", 0xb },
2044 },
2045 },
2046 {
2047 .num_items = 3,
2048 .items = {
2049 { "Mic", 0x0 },
2050 { "Line", 0x2 },
2051 { "CD", 0x4 },
2052 },
2053 }
2054 };
2055
2056 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2057 /* Interal mic only available on one ADC */
2058 {
2059 .num_items = 5,
2060 .items = {
2061 { "Ext Mic", 0x0 },
2062 { "Line In", 0x2 },
2063 { "CD", 0x4 },
2064 { "Input Mix", 0xa },
2065 { "Int Mic", 0xb },
2066 },
2067 },
2068 {
2069 .num_items = 4,
2070 .items = {
2071 { "Ext Mic", 0x0 },
2072 { "Line In", 0x2 },
2073 { "CD", 0x4 },
2074 { "Input Mix", 0xa },
2075 },
2076 }
2077 };
2078
2079 static struct hda_input_mux alc889_capture_sources[3] = {
2080 /* Digital mic only available on first "ADC" */
2081 {
2082 .num_items = 5,
2083 .items = {
2084 { "Mic", 0x0 },
2085 { "Line", 0x2 },
2086 { "CD", 0x4 },
2087 { "Front Mic", 0xb },
2088 { "Input Mix", 0xa },
2089 },
2090 },
2091 {
2092 .num_items = 4,
2093 .items = {
2094 { "Mic", 0x0 },
2095 { "Line", 0x2 },
2096 { "CD", 0x4 },
2097 { "Input Mix", 0xa },
2098 },
2099 },
2100 {
2101 .num_items = 4,
2102 .items = {
2103 { "Mic", 0x0 },
2104 { "Line", 0x2 },
2105 { "CD", 0x4 },
2106 { "Input Mix", 0xa },
2107 },
2108 }
2109 };
2110
2111 static struct snd_kcontrol_new alc888_base_mixer[] = {
2112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2113 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2114 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2115 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2116 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2117 HDA_OUTPUT),
2118 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2119 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2120 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2121 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2122 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2123 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2124 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2128 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
2129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2130 { } /* end */
2131 };
2132
2133 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2136 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2137 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2138 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2139 HDA_OUTPUT),
2140 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2141 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2142 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2146 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
2147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2148 { } /* end */
2149 };
2150
2151
2152 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2153 {
2154 struct alc_spec *spec = codec->spec;
2155
2156 spec->autocfg.hp_pins[0] = 0x15;
2157 spec->autocfg.speaker_pins[0] = 0x14;
2158 spec->autocfg.speaker_pins[1] = 0x16;
2159 spec->autocfg.speaker_pins[2] = 0x17;
2160 }
2161
2162 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2163 {
2164 struct alc_spec *spec = codec->spec;
2165
2166 spec->autocfg.hp_pins[0] = 0x15;
2167 spec->autocfg.speaker_pins[0] = 0x14;
2168 spec->autocfg.speaker_pins[1] = 0x16;
2169 spec->autocfg.speaker_pins[2] = 0x17;
2170 }
2171
2172 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2173 {
2174 struct alc_spec *spec = codec->spec;
2175
2176 spec->autocfg.hp_pins[0] = 0x15;
2177 spec->autocfg.speaker_pins[0] = 0x14;
2178 spec->autocfg.speaker_pins[1] = 0x16;
2179 spec->autocfg.speaker_pins[2] = 0x1b;
2180 }
2181
2182 /*
2183 * ALC880 3-stack model
2184 *
2185 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2186 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2187 * F-Mic = 0x1b, HP = 0x19
2188 */
2189
2190 static hda_nid_t alc880_dac_nids[4] = {
2191 /* front, rear, clfe, rear_surr */
2192 0x02, 0x05, 0x04, 0x03
2193 };
2194
2195 static hda_nid_t alc880_adc_nids[3] = {
2196 /* ADC0-2 */
2197 0x07, 0x08, 0x09,
2198 };
2199
2200 /* The datasheet says the node 0x07 is connected from inputs,
2201 * but it shows zero connection in the real implementation on some devices.
2202 * Note: this is a 915GAV bug, fixed on 915GLV
2203 */
2204 static hda_nid_t alc880_adc_nids_alt[2] = {
2205 /* ADC1-2 */
2206 0x08, 0x09,
2207 };
2208
2209 #define ALC880_DIGOUT_NID 0x06
2210 #define ALC880_DIGIN_NID 0x0a
2211
2212 static struct hda_input_mux alc880_capture_source = {
2213 .num_items = 4,
2214 .items = {
2215 { "Mic", 0x0 },
2216 { "Front Mic", 0x3 },
2217 { "Line", 0x2 },
2218 { "CD", 0x4 },
2219 },
2220 };
2221
2222 /* channel source setting (2/6 channel selection for 3-stack) */
2223 /* 2ch mode */
2224 static struct hda_verb alc880_threestack_ch2_init[] = {
2225 /* set line-in to input, mute it */
2226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2228 /* set mic-in to input vref 80%, mute it */
2229 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2230 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2231 { } /* end */
2232 };
2233
2234 /* 6ch mode */
2235 static struct hda_verb alc880_threestack_ch6_init[] = {
2236 /* set line-in to output, unmute it */
2237 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2238 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2239 /* set mic-in to output, unmute it */
2240 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2241 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2242 { } /* end */
2243 };
2244
2245 static struct hda_channel_mode alc880_threestack_modes[2] = {
2246 { 2, alc880_threestack_ch2_init },
2247 { 6, alc880_threestack_ch6_init },
2248 };
2249
2250 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2251 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2252 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2253 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2254 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2255 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2256 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2257 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2258 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2259 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2260 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2262 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2264 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2265 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2266 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2267 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2268 {
2269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2270 .name = "Channel Mode",
2271 .info = alc_ch_mode_info,
2272 .get = alc_ch_mode_get,
2273 .put = alc_ch_mode_put,
2274 },
2275 { } /* end */
2276 };
2277
2278 /* capture mixer elements */
2279 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2280 struct snd_ctl_elem_info *uinfo)
2281 {
2282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2283 struct alc_spec *spec = codec->spec;
2284 int err;
2285
2286 mutex_lock(&codec->control_mutex);
2287 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2288 HDA_INPUT);
2289 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2290 mutex_unlock(&codec->control_mutex);
2291 return err;
2292 }
2293
2294 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2295 unsigned int size, unsigned int __user *tlv)
2296 {
2297 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2298 struct alc_spec *spec = codec->spec;
2299 int err;
2300
2301 mutex_lock(&codec->control_mutex);
2302 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2303 HDA_INPUT);
2304 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2305 mutex_unlock(&codec->control_mutex);
2306 return err;
2307 }
2308
2309 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2310 struct snd_ctl_elem_value *ucontrol);
2311
2312 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2313 struct snd_ctl_elem_value *ucontrol,
2314 getput_call_t func)
2315 {
2316 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2317 struct alc_spec *spec = codec->spec;
2318 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2319 int err;
2320
2321 mutex_lock(&codec->control_mutex);
2322 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2323 3, 0, HDA_INPUT);
2324 err = func(kcontrol, ucontrol);
2325 mutex_unlock(&codec->control_mutex);
2326 return err;
2327 }
2328
2329 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2330 struct snd_ctl_elem_value *ucontrol)
2331 {
2332 return alc_cap_getput_caller(kcontrol, ucontrol,
2333 snd_hda_mixer_amp_volume_get);
2334 }
2335
2336 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2337 struct snd_ctl_elem_value *ucontrol)
2338 {
2339 return alc_cap_getput_caller(kcontrol, ucontrol,
2340 snd_hda_mixer_amp_volume_put);
2341 }
2342
2343 /* capture mixer elements */
2344 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2345
2346 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2347 struct snd_ctl_elem_value *ucontrol)
2348 {
2349 return alc_cap_getput_caller(kcontrol, ucontrol,
2350 snd_hda_mixer_amp_switch_get);
2351 }
2352
2353 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2354 struct snd_ctl_elem_value *ucontrol)
2355 {
2356 return alc_cap_getput_caller(kcontrol, ucontrol,
2357 snd_hda_mixer_amp_switch_put);
2358 }
2359
2360 #define _DEFINE_CAPMIX(num) \
2361 { \
2362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2363 .name = "Capture Switch", \
2364 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2365 .count = num, \
2366 .info = alc_cap_sw_info, \
2367 .get = alc_cap_sw_get, \
2368 .put = alc_cap_sw_put, \
2369 }, \
2370 { \
2371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2372 .name = "Capture Volume", \
2373 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2374 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2375 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2376 .count = num, \
2377 .info = alc_cap_vol_info, \
2378 .get = alc_cap_vol_get, \
2379 .put = alc_cap_vol_put, \
2380 .tlv = { .c = alc_cap_vol_tlv }, \
2381 }
2382
2383 #define _DEFINE_CAPSRC(num) \
2384 { \
2385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2386 /* .name = "Capture Source", */ \
2387 .name = "Input Source", \
2388 .count = num, \
2389 .info = alc_mux_enum_info, \
2390 .get = alc_mux_enum_get, \
2391 .put = alc_mux_enum_put, \
2392 }
2393
2394 #define DEFINE_CAPMIX(num) \
2395 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2396 _DEFINE_CAPMIX(num), \
2397 _DEFINE_CAPSRC(num), \
2398 { } /* end */ \
2399 }
2400
2401 #define DEFINE_CAPMIX_NOSRC(num) \
2402 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2403 _DEFINE_CAPMIX(num), \
2404 { } /* end */ \
2405 }
2406
2407 /* up to three ADCs */
2408 DEFINE_CAPMIX(1);
2409 DEFINE_CAPMIX(2);
2410 DEFINE_CAPMIX(3);
2411 DEFINE_CAPMIX_NOSRC(1);
2412 DEFINE_CAPMIX_NOSRC(2);
2413 DEFINE_CAPMIX_NOSRC(3);
2414
2415 /*
2416 * ALC880 5-stack model
2417 *
2418 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2419 * Side = 0x02 (0xd)
2420 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2421 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2422 */
2423
2424 /* additional mixers to alc880_three_stack_mixer */
2425 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2426 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2427 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2428 { } /* end */
2429 };
2430
2431 /* channel source setting (6/8 channel selection for 5-stack) */
2432 /* 6ch mode */
2433 static struct hda_verb alc880_fivestack_ch6_init[] = {
2434 /* set line-in to input, mute it */
2435 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2436 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2437 { } /* end */
2438 };
2439
2440 /* 8ch mode */
2441 static struct hda_verb alc880_fivestack_ch8_init[] = {
2442 /* set line-in to output, unmute it */
2443 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2444 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2445 { } /* end */
2446 };
2447
2448 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2449 { 6, alc880_fivestack_ch6_init },
2450 { 8, alc880_fivestack_ch8_init },
2451 };
2452
2453
2454 /*
2455 * ALC880 6-stack model
2456 *
2457 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2458 * Side = 0x05 (0x0f)
2459 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2460 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2461 */
2462
2463 static hda_nid_t alc880_6st_dac_nids[4] = {
2464 /* front, rear, clfe, rear_surr */
2465 0x02, 0x03, 0x04, 0x05
2466 };
2467
2468 static struct hda_input_mux alc880_6stack_capture_source = {
2469 .num_items = 4,
2470 .items = {
2471 { "Mic", 0x0 },
2472 { "Front Mic", 0x1 },
2473 { "Line", 0x2 },
2474 { "CD", 0x4 },
2475 },
2476 };
2477
2478 /* fixed 8-channels */
2479 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2480 { 8, NULL },
2481 };
2482
2483 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2484 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2486 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2487 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2488 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2489 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2490 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2491 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2492 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2493 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2494 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2495 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2496 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2497 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2498 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2499 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2500 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2501 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2502 {
2503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2504 .name = "Channel Mode",
2505 .info = alc_ch_mode_info,
2506 .get = alc_ch_mode_get,
2507 .put = alc_ch_mode_put,
2508 },
2509 { } /* end */
2510 };
2511
2512
2513 /*
2514 * ALC880 W810 model
2515 *
2516 * W810 has rear IO for:
2517 * Front (DAC 02)
2518 * Surround (DAC 03)
2519 * Center/LFE (DAC 04)
2520 * Digital out (06)
2521 *
2522 * The system also has a pair of internal speakers, and a headphone jack.
2523 * These are both connected to Line2 on the codec, hence to DAC 02.
2524 *
2525 * There is a variable resistor to control the speaker or headphone
2526 * volume. This is a hardware-only device without a software API.
2527 *
2528 * Plugging headphones in will disable the internal speakers. This is
2529 * implemented in hardware, not via the driver using jack sense. In
2530 * a similar fashion, plugging into the rear socket marked "front" will
2531 * disable both the speakers and headphones.
2532 *
2533 * For input, there's a microphone jack, and an "audio in" jack.
2534 * These may not do anything useful with this driver yet, because I
2535 * haven't setup any initialization verbs for these yet...
2536 */
2537
2538 static hda_nid_t alc880_w810_dac_nids[3] = {
2539 /* front, rear/surround, clfe */
2540 0x02, 0x03, 0x04
2541 };
2542
2543 /* fixed 6 channels */
2544 static struct hda_channel_mode alc880_w810_modes[1] = {
2545 { 6, NULL }
2546 };
2547
2548 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2549 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2550 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2551 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2552 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2553 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2554 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2555 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2556 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2557 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2559 { } /* end */
2560 };
2561
2562
2563 /*
2564 * Z710V model
2565 *
2566 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2567 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2568 * Line = 0x1a
2569 */
2570
2571 static hda_nid_t alc880_z71v_dac_nids[1] = {
2572 0x02
2573 };
2574 #define ALC880_Z71V_HP_DAC 0x03
2575
2576 /* fixed 2 channels */
2577 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2578 { 2, NULL }
2579 };
2580
2581 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2582 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2583 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2584 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2585 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2586 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2587 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2590 { } /* end */
2591 };
2592
2593
2594 /*
2595 * ALC880 F1734 model
2596 *
2597 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2598 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2599 */
2600
2601 static hda_nid_t alc880_f1734_dac_nids[1] = {
2602 0x03
2603 };
2604 #define ALC880_F1734_HP_DAC 0x02
2605
2606 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2607 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2608 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2609 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2610 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2611 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2612 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2615 { } /* end */
2616 };
2617
2618 static struct hda_input_mux alc880_f1734_capture_source = {
2619 .num_items = 2,
2620 .items = {
2621 { "Mic", 0x1 },
2622 { "CD", 0x4 },
2623 },
2624 };
2625
2626
2627 /*
2628 * ALC880 ASUS model
2629 *
2630 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2631 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2632 * Mic = 0x18, Line = 0x1a
2633 */
2634
2635 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2636 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2637
2638 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2639 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2640 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2641 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2642 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2643 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2644 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2645 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2646 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2653 {
2654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2655 .name = "Channel Mode",
2656 .info = alc_ch_mode_info,
2657 .get = alc_ch_mode_get,
2658 .put = alc_ch_mode_put,
2659 },
2660 { } /* end */
2661 };
2662
2663 /*
2664 * ALC880 ASUS W1V model
2665 *
2666 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2667 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2668 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2669 */
2670
2671 /* additional mixers to alc880_asus_mixer */
2672 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2673 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2674 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2675 { } /* end */
2676 };
2677
2678 /* TCL S700 */
2679 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2680 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2681 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2682 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2683 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2684 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2687 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2688 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2689 { } /* end */
2690 };
2691
2692 /* Uniwill */
2693 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2694 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2695 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2696 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2697 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2698 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2699 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2700 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2701 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2702 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2703 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2708 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2709 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2710 {
2711 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2712 .name = "Channel Mode",
2713 .info = alc_ch_mode_info,
2714 .get = alc_ch_mode_get,
2715 .put = alc_ch_mode_put,
2716 },
2717 { } /* end */
2718 };
2719
2720 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2722 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2723 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2724 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2725 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2726 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2727 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2728 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2730 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2731 { } /* end */
2732 };
2733
2734 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2735 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2736 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2737 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2738 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2740 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2741 { } /* end */
2742 };
2743
2744 /*
2745 * virtual master controls
2746 */
2747
2748 /*
2749 * slave controls for virtual master
2750 */
2751 static const char *alc_slave_vols[] = {
2752 "Front Playback Volume",
2753 "Surround Playback Volume",
2754 "Center Playback Volume",
2755 "LFE Playback Volume",
2756 "Side Playback Volume",
2757 "Headphone Playback Volume",
2758 "Speaker Playback Volume",
2759 "Mono Playback Volume",
2760 "Line-Out Playback Volume",
2761 "PCM Playback Volume",
2762 NULL,
2763 };
2764
2765 static const char *alc_slave_sws[] = {
2766 "Front Playback Switch",
2767 "Surround Playback Switch",
2768 "Center Playback Switch",
2769 "LFE Playback Switch",
2770 "Side Playback Switch",
2771 "Headphone Playback Switch",
2772 "Speaker Playback Switch",
2773 "Mono Playback Switch",
2774 "IEC958 Playback Switch",
2775 "Line-Out Playback Switch",
2776 "PCM Playback Switch",
2777 NULL,
2778 };
2779
2780 /*
2781 * build control elements
2782 */
2783
2784 #define NID_MAPPING (-1)
2785
2786 #define SUBDEV_SPEAKER_ (0 << 6)
2787 #define SUBDEV_HP_ (1 << 6)
2788 #define SUBDEV_LINE_ (2 << 6)
2789 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2790 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2791 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2792
2793 static void alc_free_kctls(struct hda_codec *codec);
2794
2795 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2796 /* additional beep mixers; the actual parameters are overwritten at build */
2797 static struct snd_kcontrol_new alc_beep_mixer[] = {
2798 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2799 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2800 { } /* end */
2801 };
2802 #endif
2803
2804 static int alc_build_controls(struct hda_codec *codec)
2805 {
2806 struct alc_spec *spec = codec->spec;
2807 struct snd_kcontrol *kctl = NULL;
2808 struct snd_kcontrol_new *knew;
2809 int i, j, err;
2810 unsigned int u;
2811 hda_nid_t nid;
2812
2813 for (i = 0; i < spec->num_mixers; i++) {
2814 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2815 if (err < 0)
2816 return err;
2817 }
2818 if (spec->cap_mixer) {
2819 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2820 if (err < 0)
2821 return err;
2822 }
2823 if (spec->multiout.dig_out_nid) {
2824 err = snd_hda_create_spdif_out_ctls(codec,
2825 spec->multiout.dig_out_nid);
2826 if (err < 0)
2827 return err;
2828 if (!spec->no_analog) {
2829 err = snd_hda_create_spdif_share_sw(codec,
2830 &spec->multiout);
2831 if (err < 0)
2832 return err;
2833 spec->multiout.share_spdif = 1;
2834 }
2835 }
2836 if (spec->dig_in_nid) {
2837 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2838 if (err < 0)
2839 return err;
2840 }
2841
2842 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2843 /* create beep controls if needed */
2844 if (spec->beep_amp) {
2845 struct snd_kcontrol_new *knew;
2846 for (knew = alc_beep_mixer; knew->name; knew++) {
2847 struct snd_kcontrol *kctl;
2848 kctl = snd_ctl_new1(knew, codec);
2849 if (!kctl)
2850 return -ENOMEM;
2851 kctl->private_value = spec->beep_amp;
2852 err = snd_hda_ctl_add(codec, 0, kctl);
2853 if (err < 0)
2854 return err;
2855 }
2856 }
2857 #endif
2858
2859 /* if we have no master control, let's create it */
2860 if (!spec->no_analog &&
2861 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2862 unsigned int vmaster_tlv[4];
2863 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2864 HDA_OUTPUT, vmaster_tlv);
2865 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2866 vmaster_tlv, alc_slave_vols);
2867 if (err < 0)
2868 return err;
2869 }
2870 if (!spec->no_analog &&
2871 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2872 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2873 NULL, alc_slave_sws);
2874 if (err < 0)
2875 return err;
2876 }
2877
2878 /* assign Capture Source enums to NID */
2879 if (spec->capsrc_nids || spec->adc_nids) {
2880 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2881 if (!kctl)
2882 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2883 for (i = 0; kctl && i < kctl->count; i++) {
2884 hda_nid_t *nids = spec->capsrc_nids;
2885 if (!nids)
2886 nids = spec->adc_nids;
2887 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2888 if (err < 0)
2889 return err;
2890 }
2891 }
2892 if (spec->cap_mixer) {
2893 const char *kname = kctl ? kctl->id.name : NULL;
2894 for (knew = spec->cap_mixer; knew->name; knew++) {
2895 if (kname && strcmp(knew->name, kname) == 0)
2896 continue;
2897 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2898 for (i = 0; kctl && i < kctl->count; i++) {
2899 err = snd_hda_add_nid(codec, kctl, i,
2900 spec->adc_nids[i]);
2901 if (err < 0)
2902 return err;
2903 }
2904 }
2905 }
2906
2907 /* other nid->control mapping */
2908 for (i = 0; i < spec->num_mixers; i++) {
2909 for (knew = spec->mixers[i]; knew->name; knew++) {
2910 if (knew->iface != NID_MAPPING)
2911 continue;
2912 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2913 if (kctl == NULL)
2914 continue;
2915 u = knew->subdevice;
2916 for (j = 0; j < 4; j++, u >>= 8) {
2917 nid = u & 0x3f;
2918 if (nid == 0)
2919 continue;
2920 switch (u & 0xc0) {
2921 case SUBDEV_SPEAKER_:
2922 nid = spec->autocfg.speaker_pins[nid];
2923 break;
2924 case SUBDEV_LINE_:
2925 nid = spec->autocfg.line_out_pins[nid];
2926 break;
2927 case SUBDEV_HP_:
2928 nid = spec->autocfg.hp_pins[nid];
2929 break;
2930 default:
2931 continue;
2932 }
2933 err = snd_hda_add_nid(codec, kctl, 0, nid);
2934 if (err < 0)
2935 return err;
2936 }
2937 u = knew->private_value;
2938 for (j = 0; j < 4; j++, u >>= 8) {
2939 nid = u & 0xff;
2940 if (nid == 0)
2941 continue;
2942 err = snd_hda_add_nid(codec, kctl, 0, nid);
2943 if (err < 0)
2944 return err;
2945 }
2946 }
2947 }
2948
2949 alc_free_kctls(codec); /* no longer needed */
2950
2951 return 0;
2952 }
2953
2954
2955 /*
2956 * initialize the codec volumes, etc
2957 */
2958
2959 /*
2960 * generic initialization of ADC, input mixers and output mixers
2961 */
2962 static struct hda_verb alc880_volume_init_verbs[] = {
2963 /*
2964 * Unmute ADC0-2 and set the default input to mic-in
2965 */
2966 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2968 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2970 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2971 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2972
2973 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2974 * mixer widget
2975 * Note: PASD motherboards uses the Line In 2 as the input for front
2976 * panel mic (mic 2)
2977 */
2978 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2979 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2980 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2981 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2982 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2983 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2986
2987 /*
2988 * Set up output mixers (0x0c - 0x0f)
2989 */
2990 /* set vol=0 to output mixers */
2991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2993 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2994 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2995 /* set up input amps for analog loopback */
2996 /* Amp Indices: DAC = 0, mixer = 1 */
2997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3000 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3001 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3002 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3004 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3005
3006 { }
3007 };
3008
3009 /*
3010 * 3-stack pin configuration:
3011 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3012 */
3013 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3014 /*
3015 * preset connection lists of input pins
3016 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3017 */
3018 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3019 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3020 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3021
3022 /*
3023 * Set pin mode and muting
3024 */
3025 /* set front pin widgets 0x14 for output */
3026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3028 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3029 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3030 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3031 /* Mic2 (as headphone out) for HP output */
3032 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3033 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3034 /* Line In pin widget for input */
3035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3036 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3037 /* Line2 (as front mic) pin widget for input and vref at 80% */
3038 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3039 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3040 /* CD pin widget for input */
3041 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3042
3043 { }
3044 };
3045
3046 /*
3047 * 5-stack pin configuration:
3048 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3049 * line-in/side = 0x1a, f-mic = 0x1b
3050 */
3051 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3052 /*
3053 * preset connection lists of input pins
3054 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3055 */
3056 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3057 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3058
3059 /*
3060 * Set pin mode and muting
3061 */
3062 /* set pin widgets 0x14-0x17 for output */
3063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3066 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3067 /* unmute pins for output (no gain on this amp) */
3068 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3069 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3070 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3072
3073 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3074 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3076 /* Mic2 (as headphone out) for HP output */
3077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3079 /* Line In pin widget for input */
3080 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3081 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3082 /* Line2 (as front mic) pin widget for input and vref at 80% */
3083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3085 /* CD pin widget for input */
3086 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3087
3088 { }
3089 };
3090
3091 /*
3092 * W810 pin configuration:
3093 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3094 */
3095 static struct hda_verb alc880_pin_w810_init_verbs[] = {
3096 /* hphone/speaker input selector: front DAC */
3097 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3098
3099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3100 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3101 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3103 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3104 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3105
3106 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3107 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3108
3109 { }
3110 };
3111
3112 /*
3113 * Z71V pin configuration:
3114 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3115 */
3116 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
3117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3120 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3121
3122 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3123 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3124 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3125 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3126
3127 { }
3128 };
3129
3130 /*
3131 * 6-stack pin configuration:
3132 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3133 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3134 */
3135 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3136 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3137
3138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3141 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3142 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3143 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3144 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3145 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3146
3147 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3148 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3149 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3150 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3153 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3154 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3156
3157 { }
3158 };
3159
3160 /*
3161 * Uniwill pin configuration:
3162 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3163 * line = 0x1a
3164 */
3165 static struct hda_verb alc880_uniwill_init_verbs[] = {
3166 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3167
3168 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3169 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3171 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3172 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3173 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3174 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3175 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3178 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3179 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3182
3183 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3184 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3185 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3186 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3187 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3188 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3189 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3190 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3191 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3192
3193 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3194 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3195
3196 { }
3197 };
3198
3199 /*
3200 * Uniwill P53
3201 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3202 */
3203 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3204 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3205
3206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3209 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3210 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3211 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3214 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3215 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3216 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3217 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3218
3219 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3220 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3221 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3222 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3223 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3224 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3225
3226 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3227 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3228
3229 { }
3230 };
3231
3232 static struct hda_verb alc880_beep_init_verbs[] = {
3233 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3234 { }
3235 };
3236
3237 /* auto-toggle front mic */
3238 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3239 {
3240 unsigned int present;
3241 unsigned char bits;
3242
3243 present = snd_hda_jack_detect(codec, 0x18);
3244 bits = present ? HDA_AMP_MUTE : 0;
3245 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3246 }
3247
3248 static void alc880_uniwill_setup(struct hda_codec *codec)
3249 {
3250 struct alc_spec *spec = codec->spec;
3251
3252 spec->autocfg.hp_pins[0] = 0x14;
3253 spec->autocfg.speaker_pins[0] = 0x15;
3254 spec->autocfg.speaker_pins[0] = 0x16;
3255 }
3256
3257 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3258 {
3259 alc_automute_amp(codec);
3260 alc880_uniwill_mic_automute(codec);
3261 }
3262
3263 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3264 unsigned int res)
3265 {
3266 /* Looks like the unsol event is incompatible with the standard
3267 * definition. 4bit tag is placed at 28 bit!
3268 */
3269 switch (res >> 28) {
3270 case ALC880_MIC_EVENT:
3271 alc880_uniwill_mic_automute(codec);
3272 break;
3273 default:
3274 alc_automute_amp_unsol_event(codec, res);
3275 break;
3276 }
3277 }
3278
3279 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3280 {
3281 struct alc_spec *spec = codec->spec;
3282
3283 spec->autocfg.hp_pins[0] = 0x14;
3284 spec->autocfg.speaker_pins[0] = 0x15;
3285 }
3286
3287 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3288 {
3289 unsigned int present;
3290
3291 present = snd_hda_codec_read(codec, 0x21, 0,
3292 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3293 present &= HDA_AMP_VOLMASK;
3294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3295 HDA_AMP_VOLMASK, present);
3296 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3297 HDA_AMP_VOLMASK, present);
3298 }
3299
3300 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3301 unsigned int res)
3302 {
3303 /* Looks like the unsol event is incompatible with the standard
3304 * definition. 4bit tag is placed at 28 bit!
3305 */
3306 if ((res >> 28) == ALC880_DCVOL_EVENT)
3307 alc880_uniwill_p53_dcvol_automute(codec);
3308 else
3309 alc_automute_amp_unsol_event(codec, res);
3310 }
3311
3312 /*
3313 * F1734 pin configuration:
3314 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3315 */
3316 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3317 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3318 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3319 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3320 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3321 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3322
3323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3327
3328 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3329 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3330 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3331 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3332 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3333 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3334 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3335 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3336 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3337
3338 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3339 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3340
3341 { }
3342 };
3343
3344 /*
3345 * ASUS pin configuration:
3346 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3347 */
3348 static struct hda_verb alc880_pin_asus_init_verbs[] = {
3349 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3350 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3351 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3352 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3353
3354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3355 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3356 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3358 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3359 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3360 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3362
3363 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3365 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3366 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3367 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3368 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3370 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3371 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3372
3373 { }
3374 };
3375
3376 /* Enable GPIO mask and set output */
3377 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3378 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3379 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3380
3381 /* Clevo m520g init */
3382 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3383 /* headphone output */
3384 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3385 /* line-out */
3386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3387 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3388 /* Line-in */
3389 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3390 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3391 /* CD */
3392 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3393 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3394 /* Mic1 (rear panel) */
3395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3397 /* Mic2 (front panel) */
3398 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3399 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3400 /* headphone */
3401 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3402 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3403 /* change to EAPD mode */
3404 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3405 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3406
3407 { }
3408 };
3409
3410 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3411 /* change to EAPD mode */
3412 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3413 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3414
3415 /* Headphone output */
3416 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3417 /* Front output*/
3418 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3419 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3420
3421 /* Line In pin widget for input */
3422 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3423 /* CD pin widget for input */
3424 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3425 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3426 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3427
3428 /* change to EAPD mode */
3429 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3430 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3431
3432 { }
3433 };
3434
3435 /*
3436 * LG m1 express dual
3437 *
3438 * Pin assignment:
3439 * Rear Line-In/Out (blue): 0x14
3440 * Build-in Mic-In: 0x15
3441 * Speaker-out: 0x17
3442 * HP-Out (green): 0x1b
3443 * Mic-In/Out (red): 0x19
3444 * SPDIF-Out: 0x1e
3445 */
3446
3447 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3448 static hda_nid_t alc880_lg_dac_nids[3] = {
3449 0x05, 0x02, 0x03
3450 };
3451
3452 /* seems analog CD is not working */
3453 static struct hda_input_mux alc880_lg_capture_source = {
3454 .num_items = 3,
3455 .items = {
3456 { "Mic", 0x1 },
3457 { "Line", 0x5 },
3458 { "Internal Mic", 0x6 },
3459 },
3460 };
3461
3462 /* 2,4,6 channel modes */
3463 static struct hda_verb alc880_lg_ch2_init[] = {
3464 /* set line-in and mic-in to input */
3465 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3466 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3467 { }
3468 };
3469
3470 static struct hda_verb alc880_lg_ch4_init[] = {
3471 /* set line-in to out and mic-in to input */
3472 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3473 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3474 { }
3475 };
3476
3477 static struct hda_verb alc880_lg_ch6_init[] = {
3478 /* set line-in and mic-in to output */
3479 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3480 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3481 { }
3482 };
3483
3484 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3485 { 2, alc880_lg_ch2_init },
3486 { 4, alc880_lg_ch4_init },
3487 { 6, alc880_lg_ch6_init },
3488 };
3489
3490 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3491 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3492 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3494 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3495 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3496 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3497 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3498 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3501 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3502 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3503 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3504 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3505 {
3506 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3507 .name = "Channel Mode",
3508 .info = alc_ch_mode_info,
3509 .get = alc_ch_mode_get,
3510 .put = alc_ch_mode_put,
3511 },
3512 { } /* end */
3513 };
3514
3515 static struct hda_verb alc880_lg_init_verbs[] = {
3516 /* set capture source to mic-in */
3517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3518 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3519 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3520 /* mute all amp mixer inputs */
3521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3524 /* line-in to input */
3525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3527 /* built-in mic */
3528 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3529 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530 /* speaker-out */
3531 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3532 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3533 /* mic-in to input */
3534 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3535 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3536 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3537 /* HP-out */
3538 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3540 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 /* jack sense */
3542 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3543 { }
3544 };
3545
3546 /* toggle speaker-output according to the hp-jack state */
3547 static void alc880_lg_setup(struct hda_codec *codec)
3548 {
3549 struct alc_spec *spec = codec->spec;
3550
3551 spec->autocfg.hp_pins[0] = 0x1b;
3552 spec->autocfg.speaker_pins[0] = 0x17;
3553 }
3554
3555 /*
3556 * LG LW20
3557 *
3558 * Pin assignment:
3559 * Speaker-out: 0x14
3560 * Mic-In: 0x18
3561 * Built-in Mic-In: 0x19
3562 * Line-In: 0x1b
3563 * HP-Out: 0x1a
3564 * SPDIF-Out: 0x1e
3565 */
3566
3567 static struct hda_input_mux alc880_lg_lw_capture_source = {
3568 .num_items = 3,
3569 .items = {
3570 { "Mic", 0x0 },
3571 { "Internal Mic", 0x1 },
3572 { "Line In", 0x2 },
3573 },
3574 };
3575
3576 #define alc880_lg_lw_modes alc880_threestack_modes
3577
3578 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3579 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3580 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3581 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3582 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3583 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3584 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3585 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3586 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3587 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3588 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3589 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3591 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3592 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3593 {
3594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3595 .name = "Channel Mode",
3596 .info = alc_ch_mode_info,
3597 .get = alc_ch_mode_get,
3598 .put = alc_ch_mode_put,
3599 },
3600 { } /* end */
3601 };
3602
3603 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3604 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3605 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3606 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3607
3608 /* set capture source to mic-in */
3609 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3610 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3611 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3612 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3613 /* speaker-out */
3614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3615 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3616 /* HP-out */
3617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3618 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3619 /* mic-in to input */
3620 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3621 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3622 /* built-in mic */
3623 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3624 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3625 /* jack sense */
3626 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3627 { }
3628 };
3629
3630 /* toggle speaker-output according to the hp-jack state */
3631 static void alc880_lg_lw_setup(struct hda_codec *codec)
3632 {
3633 struct alc_spec *spec = codec->spec;
3634
3635 spec->autocfg.hp_pins[0] = 0x1b;
3636 spec->autocfg.speaker_pins[0] = 0x14;
3637 }
3638
3639 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3640 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3641 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3643 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3644 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3645 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3646 { } /* end */
3647 };
3648
3649 static struct hda_input_mux alc880_medion_rim_capture_source = {
3650 .num_items = 2,
3651 .items = {
3652 { "Mic", 0x0 },
3653 { "Internal Mic", 0x1 },
3654 },
3655 };
3656
3657 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3658 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3659
3660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3661 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3662
3663 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3666 /* Mic2 (as headphone out) for HP output */
3667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3669 /* Internal Speaker */
3670 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3671 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3672
3673 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3674 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3675
3676 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3677 { }
3678 };
3679
3680 /* toggle speaker-output according to the hp-jack state */
3681 static void alc880_medion_rim_automute(struct hda_codec *codec)
3682 {
3683 struct alc_spec *spec = codec->spec;
3684 alc_automute_amp(codec);
3685 /* toggle EAPD */
3686 if (spec->jack_present)
3687 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3688 else
3689 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3690 }
3691
3692 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3693 unsigned int res)
3694 {
3695 /* Looks like the unsol event is incompatible with the standard
3696 * definition. 4bit tag is placed at 28 bit!
3697 */
3698 if ((res >> 28) == ALC880_HP_EVENT)
3699 alc880_medion_rim_automute(codec);
3700 }
3701
3702 static void alc880_medion_rim_setup(struct hda_codec *codec)
3703 {
3704 struct alc_spec *spec = codec->spec;
3705
3706 spec->autocfg.hp_pins[0] = 0x14;
3707 spec->autocfg.speaker_pins[0] = 0x1b;
3708 }
3709
3710 #ifdef CONFIG_SND_HDA_POWER_SAVE
3711 static struct hda_amp_list alc880_loopbacks[] = {
3712 { 0x0b, HDA_INPUT, 0 },
3713 { 0x0b, HDA_INPUT, 1 },
3714 { 0x0b, HDA_INPUT, 2 },
3715 { 0x0b, HDA_INPUT, 3 },
3716 { 0x0b, HDA_INPUT, 4 },
3717 { } /* end */
3718 };
3719
3720 static struct hda_amp_list alc880_lg_loopbacks[] = {
3721 { 0x0b, HDA_INPUT, 1 },
3722 { 0x0b, HDA_INPUT, 6 },
3723 { 0x0b, HDA_INPUT, 7 },
3724 { } /* end */
3725 };
3726 #endif
3727
3728 /*
3729 * Common callbacks
3730 */
3731
3732 static int alc_init(struct hda_codec *codec)
3733 {
3734 struct alc_spec *spec = codec->spec;
3735 unsigned int i;
3736
3737 alc_fix_pll(codec);
3738 alc_auto_init_amp(codec, spec->init_amp);
3739
3740 for (i = 0; i < spec->num_init_verbs; i++)
3741 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3742
3743 if (spec->init_hook)
3744 spec->init_hook(codec);
3745
3746 hda_call_check_power_status(codec, 0x01);
3747 return 0;
3748 }
3749
3750 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3751 {
3752 struct alc_spec *spec = codec->spec;
3753
3754 if (spec->unsol_event)
3755 spec->unsol_event(codec, res);
3756 }
3757
3758 #ifdef CONFIG_SND_HDA_POWER_SAVE
3759 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3760 {
3761 struct alc_spec *spec = codec->spec;
3762 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3763 }
3764 #endif
3765
3766 /*
3767 * Analog playback callbacks
3768 */
3769 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3770 struct hda_codec *codec,
3771 struct snd_pcm_substream *substream)
3772 {
3773 struct alc_spec *spec = codec->spec;
3774 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3775 hinfo);
3776 }
3777
3778 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3779 struct hda_codec *codec,
3780 unsigned int stream_tag,
3781 unsigned int format,
3782 struct snd_pcm_substream *substream)
3783 {
3784 struct alc_spec *spec = codec->spec;
3785 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3786 stream_tag, format, substream);
3787 }
3788
3789 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3790 struct hda_codec *codec,
3791 struct snd_pcm_substream *substream)
3792 {
3793 struct alc_spec *spec = codec->spec;
3794 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3795 }
3796
3797 /*
3798 * Digital out
3799 */
3800 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3801 struct hda_codec *codec,
3802 struct snd_pcm_substream *substream)
3803 {
3804 struct alc_spec *spec = codec->spec;
3805 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3806 }
3807
3808 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3809 struct hda_codec *codec,
3810 unsigned int stream_tag,
3811 unsigned int format,
3812 struct snd_pcm_substream *substream)
3813 {
3814 struct alc_spec *spec = codec->spec;
3815 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3816 stream_tag, format, substream);
3817 }
3818
3819 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3820 struct hda_codec *codec,
3821 struct snd_pcm_substream *substream)
3822 {
3823 struct alc_spec *spec = codec->spec;
3824 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3825 }
3826
3827 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3828 struct hda_codec *codec,
3829 struct snd_pcm_substream *substream)
3830 {
3831 struct alc_spec *spec = codec->spec;
3832 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3833 }
3834
3835 /*
3836 * Analog capture
3837 */
3838 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3839 struct hda_codec *codec,
3840 unsigned int stream_tag,
3841 unsigned int format,
3842 struct snd_pcm_substream *substream)
3843 {
3844 struct alc_spec *spec = codec->spec;
3845
3846 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3847 stream_tag, 0, format);
3848 return 0;
3849 }
3850
3851 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3852 struct hda_codec *codec,
3853 struct snd_pcm_substream *substream)
3854 {
3855 struct alc_spec *spec = codec->spec;
3856
3857 snd_hda_codec_cleanup_stream(codec,
3858 spec->adc_nids[substream->number + 1]);
3859 return 0;
3860 }
3861
3862 /* analog capture with dynamic dual-adc changes */
3863 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3864 struct hda_codec *codec,
3865 unsigned int stream_tag,
3866 unsigned int format,
3867 struct snd_pcm_substream *substream)
3868 {
3869 struct alc_spec *spec = codec->spec;
3870 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3871 spec->cur_adc_stream_tag = stream_tag;
3872 spec->cur_adc_format = format;
3873 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3874 return 0;
3875 }
3876
3877 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3878 struct hda_codec *codec,
3879 struct snd_pcm_substream *substream)
3880 {
3881 struct alc_spec *spec = codec->spec;
3882 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3883 spec->cur_adc = 0;
3884 return 0;
3885 }
3886
3887 static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3888 .substreams = 1,
3889 .channels_min = 2,
3890 .channels_max = 2,
3891 .nid = 0, /* fill later */
3892 .ops = {
3893 .prepare = dualmic_capture_pcm_prepare,
3894 .cleanup = dualmic_capture_pcm_cleanup
3895 },
3896 };
3897
3898 /*
3899 */
3900 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3901 .substreams = 1,
3902 .channels_min = 2,
3903 .channels_max = 8,
3904 /* NID is set in alc_build_pcms */
3905 .ops = {
3906 .open = alc880_playback_pcm_open,
3907 .prepare = alc880_playback_pcm_prepare,
3908 .cleanup = alc880_playback_pcm_cleanup
3909 },
3910 };
3911
3912 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3913 .substreams = 1,
3914 .channels_min = 2,
3915 .channels_max = 2,
3916 /* NID is set in alc_build_pcms */
3917 };
3918
3919 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3920 .substreams = 1,
3921 .channels_min = 2,
3922 .channels_max = 2,
3923 /* NID is set in alc_build_pcms */
3924 };
3925
3926 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3927 .substreams = 2, /* can be overridden */
3928 .channels_min = 2,
3929 .channels_max = 2,
3930 /* NID is set in alc_build_pcms */
3931 .ops = {
3932 .prepare = alc880_alt_capture_pcm_prepare,
3933 .cleanup = alc880_alt_capture_pcm_cleanup
3934 },
3935 };
3936
3937 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3938 .substreams = 1,
3939 .channels_min = 2,
3940 .channels_max = 2,
3941 /* NID is set in alc_build_pcms */
3942 .ops = {
3943 .open = alc880_dig_playback_pcm_open,
3944 .close = alc880_dig_playback_pcm_close,
3945 .prepare = alc880_dig_playback_pcm_prepare,
3946 .cleanup = alc880_dig_playback_pcm_cleanup
3947 },
3948 };
3949
3950 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3951 .substreams = 1,
3952 .channels_min = 2,
3953 .channels_max = 2,
3954 /* NID is set in alc_build_pcms */
3955 };
3956
3957 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3958 static struct hda_pcm_stream alc_pcm_null_stream = {
3959 .substreams = 0,
3960 .channels_min = 0,
3961 .channels_max = 0,
3962 };
3963
3964 static int alc_build_pcms(struct hda_codec *codec)
3965 {
3966 struct alc_spec *spec = codec->spec;
3967 struct hda_pcm *info = spec->pcm_rec;
3968 int i;
3969
3970 codec->num_pcms = 1;
3971 codec->pcm_info = info;
3972
3973 if (spec->no_analog)
3974 goto skip_analog;
3975
3976 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3977 "%s Analog", codec->chip_name);
3978 info->name = spec->stream_name_analog;
3979
3980 if (spec->stream_analog_playback) {
3981 if (snd_BUG_ON(!spec->multiout.dac_nids))
3982 return -EINVAL;
3983 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3984 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3985 }
3986 if (spec->stream_analog_capture) {
3987 if (snd_BUG_ON(!spec->adc_nids))
3988 return -EINVAL;
3989 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3990 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3991 }
3992
3993 if (spec->channel_mode) {
3994 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3995 for (i = 0; i < spec->num_channel_mode; i++) {
3996 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3997 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3998 }
3999 }
4000 }
4001
4002 skip_analog:
4003 /* SPDIF for stream index #1 */
4004 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4005 snprintf(spec->stream_name_digital,
4006 sizeof(spec->stream_name_digital),
4007 "%s Digital", codec->chip_name);
4008 codec->num_pcms = 2;
4009 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4010 info = spec->pcm_rec + 1;
4011 info->name = spec->stream_name_digital;
4012 if (spec->dig_out_type)
4013 info->pcm_type = spec->dig_out_type;
4014 else
4015 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4016 if (spec->multiout.dig_out_nid &&
4017 spec->stream_digital_playback) {
4018 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4019 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4020 }
4021 if (spec->dig_in_nid &&
4022 spec->stream_digital_capture) {
4023 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4024 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4025 }
4026 /* FIXME: do we need this for all Realtek codec models? */
4027 codec->spdif_status_reset = 1;
4028 }
4029
4030 if (spec->no_analog)
4031 return 0;
4032
4033 /* If the use of more than one ADC is requested for the current
4034 * model, configure a second analog capture-only PCM.
4035 */
4036 /* Additional Analaog capture for index #2 */
4037 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4038 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4039 codec->num_pcms = 3;
4040 info = spec->pcm_rec + 2;
4041 info->name = spec->stream_name_analog;
4042 if (spec->alt_dac_nid) {
4043 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4044 *spec->stream_analog_alt_playback;
4045 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4046 spec->alt_dac_nid;
4047 } else {
4048 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4049 alc_pcm_null_stream;
4050 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4051 }
4052 if (spec->num_adc_nids > 1) {
4053 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4054 *spec->stream_analog_alt_capture;
4055 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4056 spec->adc_nids[1];
4057 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4058 spec->num_adc_nids - 1;
4059 } else {
4060 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4061 alc_pcm_null_stream;
4062 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4063 }
4064 }
4065
4066 return 0;
4067 }
4068
4069 static inline void alc_shutup(struct hda_codec *codec)
4070 {
4071 snd_hda_shutup_pins(codec);
4072 }
4073
4074 static void alc_free_kctls(struct hda_codec *codec)
4075 {
4076 struct alc_spec *spec = codec->spec;
4077
4078 if (spec->kctls.list) {
4079 struct snd_kcontrol_new *kctl = spec->kctls.list;
4080 int i;
4081 for (i = 0; i < spec->kctls.used; i++)
4082 kfree(kctl[i].name);
4083 }
4084 snd_array_free(&spec->kctls);
4085 }
4086
4087 static void alc_free(struct hda_codec *codec)
4088 {
4089 struct alc_spec *spec = codec->spec;
4090
4091 if (!spec)
4092 return;
4093
4094 alc_shutup(codec);
4095 alc_free_kctls(codec);
4096 kfree(spec);
4097 snd_hda_detach_beep_device(codec);
4098 }
4099
4100 #ifdef CONFIG_SND_HDA_POWER_SAVE
4101 static void alc_power_eapd(struct hda_codec *codec)
4102 {
4103 /* We currently only handle front, HP */
4104 switch (codec->vendor_id) {
4105 case 0x10ec0260:
4106 set_eapd(codec, 0x0f, 0);
4107 set_eapd(codec, 0x10, 0);
4108 break;
4109 case 0x10ec0262:
4110 case 0x10ec0267:
4111 case 0x10ec0268:
4112 case 0x10ec0269:
4113 case 0x10ec0270:
4114 case 0x10ec0272:
4115 case 0x10ec0660:
4116 case 0x10ec0662:
4117 case 0x10ec0663:
4118 case 0x10ec0862:
4119 case 0x10ec0889:
4120 set_eapd(codec, 0x14, 0);
4121 set_eapd(codec, 0x15, 0);
4122 break;
4123 }
4124 }
4125
4126 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4127 {
4128 struct alc_spec *spec = codec->spec;
4129 alc_shutup(codec);
4130 if (spec && spec->power_hook)
4131 spec->power_hook(codec);
4132 return 0;
4133 }
4134 #endif
4135
4136 #ifdef SND_HDA_NEEDS_RESUME
4137 static int alc_resume(struct hda_codec *codec)
4138 {
4139 codec->patch_ops.init(codec);
4140 snd_hda_codec_resume_amp(codec);
4141 snd_hda_codec_resume_cache(codec);
4142 hda_call_check_power_status(codec, 0x01);
4143 return 0;
4144 }
4145 #endif
4146
4147 /*
4148 */
4149 static struct hda_codec_ops alc_patch_ops = {
4150 .build_controls = alc_build_controls,
4151 .build_pcms = alc_build_pcms,
4152 .init = alc_init,
4153 .free = alc_free,
4154 .unsol_event = alc_unsol_event,
4155 #ifdef SND_HDA_NEEDS_RESUME
4156 .resume = alc_resume,
4157 #endif
4158 #ifdef CONFIG_SND_HDA_POWER_SAVE
4159 .suspend = alc_suspend,
4160 .check_power_status = alc_check_power_status,
4161 #endif
4162 .reboot_notify = alc_shutup,
4163 };
4164
4165 /* replace the codec chip_name with the given string */
4166 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4167 {
4168 kfree(codec->chip_name);
4169 codec->chip_name = kstrdup(name, GFP_KERNEL);
4170 if (!codec->chip_name) {
4171 alc_free(codec);
4172 return -ENOMEM;
4173 }
4174 return 0;
4175 }
4176
4177 /*
4178 * Test configuration for debugging
4179 *
4180 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4181 * enum controls.
4182 */
4183 #ifdef CONFIG_SND_DEBUG
4184 static hda_nid_t alc880_test_dac_nids[4] = {
4185 0x02, 0x03, 0x04, 0x05
4186 };
4187
4188 static struct hda_input_mux alc880_test_capture_source = {
4189 .num_items = 7,
4190 .items = {
4191 { "In-1", 0x0 },
4192 { "In-2", 0x1 },
4193 { "In-3", 0x2 },
4194 { "In-4", 0x3 },
4195 { "CD", 0x4 },
4196 { "Front", 0x5 },
4197 { "Surround", 0x6 },
4198 },
4199 };
4200
4201 static struct hda_channel_mode alc880_test_modes[4] = {
4202 { 2, NULL },
4203 { 4, NULL },
4204 { 6, NULL },
4205 { 8, NULL },
4206 };
4207
4208 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4209 struct snd_ctl_elem_info *uinfo)
4210 {
4211 static char *texts[] = {
4212 "N/A", "Line Out", "HP Out",
4213 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4214 };
4215 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4216 uinfo->count = 1;
4217 uinfo->value.enumerated.items = 8;
4218 if (uinfo->value.enumerated.item >= 8)
4219 uinfo->value.enumerated.item = 7;
4220 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4221 return 0;
4222 }
4223
4224 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4225 struct snd_ctl_elem_value *ucontrol)
4226 {
4227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4228 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4229 unsigned int pin_ctl, item = 0;
4230
4231 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4232 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4233 if (pin_ctl & AC_PINCTL_OUT_EN) {
4234 if (pin_ctl & AC_PINCTL_HP_EN)
4235 item = 2;
4236 else
4237 item = 1;
4238 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4239 switch (pin_ctl & AC_PINCTL_VREFEN) {
4240 case AC_PINCTL_VREF_HIZ: item = 3; break;
4241 case AC_PINCTL_VREF_50: item = 4; break;
4242 case AC_PINCTL_VREF_GRD: item = 5; break;
4243 case AC_PINCTL_VREF_80: item = 6; break;
4244 case AC_PINCTL_VREF_100: item = 7; break;
4245 }
4246 }
4247 ucontrol->value.enumerated.item[0] = item;
4248 return 0;
4249 }
4250
4251 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4252 struct snd_ctl_elem_value *ucontrol)
4253 {
4254 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4255 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4256 static unsigned int ctls[] = {
4257 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4258 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4259 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4260 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4261 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4262 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4263 };
4264 unsigned int old_ctl, new_ctl;
4265
4266 old_ctl = snd_hda_codec_read(codec, nid, 0,
4267 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4268 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4269 if (old_ctl != new_ctl) {
4270 int val;
4271 snd_hda_codec_write_cache(codec, nid, 0,
4272 AC_VERB_SET_PIN_WIDGET_CONTROL,
4273 new_ctl);
4274 val = ucontrol->value.enumerated.item[0] >= 3 ?
4275 HDA_AMP_MUTE : 0;
4276 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4277 HDA_AMP_MUTE, val);
4278 return 1;
4279 }
4280 return 0;
4281 }
4282
4283 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4284 struct snd_ctl_elem_info *uinfo)
4285 {
4286 static char *texts[] = {
4287 "Front", "Surround", "CLFE", "Side"
4288 };
4289 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4290 uinfo->count = 1;
4291 uinfo->value.enumerated.items = 4;
4292 if (uinfo->value.enumerated.item >= 4)
4293 uinfo->value.enumerated.item = 3;
4294 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4295 return 0;
4296 }
4297
4298 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4299 struct snd_ctl_elem_value *ucontrol)
4300 {
4301 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4302 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4303 unsigned int sel;
4304
4305 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4306 ucontrol->value.enumerated.item[0] = sel & 3;
4307 return 0;
4308 }
4309
4310 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4311 struct snd_ctl_elem_value *ucontrol)
4312 {
4313 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4314 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4315 unsigned int sel;
4316
4317 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4318 if (ucontrol->value.enumerated.item[0] != sel) {
4319 sel = ucontrol->value.enumerated.item[0] & 3;
4320 snd_hda_codec_write_cache(codec, nid, 0,
4321 AC_VERB_SET_CONNECT_SEL, sel);
4322 return 1;
4323 }
4324 return 0;
4325 }
4326
4327 #define PIN_CTL_TEST(xname,nid) { \
4328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4329 .name = xname, \
4330 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4331 .info = alc_test_pin_ctl_info, \
4332 .get = alc_test_pin_ctl_get, \
4333 .put = alc_test_pin_ctl_put, \
4334 .private_value = nid \
4335 }
4336
4337 #define PIN_SRC_TEST(xname,nid) { \
4338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4339 .name = xname, \
4340 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4341 .info = alc_test_pin_src_info, \
4342 .get = alc_test_pin_src_get, \
4343 .put = alc_test_pin_src_put, \
4344 .private_value = nid \
4345 }
4346
4347 static struct snd_kcontrol_new alc880_test_mixer[] = {
4348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4349 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4350 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4351 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4352 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4353 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4354 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4355 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4356 PIN_CTL_TEST("Front Pin Mode", 0x14),
4357 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4358 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4359 PIN_CTL_TEST("Side Pin Mode", 0x17),
4360 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4361 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4362 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4363 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4364 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4365 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4366 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4367 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4368 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4369 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4370 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4371 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4372 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4373 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4374 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4375 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4376 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4377 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4378 {
4379 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4380 .name = "Channel Mode",
4381 .info = alc_ch_mode_info,
4382 .get = alc_ch_mode_get,
4383 .put = alc_ch_mode_put,
4384 },
4385 { } /* end */
4386 };
4387
4388 static struct hda_verb alc880_test_init_verbs[] = {
4389 /* Unmute inputs of 0x0c - 0x0f */
4390 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4396 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4397 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4398 /* Vol output for 0x0c-0x0f */
4399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4400 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4401 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4403 /* Set output pins 0x14-0x17 */
4404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4406 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4407 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4408 /* Unmute output pins 0x14-0x17 */
4409 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4410 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4411 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4412 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4413 /* Set input pins 0x18-0x1c */
4414 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4415 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4416 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4417 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4418 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4419 /* Mute input pins 0x18-0x1b */
4420 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4421 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4422 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4423 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4424 /* ADC set up */
4425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4426 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4427 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4428 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4429 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4430 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4431 /* Analog input/passthru */
4432 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4433 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4434 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4435 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4436 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4437 { }
4438 };
4439 #endif
4440
4441 /*
4442 */
4443
4444 static const char *alc880_models[ALC880_MODEL_LAST] = {
4445 [ALC880_3ST] = "3stack",
4446 [ALC880_TCL_S700] = "tcl",
4447 [ALC880_3ST_DIG] = "3stack-digout",
4448 [ALC880_CLEVO] = "clevo",
4449 [ALC880_5ST] = "5stack",
4450 [ALC880_5ST_DIG] = "5stack-digout",
4451 [ALC880_W810] = "w810",
4452 [ALC880_Z71V] = "z71v",
4453 [ALC880_6ST] = "6stack",
4454 [ALC880_6ST_DIG] = "6stack-digout",
4455 [ALC880_ASUS] = "asus",
4456 [ALC880_ASUS_W1V] = "asus-w1v",
4457 [ALC880_ASUS_DIG] = "asus-dig",
4458 [ALC880_ASUS_DIG2] = "asus-dig2",
4459 [ALC880_UNIWILL_DIG] = "uniwill",
4460 [ALC880_UNIWILL_P53] = "uniwill-p53",
4461 [ALC880_FUJITSU] = "fujitsu",
4462 [ALC880_F1734] = "F1734",
4463 [ALC880_LG] = "lg",
4464 [ALC880_LG_LW] = "lg-lw",
4465 [ALC880_MEDION_RIM] = "medion",
4466 #ifdef CONFIG_SND_DEBUG
4467 [ALC880_TEST] = "test",
4468 #endif
4469 [ALC880_AUTO] = "auto",
4470 };
4471
4472 static struct snd_pci_quirk alc880_cfg_tbl[] = {
4473 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4474 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4475 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4476 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4477 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4478 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4479 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4480 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4481 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4482 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4483 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4484 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4485 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4486 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4487 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4488 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4489 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4490 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4491 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4492 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4493 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4494 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4495 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4496 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4497 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4498 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4499 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4500 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4501 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4502 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4503 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4504 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4505 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4506 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4507 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4508 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4509 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4510 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4511 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4512 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4513 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4514 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4515 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4516 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4517 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4518 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4519 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4520 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4521 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4522 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4523 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4524 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4525 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4526 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4527 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4528 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4529 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4530 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4531 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4532 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4533 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4534 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4535 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4536 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4537 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4538 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4539 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4540 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4541 /* default Intel */
4542 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4543 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4544 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4545 {}
4546 };
4547
4548 /*
4549 * ALC880 codec presets
4550 */
4551 static struct alc_config_preset alc880_presets[] = {
4552 [ALC880_3ST] = {
4553 .mixers = { alc880_three_stack_mixer },
4554 .init_verbs = { alc880_volume_init_verbs,
4555 alc880_pin_3stack_init_verbs },
4556 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4557 .dac_nids = alc880_dac_nids,
4558 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4559 .channel_mode = alc880_threestack_modes,
4560 .need_dac_fix = 1,
4561 .input_mux = &alc880_capture_source,
4562 },
4563 [ALC880_3ST_DIG] = {
4564 .mixers = { alc880_three_stack_mixer },
4565 .init_verbs = { alc880_volume_init_verbs,
4566 alc880_pin_3stack_init_verbs },
4567 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4568 .dac_nids = alc880_dac_nids,
4569 .dig_out_nid = ALC880_DIGOUT_NID,
4570 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4571 .channel_mode = alc880_threestack_modes,
4572 .need_dac_fix = 1,
4573 .input_mux = &alc880_capture_source,
4574 },
4575 [ALC880_TCL_S700] = {
4576 .mixers = { alc880_tcl_s700_mixer },
4577 .init_verbs = { alc880_volume_init_verbs,
4578 alc880_pin_tcl_S700_init_verbs,
4579 alc880_gpio2_init_verbs },
4580 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4581 .dac_nids = alc880_dac_nids,
4582 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4583 .num_adc_nids = 1, /* single ADC */
4584 .hp_nid = 0x03,
4585 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4586 .channel_mode = alc880_2_jack_modes,
4587 .input_mux = &alc880_capture_source,
4588 },
4589 [ALC880_5ST] = {
4590 .mixers = { alc880_three_stack_mixer,
4591 alc880_five_stack_mixer},
4592 .init_verbs = { alc880_volume_init_verbs,
4593 alc880_pin_5stack_init_verbs },
4594 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4595 .dac_nids = alc880_dac_nids,
4596 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4597 .channel_mode = alc880_fivestack_modes,
4598 .input_mux = &alc880_capture_source,
4599 },
4600 [ALC880_5ST_DIG] = {
4601 .mixers = { alc880_three_stack_mixer,
4602 alc880_five_stack_mixer },
4603 .init_verbs = { alc880_volume_init_verbs,
4604 alc880_pin_5stack_init_verbs },
4605 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4606 .dac_nids = alc880_dac_nids,
4607 .dig_out_nid = ALC880_DIGOUT_NID,
4608 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4609 .channel_mode = alc880_fivestack_modes,
4610 .input_mux = &alc880_capture_source,
4611 },
4612 [ALC880_6ST] = {
4613 .mixers = { alc880_six_stack_mixer },
4614 .init_verbs = { alc880_volume_init_verbs,
4615 alc880_pin_6stack_init_verbs },
4616 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4617 .dac_nids = alc880_6st_dac_nids,
4618 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4619 .channel_mode = alc880_sixstack_modes,
4620 .input_mux = &alc880_6stack_capture_source,
4621 },
4622 [ALC880_6ST_DIG] = {
4623 .mixers = { alc880_six_stack_mixer },
4624 .init_verbs = { alc880_volume_init_verbs,
4625 alc880_pin_6stack_init_verbs },
4626 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4627 .dac_nids = alc880_6st_dac_nids,
4628 .dig_out_nid = ALC880_DIGOUT_NID,
4629 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4630 .channel_mode = alc880_sixstack_modes,
4631 .input_mux = &alc880_6stack_capture_source,
4632 },
4633 [ALC880_W810] = {
4634 .mixers = { alc880_w810_base_mixer },
4635 .init_verbs = { alc880_volume_init_verbs,
4636 alc880_pin_w810_init_verbs,
4637 alc880_gpio2_init_verbs },
4638 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4639 .dac_nids = alc880_w810_dac_nids,
4640 .dig_out_nid = ALC880_DIGOUT_NID,
4641 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4642 .channel_mode = alc880_w810_modes,
4643 .input_mux = &alc880_capture_source,
4644 },
4645 [ALC880_Z71V] = {
4646 .mixers = { alc880_z71v_mixer },
4647 .init_verbs = { alc880_volume_init_verbs,
4648 alc880_pin_z71v_init_verbs },
4649 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4650 .dac_nids = alc880_z71v_dac_nids,
4651 .dig_out_nid = ALC880_DIGOUT_NID,
4652 .hp_nid = 0x03,
4653 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4654 .channel_mode = alc880_2_jack_modes,
4655 .input_mux = &alc880_capture_source,
4656 },
4657 [ALC880_F1734] = {
4658 .mixers = { alc880_f1734_mixer },
4659 .init_verbs = { alc880_volume_init_verbs,
4660 alc880_pin_f1734_init_verbs },
4661 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4662 .dac_nids = alc880_f1734_dac_nids,
4663 .hp_nid = 0x02,
4664 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4665 .channel_mode = alc880_2_jack_modes,
4666 .input_mux = &alc880_f1734_capture_source,
4667 .unsol_event = alc880_uniwill_p53_unsol_event,
4668 .setup = alc880_uniwill_p53_setup,
4669 .init_hook = alc_automute_amp,
4670 },
4671 [ALC880_ASUS] = {
4672 .mixers = { alc880_asus_mixer },
4673 .init_verbs = { alc880_volume_init_verbs,
4674 alc880_pin_asus_init_verbs,
4675 alc880_gpio1_init_verbs },
4676 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4677 .dac_nids = alc880_asus_dac_nids,
4678 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4679 .channel_mode = alc880_asus_modes,
4680 .need_dac_fix = 1,
4681 .input_mux = &alc880_capture_source,
4682 },
4683 [ALC880_ASUS_DIG] = {
4684 .mixers = { alc880_asus_mixer },
4685 .init_verbs = { alc880_volume_init_verbs,
4686 alc880_pin_asus_init_verbs,
4687 alc880_gpio1_init_verbs },
4688 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4689 .dac_nids = alc880_asus_dac_nids,
4690 .dig_out_nid = ALC880_DIGOUT_NID,
4691 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4692 .channel_mode = alc880_asus_modes,
4693 .need_dac_fix = 1,
4694 .input_mux = &alc880_capture_source,
4695 },
4696 [ALC880_ASUS_DIG2] = {
4697 .mixers = { alc880_asus_mixer },
4698 .init_verbs = { alc880_volume_init_verbs,
4699 alc880_pin_asus_init_verbs,
4700 alc880_gpio2_init_verbs }, /* use GPIO2 */
4701 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4702 .dac_nids = alc880_asus_dac_nids,
4703 .dig_out_nid = ALC880_DIGOUT_NID,
4704 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4705 .channel_mode = alc880_asus_modes,
4706 .need_dac_fix = 1,
4707 .input_mux = &alc880_capture_source,
4708 },
4709 [ALC880_ASUS_W1V] = {
4710 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4711 .init_verbs = { alc880_volume_init_verbs,
4712 alc880_pin_asus_init_verbs,
4713 alc880_gpio1_init_verbs },
4714 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4715 .dac_nids = alc880_asus_dac_nids,
4716 .dig_out_nid = ALC880_DIGOUT_NID,
4717 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4718 .channel_mode = alc880_asus_modes,
4719 .need_dac_fix = 1,
4720 .input_mux = &alc880_capture_source,
4721 },
4722 [ALC880_UNIWILL_DIG] = {
4723 .mixers = { alc880_asus_mixer },
4724 .init_verbs = { alc880_volume_init_verbs,
4725 alc880_pin_asus_init_verbs },
4726 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4727 .dac_nids = alc880_asus_dac_nids,
4728 .dig_out_nid = ALC880_DIGOUT_NID,
4729 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4730 .channel_mode = alc880_asus_modes,
4731 .need_dac_fix = 1,
4732 .input_mux = &alc880_capture_source,
4733 },
4734 [ALC880_UNIWILL] = {
4735 .mixers = { alc880_uniwill_mixer },
4736 .init_verbs = { alc880_volume_init_verbs,
4737 alc880_uniwill_init_verbs },
4738 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4739 .dac_nids = alc880_asus_dac_nids,
4740 .dig_out_nid = ALC880_DIGOUT_NID,
4741 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4742 .channel_mode = alc880_threestack_modes,
4743 .need_dac_fix = 1,
4744 .input_mux = &alc880_capture_source,
4745 .unsol_event = alc880_uniwill_unsol_event,
4746 .setup = alc880_uniwill_setup,
4747 .init_hook = alc880_uniwill_init_hook,
4748 },
4749 [ALC880_UNIWILL_P53] = {
4750 .mixers = { alc880_uniwill_p53_mixer },
4751 .init_verbs = { alc880_volume_init_verbs,
4752 alc880_uniwill_p53_init_verbs },
4753 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4754 .dac_nids = alc880_asus_dac_nids,
4755 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4756 .channel_mode = alc880_threestack_modes,
4757 .input_mux = &alc880_capture_source,
4758 .unsol_event = alc880_uniwill_p53_unsol_event,
4759 .setup = alc880_uniwill_p53_setup,
4760 .init_hook = alc_automute_amp,
4761 },
4762 [ALC880_FUJITSU] = {
4763 .mixers = { alc880_fujitsu_mixer },
4764 .init_verbs = { alc880_volume_init_verbs,
4765 alc880_uniwill_p53_init_verbs,
4766 alc880_beep_init_verbs },
4767 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4768 .dac_nids = alc880_dac_nids,
4769 .dig_out_nid = ALC880_DIGOUT_NID,
4770 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4771 .channel_mode = alc880_2_jack_modes,
4772 .input_mux = &alc880_capture_source,
4773 .unsol_event = alc880_uniwill_p53_unsol_event,
4774 .setup = alc880_uniwill_p53_setup,
4775 .init_hook = alc_automute_amp,
4776 },
4777 [ALC880_CLEVO] = {
4778 .mixers = { alc880_three_stack_mixer },
4779 .init_verbs = { alc880_volume_init_verbs,
4780 alc880_pin_clevo_init_verbs },
4781 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4782 .dac_nids = alc880_dac_nids,
4783 .hp_nid = 0x03,
4784 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4785 .channel_mode = alc880_threestack_modes,
4786 .need_dac_fix = 1,
4787 .input_mux = &alc880_capture_source,
4788 },
4789 [ALC880_LG] = {
4790 .mixers = { alc880_lg_mixer },
4791 .init_verbs = { alc880_volume_init_verbs,
4792 alc880_lg_init_verbs },
4793 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4794 .dac_nids = alc880_lg_dac_nids,
4795 .dig_out_nid = ALC880_DIGOUT_NID,
4796 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4797 .channel_mode = alc880_lg_ch_modes,
4798 .need_dac_fix = 1,
4799 .input_mux = &alc880_lg_capture_source,
4800 .unsol_event = alc_automute_amp_unsol_event,
4801 .setup = alc880_lg_setup,
4802 .init_hook = alc_automute_amp,
4803 #ifdef CONFIG_SND_HDA_POWER_SAVE
4804 .loopbacks = alc880_lg_loopbacks,
4805 #endif
4806 },
4807 [ALC880_LG_LW] = {
4808 .mixers = { alc880_lg_lw_mixer },
4809 .init_verbs = { alc880_volume_init_verbs,
4810 alc880_lg_lw_init_verbs },
4811 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4812 .dac_nids = alc880_dac_nids,
4813 .dig_out_nid = ALC880_DIGOUT_NID,
4814 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4815 .channel_mode = alc880_lg_lw_modes,
4816 .input_mux = &alc880_lg_lw_capture_source,
4817 .unsol_event = alc_automute_amp_unsol_event,
4818 .setup = alc880_lg_lw_setup,
4819 .init_hook = alc_automute_amp,
4820 },
4821 [ALC880_MEDION_RIM] = {
4822 .mixers = { alc880_medion_rim_mixer },
4823 .init_verbs = { alc880_volume_init_verbs,
4824 alc880_medion_rim_init_verbs,
4825 alc_gpio2_init_verbs },
4826 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4827 .dac_nids = alc880_dac_nids,
4828 .dig_out_nid = ALC880_DIGOUT_NID,
4829 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4830 .channel_mode = alc880_2_jack_modes,
4831 .input_mux = &alc880_medion_rim_capture_source,
4832 .unsol_event = alc880_medion_rim_unsol_event,
4833 .setup = alc880_medion_rim_setup,
4834 .init_hook = alc880_medion_rim_automute,
4835 },
4836 #ifdef CONFIG_SND_DEBUG
4837 [ALC880_TEST] = {
4838 .mixers = { alc880_test_mixer },
4839 .init_verbs = { alc880_test_init_verbs },
4840 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4841 .dac_nids = alc880_test_dac_nids,
4842 .dig_out_nid = ALC880_DIGOUT_NID,
4843 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4844 .channel_mode = alc880_test_modes,
4845 .input_mux = &alc880_test_capture_source,
4846 },
4847 #endif
4848 };
4849
4850 /*
4851 * Automatic parse of I/O pins from the BIOS configuration
4852 */
4853
4854 enum {
4855 ALC_CTL_WIDGET_VOL,
4856 ALC_CTL_WIDGET_MUTE,
4857 ALC_CTL_BIND_MUTE,
4858 };
4859 static struct snd_kcontrol_new alc880_control_templates[] = {
4860 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4861 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4862 HDA_BIND_MUTE(NULL, 0, 0, 0),
4863 };
4864
4865 /* add dynamic controls */
4866 static int add_control(struct alc_spec *spec, int type, const char *name,
4867 int cidx, unsigned long val)
4868 {
4869 struct snd_kcontrol_new *knew;
4870
4871 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4872 knew = snd_array_new(&spec->kctls);
4873 if (!knew)
4874 return -ENOMEM;
4875 *knew = alc880_control_templates[type];
4876 knew->name = kstrdup(name, GFP_KERNEL);
4877 if (!knew->name)
4878 return -ENOMEM;
4879 knew->index = cidx;
4880 if (get_amp_nid_(val))
4881 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4882 knew->private_value = val;
4883 return 0;
4884 }
4885
4886 static int add_control_with_pfx(struct alc_spec *spec, int type,
4887 const char *pfx, const char *dir,
4888 const char *sfx, int cidx, unsigned long val)
4889 {
4890 char name[32];
4891 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4892 return add_control(spec, type, name, cidx, val);
4893 }
4894
4895 #define add_pb_vol_ctrl(spec, type, pfx, val) \
4896 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
4897 #define add_pb_sw_ctrl(spec, type, pfx, val) \
4898 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
4899 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
4900 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
4901 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
4902 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
4903
4904 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4905 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4906 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4907 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4908 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4909 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4910 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4911 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4912 #define ALC880_PIN_CD_NID 0x1c
4913
4914 /* fill in the dac_nids table from the parsed pin configuration */
4915 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4916 const struct auto_pin_cfg *cfg)
4917 {
4918 hda_nid_t nid;
4919 int assigned[4];
4920 int i, j;
4921
4922 memset(assigned, 0, sizeof(assigned));
4923 spec->multiout.dac_nids = spec->private_dac_nids;
4924
4925 /* check the pins hardwired to audio widget */
4926 for (i = 0; i < cfg->line_outs; i++) {
4927 nid = cfg->line_out_pins[i];
4928 if (alc880_is_fixed_pin(nid)) {
4929 int idx = alc880_fixed_pin_idx(nid);
4930 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4931 assigned[idx] = 1;
4932 }
4933 }
4934 /* left pins can be connect to any audio widget */
4935 for (i = 0; i < cfg->line_outs; i++) {
4936 nid = cfg->line_out_pins[i];
4937 if (alc880_is_fixed_pin(nid))
4938 continue;
4939 /* search for an empty channel */
4940 for (j = 0; j < cfg->line_outs; j++) {
4941 if (!assigned[j]) {
4942 spec->multiout.dac_nids[i] =
4943 alc880_idx_to_dac(j);
4944 assigned[j] = 1;
4945 break;
4946 }
4947 }
4948 }
4949 spec->multiout.num_dacs = cfg->line_outs;
4950 return 0;
4951 }
4952
4953 /* add playback controls from the parsed DAC table */
4954 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4955 const struct auto_pin_cfg *cfg)
4956 {
4957 static const char *chname[4] = {
4958 "Front", "Surround", NULL /*CLFE*/, "Side"
4959 };
4960 hda_nid_t nid;
4961 int i, err;
4962
4963 for (i = 0; i < cfg->line_outs; i++) {
4964 if (!spec->multiout.dac_nids[i])
4965 continue;
4966 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4967 if (i == 2) {
4968 /* Center/LFE */
4969 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4970 "Center",
4971 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4972 HDA_OUTPUT));
4973 if (err < 0)
4974 return err;
4975 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4976 "LFE",
4977 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4978 HDA_OUTPUT));
4979 if (err < 0)
4980 return err;
4981 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4982 "Center",
4983 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4984 HDA_INPUT));
4985 if (err < 0)
4986 return err;
4987 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4988 "LFE",
4989 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4990 HDA_INPUT));
4991 if (err < 0)
4992 return err;
4993 } else {
4994 const char *pfx;
4995 if (cfg->line_outs == 1 &&
4996 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4997 pfx = "Speaker";
4998 else
4999 pfx = chname[i];
5000 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5001 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5002 HDA_OUTPUT));
5003 if (err < 0)
5004 return err;
5005 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5006 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5007 HDA_INPUT));
5008 if (err < 0)
5009 return err;
5010 }
5011 }
5012 return 0;
5013 }
5014
5015 /* add playback controls for speaker and HP outputs */
5016 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5017 const char *pfx)
5018 {
5019 hda_nid_t nid;
5020 int err;
5021
5022 if (!pin)
5023 return 0;
5024
5025 if (alc880_is_fixed_pin(pin)) {
5026 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5027 /* specify the DAC as the extra output */
5028 if (!spec->multiout.hp_nid)
5029 spec->multiout.hp_nid = nid;
5030 else
5031 spec->multiout.extra_out_nid[0] = nid;
5032 /* control HP volume/switch on the output mixer amp */
5033 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5034 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5035 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5036 if (err < 0)
5037 return err;
5038 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5039 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5040 if (err < 0)
5041 return err;
5042 } else if (alc880_is_multi_pin(pin)) {
5043 /* set manual connection */
5044 /* we have only a switch on HP-out PIN */
5045 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5046 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5047 if (err < 0)
5048 return err;
5049 }
5050 return 0;
5051 }
5052
5053 /* create input playback/capture controls for the given pin */
5054 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5055 const char *ctlname, int ctlidx,
5056 int idx, hda_nid_t mix_nid)
5057 {
5058 int err;
5059
5060 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5061 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5062 if (err < 0)
5063 return err;
5064 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5065 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5066 if (err < 0)
5067 return err;
5068 return 0;
5069 }
5070
5071 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5072 {
5073 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5074 return (pincap & AC_PINCAP_IN) != 0;
5075 }
5076
5077 /* create playback/capture controls for input pins */
5078 static int alc_auto_create_input_ctls(struct hda_codec *codec,
5079 const struct auto_pin_cfg *cfg,
5080 hda_nid_t mixer,
5081 hda_nid_t cap1, hda_nid_t cap2)
5082 {
5083 struct alc_spec *spec = codec->spec;
5084 struct hda_input_mux *imux = &spec->private_imux[0];
5085 int i, err, idx, type, type_idx = 0;
5086
5087 for (i = 0; i < cfg->num_inputs; i++) {
5088 hda_nid_t pin;
5089 const char *label;
5090
5091 pin = cfg->inputs[i].pin;
5092 if (!alc_is_input_pin(codec, pin))
5093 continue;
5094
5095 type = cfg->inputs[i].type;
5096 if (i > 0 && type == cfg->inputs[i - 1].type)
5097 type_idx++;
5098 else
5099 type_idx = 0;
5100 label = hda_get_autocfg_input_label(codec, cfg, i);
5101 if (mixer) {
5102 idx = get_connection_index(codec, mixer, pin);
5103 if (idx >= 0) {
5104 err = new_analog_input(spec, pin,
5105 label, type_idx,
5106 idx, mixer);
5107 if (err < 0)
5108 return err;
5109 }
5110 }
5111
5112 if (!cap1)
5113 continue;
5114 idx = get_connection_index(codec, cap1, pin);
5115 if (idx < 0 && cap2)
5116 idx = get_connection_index(codec, cap2, pin);
5117 if (idx >= 0)
5118 snd_hda_add_imux_item(imux, label, idx, NULL);
5119 }
5120 return 0;
5121 }
5122
5123 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5124 const struct auto_pin_cfg *cfg)
5125 {
5126 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5127 }
5128
5129 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5130 unsigned int pin_type)
5131 {
5132 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5133 pin_type);
5134 /* unmute pin */
5135 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5136 AMP_OUT_UNMUTE);
5137 }
5138
5139 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5140 hda_nid_t nid, int pin_type,
5141 int dac_idx)
5142 {
5143 alc_set_pin_output(codec, nid, pin_type);
5144 /* need the manual connection? */
5145 if (alc880_is_multi_pin(nid)) {
5146 struct alc_spec *spec = codec->spec;
5147 int idx = alc880_multi_pin_idx(nid);
5148 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5149 AC_VERB_SET_CONNECT_SEL,
5150 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5151 }
5152 }
5153
5154 static int get_pin_type(int line_out_type)
5155 {
5156 if (line_out_type == AUTO_PIN_HP_OUT)
5157 return PIN_HP;
5158 else
5159 return PIN_OUT;
5160 }
5161
5162 static void alc880_auto_init_multi_out(struct hda_codec *codec)
5163 {
5164 struct alc_spec *spec = codec->spec;
5165 int i;
5166
5167 for (i = 0; i < spec->autocfg.line_outs; i++) {
5168 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5169 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5170 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5171 }
5172 }
5173
5174 static void alc880_auto_init_extra_out(struct hda_codec *codec)
5175 {
5176 struct alc_spec *spec = codec->spec;
5177 hda_nid_t pin;
5178
5179 pin = spec->autocfg.speaker_pins[0];
5180 if (pin) /* connect to front */
5181 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5182 pin = spec->autocfg.hp_pins[0];
5183 if (pin) /* connect to front */
5184 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5185 }
5186
5187 static void alc880_auto_init_analog_input(struct hda_codec *codec)
5188 {
5189 struct alc_spec *spec = codec->spec;
5190 struct auto_pin_cfg *cfg = &spec->autocfg;
5191 int i;
5192
5193 for (i = 0; i < cfg->num_inputs; i++) {
5194 hda_nid_t nid = cfg->inputs[i].pin;
5195 if (alc_is_input_pin(codec, nid)) {
5196 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5197 if (nid != ALC880_PIN_CD_NID &&
5198 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5199 snd_hda_codec_write(codec, nid, 0,
5200 AC_VERB_SET_AMP_GAIN_MUTE,
5201 AMP_OUT_MUTE);
5202 }
5203 }
5204 }
5205
5206 static void alc880_auto_init_input_src(struct hda_codec *codec)
5207 {
5208 struct alc_spec *spec = codec->spec;
5209 int c;
5210
5211 for (c = 0; c < spec->num_adc_nids; c++) {
5212 unsigned int mux_idx;
5213 const struct hda_input_mux *imux;
5214 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5215 imux = &spec->input_mux[mux_idx];
5216 if (!imux->num_items && mux_idx > 0)
5217 imux = &spec->input_mux[0];
5218 if (imux)
5219 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5220 AC_VERB_SET_CONNECT_SEL,
5221 imux->items[0].index);
5222 }
5223 }
5224
5225 /* parse the BIOS configuration and set up the alc_spec */
5226 /* return 1 if successful, 0 if the proper config is not found,
5227 * or a negative error code
5228 */
5229 static int alc880_parse_auto_config(struct hda_codec *codec)
5230 {
5231 struct alc_spec *spec = codec->spec;
5232 int err;
5233 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5234
5235 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5236 alc880_ignore);
5237 if (err < 0)
5238 return err;
5239 if (!spec->autocfg.line_outs)
5240 return 0; /* can't find valid BIOS pin config */
5241
5242 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5243 if (err < 0)
5244 return err;
5245 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5246 if (err < 0)
5247 return err;
5248 err = alc880_auto_create_extra_out(spec,
5249 spec->autocfg.speaker_pins[0],
5250 "Speaker");
5251 if (err < 0)
5252 return err;
5253 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5254 "Headphone");
5255 if (err < 0)
5256 return err;
5257 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5258 if (err < 0)
5259 return err;
5260
5261 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5262
5263 alc_auto_parse_digital(codec);
5264
5265 if (spec->kctls.list)
5266 add_mixer(spec, spec->kctls.list);
5267
5268 add_verb(spec, alc880_volume_init_verbs);
5269
5270 spec->num_mux_defs = 1;
5271 spec->input_mux = &spec->private_imux[0];
5272
5273 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5274
5275 return 1;
5276 }
5277
5278 /* additional initialization for auto-configuration model */
5279 static void alc880_auto_init(struct hda_codec *codec)
5280 {
5281 struct alc_spec *spec = codec->spec;
5282 alc880_auto_init_multi_out(codec);
5283 alc880_auto_init_extra_out(codec);
5284 alc880_auto_init_analog_input(codec);
5285 alc880_auto_init_input_src(codec);
5286 alc_auto_init_digital(codec);
5287 if (spec->unsol_event)
5288 alc_inithook(codec);
5289 }
5290
5291 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5292 * one of two digital mic pins, e.g. on ALC272
5293 */
5294 static void fixup_automic_adc(struct hda_codec *codec)
5295 {
5296 struct alc_spec *spec = codec->spec;
5297 int i;
5298
5299 for (i = 0; i < spec->num_adc_nids; i++) {
5300 hda_nid_t cap = spec->capsrc_nids ?
5301 spec->capsrc_nids[i] : spec->adc_nids[i];
5302 int iidx, eidx;
5303
5304 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5305 if (iidx < 0)
5306 continue;
5307 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5308 if (eidx < 0)
5309 continue;
5310 spec->int_mic.mux_idx = iidx;
5311 spec->ext_mic.mux_idx = eidx;
5312 if (spec->capsrc_nids)
5313 spec->capsrc_nids += i;
5314 spec->adc_nids += i;
5315 spec->num_adc_nids = 1;
5316 return;
5317 }
5318 snd_printd(KERN_INFO "hda_codec: %s: "
5319 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5320 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5321 spec->auto_mic = 0; /* disable auto-mic to be sure */
5322 }
5323
5324 /* select or unmute the given capsrc route */
5325 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5326 int idx)
5327 {
5328 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5329 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5330 HDA_AMP_MUTE, 0);
5331 } else {
5332 snd_hda_codec_write_cache(codec, cap, 0,
5333 AC_VERB_SET_CONNECT_SEL, idx);
5334 }
5335 }
5336
5337 /* set the default connection to that pin */
5338 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5339 {
5340 struct alc_spec *spec = codec->spec;
5341 int i;
5342
5343 for (i = 0; i < spec->num_adc_nids; i++) {
5344 hda_nid_t cap = spec->capsrc_nids ?
5345 spec->capsrc_nids[i] : spec->adc_nids[i];
5346 int idx;
5347
5348 idx = get_connection_index(codec, cap, pin);
5349 if (idx < 0)
5350 continue;
5351 select_or_unmute_capsrc(codec, cap, idx);
5352 return i; /* return the found index */
5353 }
5354 return -1; /* not found */
5355 }
5356
5357 /* choose the ADC/MUX containing the input pin and initialize the setup */
5358 static void fixup_single_adc(struct hda_codec *codec)
5359 {
5360 struct alc_spec *spec = codec->spec;
5361 struct auto_pin_cfg *cfg = &spec->autocfg;
5362 int i;
5363
5364 /* search for the input pin; there must be only one */
5365 if (cfg->num_inputs != 1)
5366 return;
5367 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5368 if (i >= 0) {
5369 /* use only this ADC */
5370 if (spec->capsrc_nids)
5371 spec->capsrc_nids += i;
5372 spec->adc_nids += i;
5373 spec->num_adc_nids = 1;
5374 }
5375 }
5376
5377 /* initialize dual adcs */
5378 static void fixup_dual_adc_switch(struct hda_codec *codec)
5379 {
5380 struct alc_spec *spec = codec->spec;
5381 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5382 init_capsrc_for_pin(codec, spec->int_mic.pin);
5383 }
5384
5385 static void set_capture_mixer(struct hda_codec *codec)
5386 {
5387 struct alc_spec *spec = codec->spec;
5388 static struct snd_kcontrol_new *caps[2][3] = {
5389 { alc_capture_mixer_nosrc1,
5390 alc_capture_mixer_nosrc2,
5391 alc_capture_mixer_nosrc3 },
5392 { alc_capture_mixer1,
5393 alc_capture_mixer2,
5394 alc_capture_mixer3 },
5395 };
5396 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5397 int mux = 0;
5398 int num_adcs = spec->num_adc_nids;
5399 if (spec->dual_adc_switch)
5400 fixup_dual_adc_switch(codec);
5401 else if (spec->auto_mic)
5402 fixup_automic_adc(codec);
5403 else if (spec->input_mux) {
5404 if (spec->input_mux->num_items > 1)
5405 mux = 1;
5406 else if (spec->input_mux->num_items == 1)
5407 fixup_single_adc(codec);
5408 }
5409 if (spec->dual_adc_switch)
5410 num_adcs = 1;
5411 spec->cap_mixer = caps[mux][num_adcs - 1];
5412 }
5413 }
5414
5415 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5416 static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5417 int num_nids)
5418 {
5419 struct alc_spec *spec = codec->spec;
5420 struct auto_pin_cfg *cfg = &spec->autocfg;
5421 int n;
5422 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5423
5424 for (n = 0; n < num_nids; n++) {
5425 hda_nid_t adc, cap;
5426 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5427 int nconns, i, j;
5428
5429 adc = nids[n];
5430 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5431 continue;
5432 cap = adc;
5433 nconns = snd_hda_get_connections(codec, cap, conn,
5434 ARRAY_SIZE(conn));
5435 if (nconns == 1) {
5436 cap = conn[0];
5437 nconns = snd_hda_get_connections(codec, cap, conn,
5438 ARRAY_SIZE(conn));
5439 }
5440 if (nconns <= 0)
5441 continue;
5442 if (!fallback_adc) {
5443 fallback_adc = adc;
5444 fallback_cap = cap;
5445 }
5446 for (i = 0; i < cfg->num_inputs; i++) {
5447 hda_nid_t nid = cfg->inputs[i].pin;
5448 for (j = 0; j < nconns; j++) {
5449 if (conn[j] == nid)
5450 break;
5451 }
5452 if (j >= nconns)
5453 break;
5454 }
5455 if (i >= cfg->num_inputs) {
5456 int num_adcs = spec->num_adc_nids;
5457 spec->private_adc_nids[num_adcs] = adc;
5458 spec->private_capsrc_nids[num_adcs] = cap;
5459 spec->num_adc_nids++;
5460 spec->adc_nids = spec->private_adc_nids;
5461 if (adc != cap)
5462 spec->capsrc_nids = spec->private_capsrc_nids;
5463 }
5464 }
5465 if (!spec->num_adc_nids) {
5466 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5467 " using fallback 0x%x\n",
5468 codec->chip_name, fallback_adc);
5469 spec->private_adc_nids[0] = fallback_adc;
5470 spec->adc_nids = spec->private_adc_nids;
5471 if (fallback_adc != fallback_cap) {
5472 spec->private_capsrc_nids[0] = fallback_cap;
5473 spec->capsrc_nids = spec->private_adc_nids;
5474 }
5475 }
5476 }
5477
5478 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5479 #define set_beep_amp(spec, nid, idx, dir) \
5480 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5481
5482 static struct snd_pci_quirk beep_white_list[] = {
5483 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5484 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5485 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5486 {}
5487 };
5488
5489 static inline int has_cdefine_beep(struct hda_codec *codec)
5490 {
5491 struct alc_spec *spec = codec->spec;
5492 const struct snd_pci_quirk *q;
5493 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5494 if (q)
5495 return q->value;
5496 return spec->cdefine.enable_pcbeep;
5497 }
5498 #else
5499 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5500 #define has_cdefine_beep(codec) 0
5501 #endif
5502
5503 /*
5504 * OK, here we have finally the patch for ALC880
5505 */
5506
5507 static int patch_alc880(struct hda_codec *codec)
5508 {
5509 struct alc_spec *spec;
5510 int board_config;
5511 int err;
5512
5513 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5514 if (spec == NULL)
5515 return -ENOMEM;
5516
5517 codec->spec = spec;
5518
5519 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5520 alc880_models,
5521 alc880_cfg_tbl);
5522 if (board_config < 0) {
5523 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5524 codec->chip_name);
5525 board_config = ALC880_AUTO;
5526 }
5527
5528 if (board_config == ALC880_AUTO) {
5529 /* automatic parse from the BIOS config */
5530 err = alc880_parse_auto_config(codec);
5531 if (err < 0) {
5532 alc_free(codec);
5533 return err;
5534 } else if (!err) {
5535 printk(KERN_INFO
5536 "hda_codec: Cannot set up configuration "
5537 "from BIOS. Using 3-stack mode...\n");
5538 board_config = ALC880_3ST;
5539 }
5540 }
5541
5542 err = snd_hda_attach_beep_device(codec, 0x1);
5543 if (err < 0) {
5544 alc_free(codec);
5545 return err;
5546 }
5547
5548 if (board_config != ALC880_AUTO)
5549 setup_preset(codec, &alc880_presets[board_config]);
5550
5551 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5552 spec->stream_analog_capture = &alc880_pcm_analog_capture;
5553 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
5554
5555 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5556 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5557
5558 if (!spec->adc_nids && spec->input_mux) {
5559 /* check whether NID 0x07 is valid */
5560 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
5561 /* get type */
5562 wcap = get_wcaps_type(wcap);
5563 if (wcap != AC_WID_AUD_IN) {
5564 spec->adc_nids = alc880_adc_nids_alt;
5565 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
5566 } else {
5567 spec->adc_nids = alc880_adc_nids;
5568 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
5569 }
5570 }
5571 set_capture_mixer(codec);
5572 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5573
5574 spec->vmaster_nid = 0x0c;
5575
5576 codec->patch_ops = alc_patch_ops;
5577 if (board_config == ALC880_AUTO)
5578 spec->init_hook = alc880_auto_init;
5579 #ifdef CONFIG_SND_HDA_POWER_SAVE
5580 if (!spec->loopback.amplist)
5581 spec->loopback.amplist = alc880_loopbacks;
5582 #endif
5583
5584 return 0;
5585 }
5586
5587
5588 /*
5589 * ALC260 support
5590 */
5591
5592 static hda_nid_t alc260_dac_nids[1] = {
5593 /* front */
5594 0x02,
5595 };
5596
5597 static hda_nid_t alc260_adc_nids[1] = {
5598 /* ADC0 */
5599 0x04,
5600 };
5601
5602 static hda_nid_t alc260_adc_nids_alt[1] = {
5603 /* ADC1 */
5604 0x05,
5605 };
5606
5607 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5608 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5609 */
5610 static hda_nid_t alc260_dual_adc_nids[2] = {
5611 /* ADC0, ADC1 */
5612 0x04, 0x05
5613 };
5614
5615 #define ALC260_DIGOUT_NID 0x03
5616 #define ALC260_DIGIN_NID 0x06
5617
5618 static struct hda_input_mux alc260_capture_source = {
5619 .num_items = 4,
5620 .items = {
5621 { "Mic", 0x0 },
5622 { "Front Mic", 0x1 },
5623 { "Line", 0x2 },
5624 { "CD", 0x4 },
5625 },
5626 };
5627
5628 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5629 * headphone jack and the internal CD lines since these are the only pins at
5630 * which audio can appear. For flexibility, also allow the option of
5631 * recording the mixer output on the second ADC (ADC0 doesn't have a
5632 * connection to the mixer output).
5633 */
5634 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5635 {
5636 .num_items = 3,
5637 .items = {
5638 { "Mic/Line", 0x0 },
5639 { "CD", 0x4 },
5640 { "Headphone", 0x2 },
5641 },
5642 },
5643 {
5644 .num_items = 4,
5645 .items = {
5646 { "Mic/Line", 0x0 },
5647 { "CD", 0x4 },
5648 { "Headphone", 0x2 },
5649 { "Mixer", 0x5 },
5650 },
5651 },
5652
5653 };
5654
5655 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5656 * the Fujitsu S702x, but jacks are marked differently.
5657 */
5658 static struct hda_input_mux alc260_acer_capture_sources[2] = {
5659 {
5660 .num_items = 4,
5661 .items = {
5662 { "Mic", 0x0 },
5663 { "Line", 0x2 },
5664 { "CD", 0x4 },
5665 { "Headphone", 0x5 },
5666 },
5667 },
5668 {
5669 .num_items = 5,
5670 .items = {
5671 { "Mic", 0x0 },
5672 { "Line", 0x2 },
5673 { "CD", 0x4 },
5674 { "Headphone", 0x6 },
5675 { "Mixer", 0x5 },
5676 },
5677 },
5678 };
5679
5680 /* Maxdata Favorit 100XS */
5681 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5682 {
5683 .num_items = 2,
5684 .items = {
5685 { "Line/Mic", 0x0 },
5686 { "CD", 0x4 },
5687 },
5688 },
5689 {
5690 .num_items = 3,
5691 .items = {
5692 { "Line/Mic", 0x0 },
5693 { "CD", 0x4 },
5694 { "Mixer", 0x5 },
5695 },
5696 },
5697 };
5698
5699 /*
5700 * This is just place-holder, so there's something for alc_build_pcms to look
5701 * at when it calculates the maximum number of channels. ALC260 has no mixer
5702 * element which allows changing the channel mode, so the verb list is
5703 * never used.
5704 */
5705 static struct hda_channel_mode alc260_modes[1] = {
5706 { 2, NULL },
5707 };
5708
5709
5710 /* Mixer combinations
5711 *
5712 * basic: base_output + input + pc_beep + capture
5713 * HP: base_output + input + capture_alt
5714 * HP_3013: hp_3013 + input + capture
5715 * fujitsu: fujitsu + capture
5716 * acer: acer + capture
5717 */
5718
5719 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5720 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5721 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5723 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5724 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5725 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5726 { } /* end */
5727 };
5728
5729 static struct snd_kcontrol_new alc260_input_mixer[] = {
5730 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5731 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5732 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5733 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5735 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5736 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5737 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5738 { } /* end */
5739 };
5740
5741 /* update HP, line and mono out pins according to the master switch */
5742 static void alc260_hp_master_update(struct hda_codec *codec,
5743 hda_nid_t hp, hda_nid_t line,
5744 hda_nid_t mono)
5745 {
5746 struct alc_spec *spec = codec->spec;
5747 unsigned int val = spec->master_sw ? PIN_HP : 0;
5748 /* change HP and line-out pins */
5749 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5750 val);
5751 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5752 val);
5753 /* mono (speaker) depending on the HP jack sense */
5754 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5755 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5756 val);
5757 }
5758
5759 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5760 struct snd_ctl_elem_value *ucontrol)
5761 {
5762 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5763 struct alc_spec *spec = codec->spec;
5764 *ucontrol->value.integer.value = spec->master_sw;
5765 return 0;
5766 }
5767
5768 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5769 struct snd_ctl_elem_value *ucontrol)
5770 {
5771 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5772 struct alc_spec *spec = codec->spec;
5773 int val = !!*ucontrol->value.integer.value;
5774 hda_nid_t hp, line, mono;
5775
5776 if (val == spec->master_sw)
5777 return 0;
5778 spec->master_sw = val;
5779 hp = (kcontrol->private_value >> 16) & 0xff;
5780 line = (kcontrol->private_value >> 8) & 0xff;
5781 mono = kcontrol->private_value & 0xff;
5782 alc260_hp_master_update(codec, hp, line, mono);
5783 return 1;
5784 }
5785
5786 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5787 {
5788 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5789 .name = "Master Playback Switch",
5790 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5791 .info = snd_ctl_boolean_mono_info,
5792 .get = alc260_hp_master_sw_get,
5793 .put = alc260_hp_master_sw_put,
5794 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5795 },
5796 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5797 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5798 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5799 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5800 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5801 HDA_OUTPUT),
5802 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5803 { } /* end */
5804 };
5805
5806 static struct hda_verb alc260_hp_unsol_verbs[] = {
5807 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5808 {},
5809 };
5810
5811 static void alc260_hp_automute(struct hda_codec *codec)
5812 {
5813 struct alc_spec *spec = codec->spec;
5814
5815 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5816 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5817 }
5818
5819 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5820 {
5821 if ((res >> 26) == ALC880_HP_EVENT)
5822 alc260_hp_automute(codec);
5823 }
5824
5825 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5826 {
5827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5828 .name = "Master Playback Switch",
5829 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5830 .info = snd_ctl_boolean_mono_info,
5831 .get = alc260_hp_master_sw_get,
5832 .put = alc260_hp_master_sw_put,
5833 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5834 },
5835 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5836 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5837 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5838 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5839 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5841 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5842 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5843 { } /* end */
5844 };
5845
5846 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5847 .ops = &snd_hda_bind_vol,
5848 .values = {
5849 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5850 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5851 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5852 0
5853 },
5854 };
5855
5856 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5857 .ops = &snd_hda_bind_sw,
5858 .values = {
5859 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5860 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5861 0
5862 },
5863 };
5864
5865 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5866 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5867 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5868 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5869 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5870 { } /* end */
5871 };
5872
5873 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5874 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5875 {},
5876 };
5877
5878 static void alc260_hp_3013_automute(struct hda_codec *codec)
5879 {
5880 struct alc_spec *spec = codec->spec;
5881
5882 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
5883 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5884 }
5885
5886 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5887 unsigned int res)
5888 {
5889 if ((res >> 26) == ALC880_HP_EVENT)
5890 alc260_hp_3013_automute(codec);
5891 }
5892
5893 static void alc260_hp_3012_automute(struct hda_codec *codec)
5894 {
5895 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5896
5897 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5898 bits);
5899 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5900 bits);
5901 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5902 bits);
5903 }
5904
5905 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5906 unsigned int res)
5907 {
5908 if ((res >> 26) == ALC880_HP_EVENT)
5909 alc260_hp_3012_automute(codec);
5910 }
5911
5912 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5913 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5914 */
5915 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5917 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5918 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5919 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5920 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5921 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5922 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5923 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5924 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5925 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5926 { } /* end */
5927 };
5928
5929 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5930 * versions of the ALC260 don't act on requests to enable mic bias from NID
5931 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5932 * datasheet doesn't mention this restriction. At this stage it's not clear
5933 * whether this behaviour is intentional or is a hardware bug in chip
5934 * revisions available in early 2006. Therefore for now allow the
5935 * "Headphone Jack Mode" control to span all choices, but if it turns out
5936 * that the lack of mic bias for this NID is intentional we could change the
5937 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5938 *
5939 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5940 * don't appear to make the mic bias available from the "line" jack, even
5941 * though the NID used for this jack (0x14) can supply it. The theory is
5942 * that perhaps Acer have included blocking capacitors between the ALC260
5943 * and the output jack. If this turns out to be the case for all such
5944 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5945 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5946 *
5947 * The C20x Tablet series have a mono internal speaker which is controlled
5948 * via the chip's Mono sum widget and pin complex, so include the necessary
5949 * controls for such models. On models without a "mono speaker" the control
5950 * won't do anything.
5951 */
5952 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5953 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5954 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5955 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5956 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5957 HDA_OUTPUT),
5958 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5959 HDA_INPUT),
5960 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5961 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5962 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5963 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5964 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5965 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5966 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5967 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5968 { } /* end */
5969 };
5970
5971 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5972 */
5973 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5974 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5975 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5976 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5977 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5978 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5979 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5980 { } /* end */
5981 };
5982
5983 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5984 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5985 */
5986 static struct snd_kcontrol_new alc260_will_mixer[] = {
5987 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5988 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5990 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5991 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5992 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5993 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5994 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5995 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5996 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5997 { } /* end */
5998 };
5999
6000 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6001 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6002 */
6003 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6004 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6005 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6007 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6008 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6009 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6010 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6011 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6012 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6013 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6014 { } /* end */
6015 };
6016
6017 /*
6018 * initialization verbs
6019 */
6020 static struct hda_verb alc260_init_verbs[] = {
6021 /* Line In pin widget for input */
6022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6023 /* CD pin widget for input */
6024 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6025 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6026 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6027 /* Mic2 (front panel) pin widget for input and vref at 80% */
6028 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6029 /* LINE-2 is used for line-out in rear */
6030 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6031 /* select line-out */
6032 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6033 /* LINE-OUT pin */
6034 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6035 /* enable HP */
6036 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6037 /* enable Mono */
6038 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6039 /* mute capture amp left and right */
6040 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6041 /* set connection select to line in (default select for this ADC) */
6042 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6043 /* mute capture amp left and right */
6044 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6045 /* set connection select to line in (default select for this ADC) */
6046 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6047 /* set vol=0 Line-Out mixer amp left and right */
6048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6049 /* unmute pin widget amp left and right (no gain on this amp) */
6050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6051 /* set vol=0 HP mixer amp left and right */
6052 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6053 /* unmute pin widget amp left and right (no gain on this amp) */
6054 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6055 /* set vol=0 Mono mixer amp left and right */
6056 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6057 /* unmute pin widget amp left and right (no gain on this amp) */
6058 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6059 /* unmute LINE-2 out pin */
6060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6061 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6062 * Line In 2 = 0x03
6063 */
6064 /* mute analog inputs */
6065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6070 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6071 /* mute Front out path */
6072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6074 /* mute Headphone out path */
6075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6077 /* mute Mono out path */
6078 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6079 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6080 { }
6081 };
6082
6083 #if 0 /* should be identical with alc260_init_verbs? */
6084 static struct hda_verb alc260_hp_init_verbs[] = {
6085 /* Headphone and output */
6086 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6087 /* mono output */
6088 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6089 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6090 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6091 /* Mic2 (front panel) pin widget for input and vref at 80% */
6092 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6093 /* Line In pin widget for input */
6094 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6095 /* Line-2 pin widget for output */
6096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6097 /* CD pin widget for input */
6098 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6099 /* unmute amp left and right */
6100 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6101 /* set connection select to line in (default select for this ADC) */
6102 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6103 /* unmute Line-Out mixer amp left and right (volume = 0) */
6104 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6105 /* mute pin widget amp left and right (no gain on this amp) */
6106 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6107 /* unmute HP mixer amp left and right (volume = 0) */
6108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6109 /* mute pin widget amp left and right (no gain on this amp) */
6110 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6111 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6112 * Line In 2 = 0x03
6113 */
6114 /* mute analog inputs */
6115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6119 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6120 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6121 /* Unmute Front out path */
6122 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6124 /* Unmute Headphone out path */
6125 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6127 /* Unmute Mono out path */
6128 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6129 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6130 { }
6131 };
6132 #endif
6133
6134 static struct hda_verb alc260_hp_3013_init_verbs[] = {
6135 /* Line out and output */
6136 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6137 /* mono output */
6138 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6139 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6140 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6141 /* Mic2 (front panel) pin widget for input and vref at 80% */
6142 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6143 /* Line In pin widget for input */
6144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6145 /* Headphone pin widget for output */
6146 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6147 /* CD pin widget for input */
6148 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6149 /* unmute amp left and right */
6150 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6151 /* set connection select to line in (default select for this ADC) */
6152 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6153 /* unmute Line-Out mixer amp left and right (volume = 0) */
6154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6155 /* mute pin widget amp left and right (no gain on this amp) */
6156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6157 /* unmute HP mixer amp left and right (volume = 0) */
6158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6159 /* mute pin widget amp left and right (no gain on this amp) */
6160 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6161 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6162 * Line In 2 = 0x03
6163 */
6164 /* mute analog inputs */
6165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6169 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6170 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6171 /* Unmute Front out path */
6172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6173 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6174 /* Unmute Headphone out path */
6175 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6176 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6177 /* Unmute Mono out path */
6178 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6179 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6180 { }
6181 };
6182
6183 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6184 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6185 * audio = 0x16, internal speaker = 0x10.
6186 */
6187 static struct hda_verb alc260_fujitsu_init_verbs[] = {
6188 /* Disable all GPIOs */
6189 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6190 /* Internal speaker is connected to headphone pin */
6191 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6192 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6193 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6194 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6195 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6196 /* Ensure all other unused pins are disabled and muted. */
6197 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6198 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6199 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6200 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6201 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6202 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6205
6206 /* Disable digital (SPDIF) pins */
6207 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6208 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6209
6210 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6211 * when acting as an output.
6212 */
6213 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6214
6215 /* Start with output sum widgets muted and their output gains at min */
6216 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6217 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6218 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6219 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6220 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6221 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6222 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6223 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6224 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6225
6226 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6227 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6228 /* Unmute Line1 pin widget output buffer since it starts as an output.
6229 * If the pin mode is changed by the user the pin mode control will
6230 * take care of enabling the pin's input/output buffers as needed.
6231 * Therefore there's no need to enable the input buffer at this
6232 * stage.
6233 */
6234 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6235 /* Unmute input buffer of pin widget used for Line-in (no equiv
6236 * mixer ctrl)
6237 */
6238 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6239
6240 /* Mute capture amp left and right */
6241 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6242 /* Set ADC connection select to match default mixer setting - line
6243 * in (on mic1 pin)
6244 */
6245 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6246
6247 /* Do the same for the second ADC: mute capture input amp and
6248 * set ADC connection to line in (on mic1 pin)
6249 */
6250 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6251 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6252
6253 /* Mute all inputs to mixer widget (even unconnected ones) */
6254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6256 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6262
6263 { }
6264 };
6265
6266 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6267 * similar laptops (adapted from Fujitsu init verbs).
6268 */
6269 static struct hda_verb alc260_acer_init_verbs[] = {
6270 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6271 * the headphone jack. Turn this on and rely on the standard mute
6272 * methods whenever the user wants to turn these outputs off.
6273 */
6274 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6275 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6276 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6277 /* Internal speaker/Headphone jack is connected to Line-out pin */
6278 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6279 /* Internal microphone/Mic jack is connected to Mic1 pin */
6280 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6281 /* Line In jack is connected to Line1 pin */
6282 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6283 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6284 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6285 /* Ensure all other unused pins are disabled and muted. */
6286 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6287 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6288 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6289 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6292 /* Disable digital (SPDIF) pins */
6293 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6294 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6295
6296 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6297 * bus when acting as outputs.
6298 */
6299 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6300 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6301
6302 /* Start with output sum widgets muted and their output gains at min */
6303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6305 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6306 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6307 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6308 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6309 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6310 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6311 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6312
6313 /* Unmute Line-out pin widget amp left and right
6314 * (no equiv mixer ctrl)
6315 */
6316 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6317 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6318 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6319 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6320 * inputs. If the pin mode is changed by the user the pin mode control
6321 * will take care of enabling the pin's input/output buffers as needed.
6322 * Therefore there's no need to enable the input buffer at this
6323 * stage.
6324 */
6325 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6327
6328 /* Mute capture amp left and right */
6329 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6330 /* Set ADC connection select to match default mixer setting - mic
6331 * (on mic1 pin)
6332 */
6333 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6334
6335 /* Do similar with the second ADC: mute capture input amp and
6336 * set ADC connection to mic to match ALSA's default state.
6337 */
6338 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6339 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6340
6341 /* Mute all inputs to mixer widget (even unconnected ones) */
6342 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6343 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6344 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6346 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6347 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6348 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6349 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6350
6351 { }
6352 };
6353
6354 /* Initialisation sequence for Maxdata Favorit 100XS
6355 * (adapted from Acer init verbs).
6356 */
6357 static struct hda_verb alc260_favorit100_init_verbs[] = {
6358 /* GPIO 0 enables the output jack.
6359 * Turn this on and rely on the standard mute
6360 * methods whenever the user wants to turn these outputs off.
6361 */
6362 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6363 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6364 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6365 /* Line/Mic input jack is connected to Mic1 pin */
6366 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6367 /* Ensure all other unused pins are disabled and muted. */
6368 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6369 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6370 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6371 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6372 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6373 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6374 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6375 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6378 /* Disable digital (SPDIF) pins */
6379 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6380 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6381
6382 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6383 * bus when acting as outputs.
6384 */
6385 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6386 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6387
6388 /* Start with output sum widgets muted and their output gains at min */
6389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6390 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6391 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6394 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6395 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6396 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6397 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6398
6399 /* Unmute Line-out pin widget amp left and right
6400 * (no equiv mixer ctrl)
6401 */
6402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6403 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6404 * inputs. If the pin mode is changed by the user the pin mode control
6405 * will take care of enabling the pin's input/output buffers as needed.
6406 * Therefore there's no need to enable the input buffer at this
6407 * stage.
6408 */
6409 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6410
6411 /* Mute capture amp left and right */
6412 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6413 /* Set ADC connection select to match default mixer setting - mic
6414 * (on mic1 pin)
6415 */
6416 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6417
6418 /* Do similar with the second ADC: mute capture input amp and
6419 * set ADC connection to mic to match ALSA's default state.
6420 */
6421 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6422 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6423
6424 /* Mute all inputs to mixer widget (even unconnected ones) */
6425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6426 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6433
6434 { }
6435 };
6436
6437 static struct hda_verb alc260_will_verbs[] = {
6438 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6439 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6440 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6441 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6442 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6443 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6444 {}
6445 };
6446
6447 static struct hda_verb alc260_replacer_672v_verbs[] = {
6448 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6449 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6450 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6451
6452 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6453 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6454 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6455
6456 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6457 {}
6458 };
6459
6460 /* toggle speaker-output according to the hp-jack state */
6461 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6462 {
6463 unsigned int present;
6464
6465 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6466 present = snd_hda_jack_detect(codec, 0x0f);
6467 if (present) {
6468 snd_hda_codec_write_cache(codec, 0x01, 0,
6469 AC_VERB_SET_GPIO_DATA, 1);
6470 snd_hda_codec_write_cache(codec, 0x0f, 0,
6471 AC_VERB_SET_PIN_WIDGET_CONTROL,
6472 PIN_HP);
6473 } else {
6474 snd_hda_codec_write_cache(codec, 0x01, 0,
6475 AC_VERB_SET_GPIO_DATA, 0);
6476 snd_hda_codec_write_cache(codec, 0x0f, 0,
6477 AC_VERB_SET_PIN_WIDGET_CONTROL,
6478 PIN_OUT);
6479 }
6480 }
6481
6482 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6483 unsigned int res)
6484 {
6485 if ((res >> 26) == ALC880_HP_EVENT)
6486 alc260_replacer_672v_automute(codec);
6487 }
6488
6489 static struct hda_verb alc260_hp_dc7600_verbs[] = {
6490 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6491 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6492 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6493 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6494 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6496 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6497 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6498 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6500 {}
6501 };
6502
6503 /* Test configuration for debugging, modelled after the ALC880 test
6504 * configuration.
6505 */
6506 #ifdef CONFIG_SND_DEBUG
6507 static hda_nid_t alc260_test_dac_nids[1] = {
6508 0x02,
6509 };
6510 static hda_nid_t alc260_test_adc_nids[2] = {
6511 0x04, 0x05,
6512 };
6513 /* For testing the ALC260, each input MUX needs its own definition since
6514 * the signal assignments are different. This assumes that the first ADC
6515 * is NID 0x04.
6516 */
6517 static struct hda_input_mux alc260_test_capture_sources[2] = {
6518 {
6519 .num_items = 7,
6520 .items = {
6521 { "MIC1 pin", 0x0 },
6522 { "MIC2 pin", 0x1 },
6523 { "LINE1 pin", 0x2 },
6524 { "LINE2 pin", 0x3 },
6525 { "CD pin", 0x4 },
6526 { "LINE-OUT pin", 0x5 },
6527 { "HP-OUT pin", 0x6 },
6528 },
6529 },
6530 {
6531 .num_items = 8,
6532 .items = {
6533 { "MIC1 pin", 0x0 },
6534 { "MIC2 pin", 0x1 },
6535 { "LINE1 pin", 0x2 },
6536 { "LINE2 pin", 0x3 },
6537 { "CD pin", 0x4 },
6538 { "Mixer", 0x5 },
6539 { "LINE-OUT pin", 0x6 },
6540 { "HP-OUT pin", 0x7 },
6541 },
6542 },
6543 };
6544 static struct snd_kcontrol_new alc260_test_mixer[] = {
6545 /* Output driver widgets */
6546 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6547 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6548 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6549 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6550 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6551 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6552
6553 /* Modes for retasking pin widgets
6554 * Note: the ALC260 doesn't seem to act on requests to enable mic
6555 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6556 * mention this restriction. At this stage it's not clear whether
6557 * this behaviour is intentional or is a hardware bug in chip
6558 * revisions available at least up until early 2006. Therefore for
6559 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6560 * choices, but if it turns out that the lack of mic bias for these
6561 * NIDs is intentional we could change their modes from
6562 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6563 */
6564 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6565 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6566 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6567 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6568 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6569 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6570
6571 /* Loopback mixer controls */
6572 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6573 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6574 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6575 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6576 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6577 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6578 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6579 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6580 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6581 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6582 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6583 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6584 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6585 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6586
6587 /* Controls for GPIO pins, assuming they are configured as outputs */
6588 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6589 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6590 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6591 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6592
6593 /* Switches to allow the digital IO pins to be enabled. The datasheet
6594 * is ambigious as to which NID is which; testing on laptops which
6595 * make this output available should provide clarification.
6596 */
6597 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6598 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6599
6600 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6601 * this output to turn on an external amplifier.
6602 */
6603 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6604 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6605
6606 { } /* end */
6607 };
6608 static struct hda_verb alc260_test_init_verbs[] = {
6609 /* Enable all GPIOs as outputs with an initial value of 0 */
6610 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6611 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6612 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6613
6614 /* Enable retasking pins as output, initially without power amp */
6615 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6616 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6617 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6619 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6620 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6621
6622 /* Disable digital (SPDIF) pins initially, but users can enable
6623 * them via a mixer switch. In the case of SPDIF-out, this initverb
6624 * payload also sets the generation to 0, output to be in "consumer"
6625 * PCM format, copyright asserted, no pre-emphasis and no validity
6626 * control.
6627 */
6628 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6629 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6630
6631 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6632 * OUT1 sum bus when acting as an output.
6633 */
6634 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6635 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6636 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6637 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6638
6639 /* Start with output sum widgets muted and their output gains at min */
6640 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6641 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6642 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6643 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6644 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6645 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6646 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6647 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6648 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6649
6650 /* Unmute retasking pin widget output buffers since the default
6651 * state appears to be output. As the pin mode is changed by the
6652 * user the pin mode control will take care of enabling the pin's
6653 * input/output buffers as needed.
6654 */
6655 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6656 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6657 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6658 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6659 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6660 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6661 /* Also unmute the mono-out pin widget */
6662 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6663
6664 /* Mute capture amp left and right */
6665 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6666 /* Set ADC connection select to match default mixer setting (mic1
6667 * pin)
6668 */
6669 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6670
6671 /* Do the same for the second ADC: mute capture input amp and
6672 * set ADC connection to mic1 pin
6673 */
6674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6675 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6676
6677 /* Mute all inputs to mixer widget (even unconnected ones) */
6678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6679 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6686
6687 { }
6688 };
6689 #endif
6690
6691 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6692 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
6693
6694 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
6695 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
6696
6697 /*
6698 * for BIOS auto-configuration
6699 */
6700
6701 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6702 const char *pfx, int *vol_bits)
6703 {
6704 hda_nid_t nid_vol;
6705 unsigned long vol_val, sw_val;
6706 int err;
6707
6708 if (nid >= 0x0f && nid < 0x11) {
6709 nid_vol = nid - 0x7;
6710 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6711 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6712 } else if (nid == 0x11) {
6713 nid_vol = nid - 0x7;
6714 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6715 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6716 } else if (nid >= 0x12 && nid <= 0x15) {
6717 nid_vol = 0x08;
6718 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6719 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6720 } else
6721 return 0; /* N/A */
6722
6723 if (!(*vol_bits & (1 << nid_vol))) {
6724 /* first control for the volume widget */
6725 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6726 if (err < 0)
6727 return err;
6728 *vol_bits |= (1 << nid_vol);
6729 }
6730 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6731 if (err < 0)
6732 return err;
6733 return 1;
6734 }
6735
6736 /* add playback controls from the parsed DAC table */
6737 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6738 const struct auto_pin_cfg *cfg)
6739 {
6740 hda_nid_t nid;
6741 int err;
6742 int vols = 0;
6743
6744 spec->multiout.num_dacs = 1;
6745 spec->multiout.dac_nids = spec->private_dac_nids;
6746 spec->multiout.dac_nids[0] = 0x02;
6747
6748 nid = cfg->line_out_pins[0];
6749 if (nid) {
6750 const char *pfx;
6751 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6752 pfx = "Master";
6753 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6754 pfx = "Speaker";
6755 else
6756 pfx = "Front";
6757 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6758 if (err < 0)
6759 return err;
6760 }
6761
6762 nid = cfg->speaker_pins[0];
6763 if (nid) {
6764 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6765 if (err < 0)
6766 return err;
6767 }
6768
6769 nid = cfg->hp_pins[0];
6770 if (nid) {
6771 err = alc260_add_playback_controls(spec, nid, "Headphone",
6772 &vols);
6773 if (err < 0)
6774 return err;
6775 }
6776 return 0;
6777 }
6778
6779 /* create playback/capture controls for input pins */
6780 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6781 const struct auto_pin_cfg *cfg)
6782 {
6783 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6784 }
6785
6786 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6787 hda_nid_t nid, int pin_type,
6788 int sel_idx)
6789 {
6790 alc_set_pin_output(codec, nid, pin_type);
6791 /* need the manual connection? */
6792 if (nid >= 0x12) {
6793 int idx = nid - 0x12;
6794 snd_hda_codec_write(codec, idx + 0x0b, 0,
6795 AC_VERB_SET_CONNECT_SEL, sel_idx);
6796 }
6797 }
6798
6799 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6800 {
6801 struct alc_spec *spec = codec->spec;
6802 hda_nid_t nid;
6803
6804 nid = spec->autocfg.line_out_pins[0];
6805 if (nid) {
6806 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6807 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6808 }
6809
6810 nid = spec->autocfg.speaker_pins[0];
6811 if (nid)
6812 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6813
6814 nid = spec->autocfg.hp_pins[0];
6815 if (nid)
6816 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6817 }
6818
6819 #define ALC260_PIN_CD_NID 0x16
6820 static void alc260_auto_init_analog_input(struct hda_codec *codec)
6821 {
6822 struct alc_spec *spec = codec->spec;
6823 struct auto_pin_cfg *cfg = &spec->autocfg;
6824 int i;
6825
6826 for (i = 0; i < cfg->num_inputs; i++) {
6827 hda_nid_t nid = cfg->inputs[i].pin;
6828 if (nid >= 0x12) {
6829 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
6830 if (nid != ALC260_PIN_CD_NID &&
6831 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6832 snd_hda_codec_write(codec, nid, 0,
6833 AC_VERB_SET_AMP_GAIN_MUTE,
6834 AMP_OUT_MUTE);
6835 }
6836 }
6837 }
6838
6839 #define alc260_auto_init_input_src alc880_auto_init_input_src
6840
6841 /*
6842 * generic initialization of ADC, input mixers and output mixers
6843 */
6844 static struct hda_verb alc260_volume_init_verbs[] = {
6845 /*
6846 * Unmute ADC0-1 and set the default input to mic-in
6847 */
6848 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6849 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6850 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6851 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6852
6853 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6854 * mixer widget
6855 * Note: PASD motherboards uses the Line In 2 as the input for
6856 * front panel mic (mic 2)
6857 */
6858 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6859 /* mute analog inputs */
6860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6865
6866 /*
6867 * Set up output mixers (0x08 - 0x0a)
6868 */
6869 /* set vol=0 to output mixers */
6870 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6871 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6872 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6873 /* set up input amps for analog loopback */
6874 /* Amp Indices: DAC = 0, mixer = 1 */
6875 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6876 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6877 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6878 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6879 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6880 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6881
6882 { }
6883 };
6884
6885 static int alc260_parse_auto_config(struct hda_codec *codec)
6886 {
6887 struct alc_spec *spec = codec->spec;
6888 int err;
6889 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6890
6891 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6892 alc260_ignore);
6893 if (err < 0)
6894 return err;
6895 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6896 if (err < 0)
6897 return err;
6898 if (!spec->kctls.list)
6899 return 0; /* can't find valid BIOS pin config */
6900 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6901 if (err < 0)
6902 return err;
6903
6904 spec->multiout.max_channels = 2;
6905
6906 if (spec->autocfg.dig_outs)
6907 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6908 if (spec->kctls.list)
6909 add_mixer(spec, spec->kctls.list);
6910
6911 add_verb(spec, alc260_volume_init_verbs);
6912
6913 spec->num_mux_defs = 1;
6914 spec->input_mux = &spec->private_imux[0];
6915
6916 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6917
6918 return 1;
6919 }
6920
6921 /* additional initialization for auto-configuration model */
6922 static void alc260_auto_init(struct hda_codec *codec)
6923 {
6924 struct alc_spec *spec = codec->spec;
6925 alc260_auto_init_multi_out(codec);
6926 alc260_auto_init_analog_input(codec);
6927 alc260_auto_init_input_src(codec);
6928 alc_auto_init_digital(codec);
6929 if (spec->unsol_event)
6930 alc_inithook(codec);
6931 }
6932
6933 #ifdef CONFIG_SND_HDA_POWER_SAVE
6934 static struct hda_amp_list alc260_loopbacks[] = {
6935 { 0x07, HDA_INPUT, 0 },
6936 { 0x07, HDA_INPUT, 1 },
6937 { 0x07, HDA_INPUT, 2 },
6938 { 0x07, HDA_INPUT, 3 },
6939 { 0x07, HDA_INPUT, 4 },
6940 { } /* end */
6941 };
6942 #endif
6943
6944 /*
6945 * Pin config fixes
6946 */
6947 enum {
6948 PINFIX_HP_DC5750,
6949 };
6950
6951 static const struct alc_fixup alc260_fixups[] = {
6952 [PINFIX_HP_DC5750] = {
6953 .pins = (const struct alc_pincfg[]) {
6954 { 0x11, 0x90130110 }, /* speaker */
6955 { }
6956 }
6957 },
6958 };
6959
6960 static struct snd_pci_quirk alc260_fixup_tbl[] = {
6961 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
6962 {}
6963 };
6964
6965 /*
6966 * ALC260 configurations
6967 */
6968 static const char *alc260_models[ALC260_MODEL_LAST] = {
6969 [ALC260_BASIC] = "basic",
6970 [ALC260_HP] = "hp",
6971 [ALC260_HP_3013] = "hp-3013",
6972 [ALC260_HP_DC7600] = "hp-dc7600",
6973 [ALC260_FUJITSU_S702X] = "fujitsu",
6974 [ALC260_ACER] = "acer",
6975 [ALC260_WILL] = "will",
6976 [ALC260_REPLACER_672V] = "replacer",
6977 [ALC260_FAVORIT100] = "favorit100",
6978 #ifdef CONFIG_SND_DEBUG
6979 [ALC260_TEST] = "test",
6980 #endif
6981 [ALC260_AUTO] = "auto",
6982 };
6983
6984 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6985 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6986 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
6987 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6988 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6989 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6990 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6991 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6992 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6993 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6994 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6995 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6996 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6997 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6998 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6999 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7000 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7001 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7002 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7003 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7004 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7005 {}
7006 };
7007
7008 static struct alc_config_preset alc260_presets[] = {
7009 [ALC260_BASIC] = {
7010 .mixers = { alc260_base_output_mixer,
7011 alc260_input_mixer },
7012 .init_verbs = { alc260_init_verbs },
7013 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7014 .dac_nids = alc260_dac_nids,
7015 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7016 .adc_nids = alc260_dual_adc_nids,
7017 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7018 .channel_mode = alc260_modes,
7019 .input_mux = &alc260_capture_source,
7020 },
7021 [ALC260_HP] = {
7022 .mixers = { alc260_hp_output_mixer,
7023 alc260_input_mixer },
7024 .init_verbs = { alc260_init_verbs,
7025 alc260_hp_unsol_verbs },
7026 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7027 .dac_nids = alc260_dac_nids,
7028 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7029 .adc_nids = alc260_adc_nids_alt,
7030 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7031 .channel_mode = alc260_modes,
7032 .input_mux = &alc260_capture_source,
7033 .unsol_event = alc260_hp_unsol_event,
7034 .init_hook = alc260_hp_automute,
7035 },
7036 [ALC260_HP_DC7600] = {
7037 .mixers = { alc260_hp_dc7600_mixer,
7038 alc260_input_mixer },
7039 .init_verbs = { alc260_init_verbs,
7040 alc260_hp_dc7600_verbs },
7041 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7042 .dac_nids = alc260_dac_nids,
7043 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7044 .adc_nids = alc260_adc_nids_alt,
7045 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7046 .channel_mode = alc260_modes,
7047 .input_mux = &alc260_capture_source,
7048 .unsol_event = alc260_hp_3012_unsol_event,
7049 .init_hook = alc260_hp_3012_automute,
7050 },
7051 [ALC260_HP_3013] = {
7052 .mixers = { alc260_hp_3013_mixer,
7053 alc260_input_mixer },
7054 .init_verbs = { alc260_hp_3013_init_verbs,
7055 alc260_hp_3013_unsol_verbs },
7056 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7057 .dac_nids = alc260_dac_nids,
7058 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7059 .adc_nids = alc260_adc_nids_alt,
7060 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7061 .channel_mode = alc260_modes,
7062 .input_mux = &alc260_capture_source,
7063 .unsol_event = alc260_hp_3013_unsol_event,
7064 .init_hook = alc260_hp_3013_automute,
7065 },
7066 [ALC260_FUJITSU_S702X] = {
7067 .mixers = { alc260_fujitsu_mixer },
7068 .init_verbs = { alc260_fujitsu_init_verbs },
7069 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7070 .dac_nids = alc260_dac_nids,
7071 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7072 .adc_nids = alc260_dual_adc_nids,
7073 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7074 .channel_mode = alc260_modes,
7075 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7076 .input_mux = alc260_fujitsu_capture_sources,
7077 },
7078 [ALC260_ACER] = {
7079 .mixers = { alc260_acer_mixer },
7080 .init_verbs = { alc260_acer_init_verbs },
7081 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7082 .dac_nids = alc260_dac_nids,
7083 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7084 .adc_nids = alc260_dual_adc_nids,
7085 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7086 .channel_mode = alc260_modes,
7087 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7088 .input_mux = alc260_acer_capture_sources,
7089 },
7090 [ALC260_FAVORIT100] = {
7091 .mixers = { alc260_favorit100_mixer },
7092 .init_verbs = { alc260_favorit100_init_verbs },
7093 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7094 .dac_nids = alc260_dac_nids,
7095 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7096 .adc_nids = alc260_dual_adc_nids,
7097 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7098 .channel_mode = alc260_modes,
7099 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7100 .input_mux = alc260_favorit100_capture_sources,
7101 },
7102 [ALC260_WILL] = {
7103 .mixers = { alc260_will_mixer },
7104 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7105 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7106 .dac_nids = alc260_dac_nids,
7107 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7108 .adc_nids = alc260_adc_nids,
7109 .dig_out_nid = ALC260_DIGOUT_NID,
7110 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7111 .channel_mode = alc260_modes,
7112 .input_mux = &alc260_capture_source,
7113 },
7114 [ALC260_REPLACER_672V] = {
7115 .mixers = { alc260_replacer_672v_mixer },
7116 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7117 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7118 .dac_nids = alc260_dac_nids,
7119 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7120 .adc_nids = alc260_adc_nids,
7121 .dig_out_nid = ALC260_DIGOUT_NID,
7122 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7123 .channel_mode = alc260_modes,
7124 .input_mux = &alc260_capture_source,
7125 .unsol_event = alc260_replacer_672v_unsol_event,
7126 .init_hook = alc260_replacer_672v_automute,
7127 },
7128 #ifdef CONFIG_SND_DEBUG
7129 [ALC260_TEST] = {
7130 .mixers = { alc260_test_mixer },
7131 .init_verbs = { alc260_test_init_verbs },
7132 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7133 .dac_nids = alc260_test_dac_nids,
7134 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7135 .adc_nids = alc260_test_adc_nids,
7136 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7137 .channel_mode = alc260_modes,
7138 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7139 .input_mux = alc260_test_capture_sources,
7140 },
7141 #endif
7142 };
7143
7144 static int patch_alc260(struct hda_codec *codec)
7145 {
7146 struct alc_spec *spec;
7147 int err, board_config;
7148
7149 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7150 if (spec == NULL)
7151 return -ENOMEM;
7152
7153 codec->spec = spec;
7154
7155 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7156 alc260_models,
7157 alc260_cfg_tbl);
7158 if (board_config < 0) {
7159 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7160 codec->chip_name);
7161 board_config = ALC260_AUTO;
7162 }
7163
7164 if (board_config == ALC260_AUTO)
7165 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1);
7166
7167 if (board_config == ALC260_AUTO) {
7168 /* automatic parse from the BIOS config */
7169 err = alc260_parse_auto_config(codec);
7170 if (err < 0) {
7171 alc_free(codec);
7172 return err;
7173 } else if (!err) {
7174 printk(KERN_INFO
7175 "hda_codec: Cannot set up configuration "
7176 "from BIOS. Using base mode...\n");
7177 board_config = ALC260_BASIC;
7178 }
7179 }
7180
7181 err = snd_hda_attach_beep_device(codec, 0x1);
7182 if (err < 0) {
7183 alc_free(codec);
7184 return err;
7185 }
7186
7187 if (board_config != ALC260_AUTO)
7188 setup_preset(codec, &alc260_presets[board_config]);
7189
7190 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7191 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7192 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7193
7194 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7195 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7196
7197 if (!spec->adc_nids && spec->input_mux) {
7198 /* check whether NID 0x04 is valid */
7199 unsigned int wcap = get_wcaps(codec, 0x04);
7200 wcap = get_wcaps_type(wcap);
7201 /* get type */
7202 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7203 spec->adc_nids = alc260_adc_nids_alt;
7204 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7205 } else {
7206 spec->adc_nids = alc260_adc_nids;
7207 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7208 }
7209 }
7210 set_capture_mixer(codec);
7211 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7212
7213 if (board_config == ALC260_AUTO)
7214 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7215
7216 spec->vmaster_nid = 0x08;
7217
7218 codec->patch_ops = alc_patch_ops;
7219 if (board_config == ALC260_AUTO)
7220 spec->init_hook = alc260_auto_init;
7221 #ifdef CONFIG_SND_HDA_POWER_SAVE
7222 if (!spec->loopback.amplist)
7223 spec->loopback.amplist = alc260_loopbacks;
7224 #endif
7225
7226 return 0;
7227 }
7228
7229
7230 /*
7231 * ALC882/883/885/888/889 support
7232 *
7233 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7234 * configuration. Each pin widget can choose any input DACs and a mixer.
7235 * Each ADC is connected from a mixer of all inputs. This makes possible
7236 * 6-channel independent captures.
7237 *
7238 * In addition, an independent DAC for the multi-playback (not used in this
7239 * driver yet).
7240 */
7241 #define ALC882_DIGOUT_NID 0x06
7242 #define ALC882_DIGIN_NID 0x0a
7243 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7244 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7245 #define ALC1200_DIGOUT_NID 0x10
7246
7247
7248 static struct hda_channel_mode alc882_ch_modes[1] = {
7249 { 8, NULL }
7250 };
7251
7252 /* DACs */
7253 static hda_nid_t alc882_dac_nids[4] = {
7254 /* front, rear, clfe, rear_surr */
7255 0x02, 0x03, 0x04, 0x05
7256 };
7257 #define alc883_dac_nids alc882_dac_nids
7258
7259 /* ADCs */
7260 #define alc882_adc_nids alc880_adc_nids
7261 #define alc882_adc_nids_alt alc880_adc_nids_alt
7262 #define alc883_adc_nids alc882_adc_nids_alt
7263 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7264 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7265 #define alc889_adc_nids alc880_adc_nids
7266
7267 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7268 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7269 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7270 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7271 #define alc889_capsrc_nids alc882_capsrc_nids
7272
7273 /* input MUX */
7274 /* FIXME: should be a matrix-type input source selection */
7275
7276 static struct hda_input_mux alc882_capture_source = {
7277 .num_items = 4,
7278 .items = {
7279 { "Mic", 0x0 },
7280 { "Front Mic", 0x1 },
7281 { "Line", 0x2 },
7282 { "CD", 0x4 },
7283 },
7284 };
7285
7286 #define alc883_capture_source alc882_capture_source
7287
7288 static struct hda_input_mux alc889_capture_source = {
7289 .num_items = 3,
7290 .items = {
7291 { "Front Mic", 0x0 },
7292 { "Mic", 0x3 },
7293 { "Line", 0x2 },
7294 },
7295 };
7296
7297 static struct hda_input_mux mb5_capture_source = {
7298 .num_items = 3,
7299 .items = {
7300 { "Mic", 0x1 },
7301 { "Line", 0x7 },
7302 { "CD", 0x4 },
7303 },
7304 };
7305
7306 static struct hda_input_mux macmini3_capture_source = {
7307 .num_items = 2,
7308 .items = {
7309 { "Line", 0x2 },
7310 { "CD", 0x4 },
7311 },
7312 };
7313
7314 static struct hda_input_mux alc883_3stack_6ch_intel = {
7315 .num_items = 4,
7316 .items = {
7317 { "Mic", 0x1 },
7318 { "Front Mic", 0x0 },
7319 { "Line", 0x2 },
7320 { "CD", 0x4 },
7321 },
7322 };
7323
7324 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7325 .num_items = 2,
7326 .items = {
7327 { "Mic", 0x1 },
7328 { "Line", 0x2 },
7329 },
7330 };
7331
7332 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7333 .num_items = 4,
7334 .items = {
7335 { "Mic", 0x0 },
7336 { "Int Mic", 0x1 },
7337 { "Line", 0x2 },
7338 { "CD", 0x4 },
7339 },
7340 };
7341
7342 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7343 .num_items = 2,
7344 .items = {
7345 { "Mic", 0x0 },
7346 { "Int Mic", 0x1 },
7347 },
7348 };
7349
7350 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7351 .num_items = 3,
7352 .items = {
7353 { "Mic", 0x0 },
7354 { "Front Mic", 0x1 },
7355 { "Line", 0x4 },
7356 },
7357 };
7358
7359 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7360 .num_items = 2,
7361 .items = {
7362 { "Mic", 0x0 },
7363 { "Line", 0x2 },
7364 },
7365 };
7366
7367 static struct hda_input_mux alc889A_mb31_capture_source = {
7368 .num_items = 2,
7369 .items = {
7370 { "Mic", 0x0 },
7371 /* Front Mic (0x01) unused */
7372 { "Line", 0x2 },
7373 /* Line 2 (0x03) unused */
7374 /* CD (0x04) unused? */
7375 },
7376 };
7377
7378 static struct hda_input_mux alc889A_imac91_capture_source = {
7379 .num_items = 2,
7380 .items = {
7381 { "Mic", 0x01 },
7382 { "Line", 0x2 }, /* Not sure! */
7383 },
7384 };
7385
7386 /*
7387 * 2ch mode
7388 */
7389 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7390 { 2, NULL }
7391 };
7392
7393 /*
7394 * 2ch mode
7395 */
7396 static struct hda_verb alc882_3ST_ch2_init[] = {
7397 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7398 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7399 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7400 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7401 { } /* end */
7402 };
7403
7404 /*
7405 * 4ch mode
7406 */
7407 static struct hda_verb alc882_3ST_ch4_init[] = {
7408 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7409 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7410 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7411 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7412 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7413 { } /* end */
7414 };
7415
7416 /*
7417 * 6ch mode
7418 */
7419 static struct hda_verb alc882_3ST_ch6_init[] = {
7420 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7421 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7422 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7423 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7424 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7425 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7426 { } /* end */
7427 };
7428
7429 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7430 { 2, alc882_3ST_ch2_init },
7431 { 4, alc882_3ST_ch4_init },
7432 { 6, alc882_3ST_ch6_init },
7433 };
7434
7435 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7436
7437 /*
7438 * 2ch mode
7439 */
7440 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7441 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7442 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7443 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7444 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7445 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7446 { } /* end */
7447 };
7448
7449 /*
7450 * 4ch mode
7451 */
7452 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7453 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7454 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7455 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7456 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7457 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7458 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7459 { } /* end */
7460 };
7461
7462 /*
7463 * 6ch mode
7464 */
7465 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7466 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7467 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7468 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7469 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7470 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7471 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7472 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7473 { } /* end */
7474 };
7475
7476 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7477 { 2, alc883_3ST_ch2_clevo_init },
7478 { 4, alc883_3ST_ch4_clevo_init },
7479 { 6, alc883_3ST_ch6_clevo_init },
7480 };
7481
7482
7483 /*
7484 * 6ch mode
7485 */
7486 static struct hda_verb alc882_sixstack_ch6_init[] = {
7487 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7488 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7489 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7490 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7491 { } /* end */
7492 };
7493
7494 /*
7495 * 8ch mode
7496 */
7497 static struct hda_verb alc882_sixstack_ch8_init[] = {
7498 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7499 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7500 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7501 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7502 { } /* end */
7503 };
7504
7505 static struct hda_channel_mode alc882_sixstack_modes[2] = {
7506 { 6, alc882_sixstack_ch6_init },
7507 { 8, alc882_sixstack_ch8_init },
7508 };
7509
7510
7511 /* Macbook Air 2,1 */
7512
7513 static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7514 { 2, NULL },
7515 };
7516
7517 /*
7518 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7519 */
7520
7521 /*
7522 * 2ch mode
7523 */
7524 static struct hda_verb alc885_mbp_ch2_init[] = {
7525 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7526 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7527 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7528 { } /* end */
7529 };
7530
7531 /*
7532 * 4ch mode
7533 */
7534 static struct hda_verb alc885_mbp_ch4_init[] = {
7535 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7536 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7537 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7538 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7539 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7540 { } /* end */
7541 };
7542
7543 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7544 { 2, alc885_mbp_ch2_init },
7545 { 4, alc885_mbp_ch4_init },
7546 };
7547
7548 /*
7549 * 2ch
7550 * Speakers/Woofer/HP = Front
7551 * LineIn = Input
7552 */
7553 static struct hda_verb alc885_mb5_ch2_init[] = {
7554 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7556 { } /* end */
7557 };
7558
7559 /*
7560 * 6ch mode
7561 * Speakers/HP = Front
7562 * Woofer = LFE
7563 * LineIn = Surround
7564 */
7565 static struct hda_verb alc885_mb5_ch6_init[] = {
7566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7567 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7568 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7569 { } /* end */
7570 };
7571
7572 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7573 { 2, alc885_mb5_ch2_init },
7574 { 6, alc885_mb5_ch6_init },
7575 };
7576
7577 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7578
7579 /*
7580 * 2ch mode
7581 */
7582 static struct hda_verb alc883_4ST_ch2_init[] = {
7583 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7584 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7585 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7586 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7587 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7588 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7589 { } /* end */
7590 };
7591
7592 /*
7593 * 4ch mode
7594 */
7595 static struct hda_verb alc883_4ST_ch4_init[] = {
7596 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7597 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7598 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7599 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7600 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7601 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7602 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7603 { } /* end */
7604 };
7605
7606 /*
7607 * 6ch mode
7608 */
7609 static struct hda_verb alc883_4ST_ch6_init[] = {
7610 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7611 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7612 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7613 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7614 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7615 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7616 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7617 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7618 { } /* end */
7619 };
7620
7621 /*
7622 * 8ch mode
7623 */
7624 static struct hda_verb alc883_4ST_ch8_init[] = {
7625 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7626 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7627 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7628 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7629 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7630 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7631 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7632 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7633 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7634 { } /* end */
7635 };
7636
7637 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7638 { 2, alc883_4ST_ch2_init },
7639 { 4, alc883_4ST_ch4_init },
7640 { 6, alc883_4ST_ch6_init },
7641 { 8, alc883_4ST_ch8_init },
7642 };
7643
7644
7645 /*
7646 * 2ch mode
7647 */
7648 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7649 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7650 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7651 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7652 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7653 { } /* end */
7654 };
7655
7656 /*
7657 * 4ch mode
7658 */
7659 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7660 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7661 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7664 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7665 { } /* end */
7666 };
7667
7668 /*
7669 * 6ch mode
7670 */
7671 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7672 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7673 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7674 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7675 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7676 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7677 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7678 { } /* end */
7679 };
7680
7681 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7682 { 2, alc883_3ST_ch2_intel_init },
7683 { 4, alc883_3ST_ch4_intel_init },
7684 { 6, alc883_3ST_ch6_intel_init },
7685 };
7686
7687 /*
7688 * 2ch mode
7689 */
7690 static struct hda_verb alc889_ch2_intel_init[] = {
7691 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7692 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7693 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7694 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7695 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7696 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7697 { } /* end */
7698 };
7699
7700 /*
7701 * 6ch mode
7702 */
7703 static struct hda_verb alc889_ch6_intel_init[] = {
7704 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7705 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7706 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7707 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7710 { } /* end */
7711 };
7712
7713 /*
7714 * 8ch mode
7715 */
7716 static struct hda_verb alc889_ch8_intel_init[] = {
7717 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7718 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7719 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7720 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7721 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7722 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7723 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7724 { } /* end */
7725 };
7726
7727 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7728 { 2, alc889_ch2_intel_init },
7729 { 6, alc889_ch6_intel_init },
7730 { 8, alc889_ch8_intel_init },
7731 };
7732
7733 /*
7734 * 6ch mode
7735 */
7736 static struct hda_verb alc883_sixstack_ch6_init[] = {
7737 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7738 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7739 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7740 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7741 { } /* end */
7742 };
7743
7744 /*
7745 * 8ch mode
7746 */
7747 static struct hda_verb alc883_sixstack_ch8_init[] = {
7748 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7749 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7750 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { } /* end */
7753 };
7754
7755 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7756 { 6, alc883_sixstack_ch6_init },
7757 { 8, alc883_sixstack_ch8_init },
7758 };
7759
7760
7761 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7762 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7763 */
7764 static struct snd_kcontrol_new alc882_base_mixer[] = {
7765 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7766 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7767 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7768 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7769 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7770 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7771 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7772 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7773 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7774 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7778 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7779 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7781 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7783 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7784 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7785 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7786 { } /* end */
7787 };
7788
7789 /* Macbook Air 2,1 same control for HP and internal Speaker */
7790
7791 static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7792 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7793 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7794 { }
7795 };
7796
7797
7798 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7799 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7800 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7801 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7802 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7803 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7804 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7805 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7807 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7808 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7809 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7810 { } /* end */
7811 };
7812
7813 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7814 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7815 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7816 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7817 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7818 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7819 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7820 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7821 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7822 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7823 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7825 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7827 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7828 { } /* end */
7829 };
7830
7831 static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7832 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7833 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7834 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7835 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7836 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7837 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7838 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7839 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7840 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7841 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7842 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7843 { } /* end */
7844 };
7845
7846 static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7847 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7848 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7849 { } /* end */
7850 };
7851
7852
7853 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7854 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7855 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7858 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7859 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7863 { } /* end */
7864 };
7865
7866 static struct snd_kcontrol_new alc882_targa_mixer[] = {
7867 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7868 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7869 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7870 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7871 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7876 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7877 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7878 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7879 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7880 { } /* end */
7881 };
7882
7883 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7884 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7885 */
7886 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7888 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7889 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7890 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7893 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7894 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7895 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7896 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7899 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7900 { } /* end */
7901 };
7902
7903 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7905 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7906 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7909 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7910 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7912 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7914 { } /* end */
7915 };
7916
7917 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7918 {
7919 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7920 .name = "Channel Mode",
7921 .info = alc_ch_mode_info,
7922 .get = alc_ch_mode_get,
7923 .put = alc_ch_mode_put,
7924 },
7925 { } /* end */
7926 };
7927
7928 static struct hda_verb alc882_base_init_verbs[] = {
7929 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7932 /* Rear mixer */
7933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7935 /* CLFE mixer */
7936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7937 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7938 /* Side mixer */
7939 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7940 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7941
7942 /* Front Pin: output 0 (0x0c) */
7943 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7944 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7945 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7946 /* Rear Pin: output 1 (0x0d) */
7947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7948 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7949 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7950 /* CLFE Pin: output 2 (0x0e) */
7951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7953 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7954 /* Side Pin: output 3 (0x0f) */
7955 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7956 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7957 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7958 /* Mic (rear) pin: input vref at 80% */
7959 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7960 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7961 /* Front Mic pin: input vref at 80% */
7962 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7963 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7964 /* Line In pin: input */
7965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7966 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7967 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7968 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7969 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7970 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7971 /* CD pin widget for input */
7972 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7973
7974 /* FIXME: use matrix-type input source selection */
7975 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7976 /* Input mixer2 */
7977 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7978 /* Input mixer3 */
7979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7980 /* ADC2: mute amp left and right */
7981 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7982 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7983 /* ADC3: mute amp left and right */
7984 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7985 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7986
7987 { }
7988 };
7989
7990 static struct hda_verb alc882_adc1_init_verbs[] = {
7991 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7996 /* ADC1: mute amp left and right */
7997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7998 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7999 { }
8000 };
8001
8002 static struct hda_verb alc882_eapd_verbs[] = {
8003 /* change to EAPD mode */
8004 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8005 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8006 { }
8007 };
8008
8009 static struct hda_verb alc889_eapd_verbs[] = {
8010 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8011 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8012 { }
8013 };
8014
8015 static struct hda_verb alc_hp15_unsol_verbs[] = {
8016 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8018 {}
8019 };
8020
8021 static struct hda_verb alc885_init_verbs[] = {
8022 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8025 /* Rear mixer */
8026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8028 /* CLFE mixer */
8029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8031 /* Side mixer */
8032 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8033 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8034
8035 /* Front HP Pin: output 0 (0x0c) */
8036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8038 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8039 /* Front Pin: output 0 (0x0c) */
8040 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8041 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8042 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8043 /* Rear Pin: output 1 (0x0d) */
8044 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8045 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8046 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8047 /* CLFE Pin: output 2 (0x0e) */
8048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8049 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8050 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8051 /* Side Pin: output 3 (0x0f) */
8052 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8053 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8054 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8055 /* Mic (rear) pin: input vref at 80% */
8056 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8058 /* Front Mic pin: input vref at 80% */
8059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8060 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8061 /* Line In pin: input */
8062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8063 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8064
8065 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8066 /* Input mixer1 */
8067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8068 /* Input mixer2 */
8069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8070 /* Input mixer3 */
8071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8072 /* ADC2: mute amp left and right */
8073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8074 /* ADC3: mute amp left and right */
8075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8076
8077 { }
8078 };
8079
8080 static struct hda_verb alc885_init_input_verbs[] = {
8081 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8082 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8083 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8084 { }
8085 };
8086
8087
8088 /* Unmute Selector 24h and set the default input to front mic */
8089 static struct hda_verb alc889_init_input_verbs[] = {
8090 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8091 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8092 { }
8093 };
8094
8095
8096 #define alc883_init_verbs alc882_base_init_verbs
8097
8098 /* Mac Pro test */
8099 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8101 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8102 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8103 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8104 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8105 /* FIXME: this looks suspicious...
8106 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8107 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8108 */
8109 { } /* end */
8110 };
8111
8112 static struct hda_verb alc882_macpro_init_verbs[] = {
8113 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8117 /* Front Pin: output 0 (0x0c) */
8118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8119 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8120 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8121 /* Front Mic pin: input vref at 80% */
8122 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8124 /* Speaker: output */
8125 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8126 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8127 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8128 /* Headphone output (output 0 - 0x0c) */
8129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8130 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8131 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8132
8133 /* FIXME: use matrix-type input source selection */
8134 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8135 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8140 /* Input mixer2 */
8141 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8143 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8144 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8145 /* Input mixer3 */
8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8148 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8149 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8150 /* ADC1: mute amp left and right */
8151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8152 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8153 /* ADC2: mute amp left and right */
8154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8155 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8156 /* ADC3: mute amp left and right */
8157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8158 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8159
8160 { }
8161 };
8162
8163 /* Macbook 5,1 */
8164 static struct hda_verb alc885_mb5_init_verbs[] = {
8165 /* DACs */
8166 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8167 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8168 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8169 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8170 /* Front mixer */
8171 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8172 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8174 /* Surround mixer */
8175 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8178 /* LFE mixer */
8179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8182 /* HP mixer */
8183 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8184 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8185 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8186 /* Front Pin (0x0c) */
8187 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8188 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8189 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8190 /* LFE Pin (0x0e) */
8191 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8192 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8193 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8194 /* HP Pin (0x0f) */
8195 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8196 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8197 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8198 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8199 /* Front Mic pin: input vref at 80% */
8200 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8202 /* Line In pin */
8203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8205
8206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8209 { }
8210 };
8211
8212 /* Macmini 3,1 */
8213 static struct hda_verb alc885_macmini3_init_verbs[] = {
8214 /* DACs */
8215 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8216 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8217 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8218 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8219 /* Front mixer */
8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8223 /* Surround mixer */
8224 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8225 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8226 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8227 /* LFE mixer */
8228 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8229 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8231 /* HP mixer */
8232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8234 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8235 /* Front Pin (0x0c) */
8236 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8237 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8238 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8239 /* LFE Pin (0x0e) */
8240 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8241 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8242 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8243 /* HP Pin (0x0f) */
8244 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8245 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8246 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8247 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8248 /* Line In pin */
8249 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8250 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8251
8252 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8253 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8254 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8255 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8256 { }
8257 };
8258
8259
8260 static struct hda_verb alc885_mba21_init_verbs[] = {
8261 /*Internal and HP Speaker Mixer*/
8262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8265 /*Internal Speaker Pin (0x0c)*/
8266 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8267 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8268 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8269 /* HP Pin: output 0 (0x0e) */
8270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8271 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8272 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8273 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8274 /* Line in (is hp when jack connected)*/
8275 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8276 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8277
8278 { }
8279 };
8280
8281
8282 /* Macbook Pro rev3 */
8283 static struct hda_verb alc885_mbp3_init_verbs[] = {
8284 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8285 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8288 /* Rear mixer */
8289 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8290 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8292 /* HP mixer */
8293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8294 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8295 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8296 /* Front Pin: output 0 (0x0c) */
8297 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8298 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8299 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8300 /* HP Pin: output 0 (0x0e) */
8301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8303 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8305 /* Mic (rear) pin: input vref at 80% */
8306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8308 /* Front Mic pin: input vref at 80% */
8309 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8311 /* Line In pin: use output 1 when in LineOut mode */
8312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8314 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8315
8316 /* FIXME: use matrix-type input source selection */
8317 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8318 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8322 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8323 /* Input mixer2 */
8324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8326 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8328 /* Input mixer3 */
8329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8332 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8333 /* ADC1: mute amp left and right */
8334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8335 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8336 /* ADC2: mute amp left and right */
8337 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8338 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8339 /* ADC3: mute amp left and right */
8340 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8341 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8342
8343 { }
8344 };
8345
8346 /* iMac 9,1 */
8347 static struct hda_verb alc885_imac91_init_verbs[] = {
8348 /* Internal Speaker Pin (0x0c) */
8349 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8350 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8351 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8352 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8353 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8354 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8355 /* HP Pin: Rear */
8356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8358 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8359 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8360 /* Line in Rear */
8361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8362 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8363 /* Front Mic pin: input vref at 80% */
8364 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8365 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8366 /* Rear mixer */
8367 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8379 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8384 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8389 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8392 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8393 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8394 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8395 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8397 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8398 { }
8399 };
8400
8401 /* iMac 24 mixer. */
8402 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8403 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8404 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8405 { } /* end */
8406 };
8407
8408 /* iMac 24 init verbs. */
8409 static struct hda_verb alc885_imac24_init_verbs[] = {
8410 /* Internal speakers: output 0 (0x0c) */
8411 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8413 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8414 /* Internal speakers: output 0 (0x0c) */
8415 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8416 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8417 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8418 /* Headphone: output 0 (0x0c) */
8419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8420 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8421 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8422 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8423 /* Front Mic: input vref at 80% */
8424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8426 { }
8427 };
8428
8429 /* Toggle speaker-output according to the hp-jack state */
8430 static void alc885_imac24_setup(struct hda_codec *codec)
8431 {
8432 struct alc_spec *spec = codec->spec;
8433
8434 spec->autocfg.hp_pins[0] = 0x14;
8435 spec->autocfg.speaker_pins[0] = 0x18;
8436 spec->autocfg.speaker_pins[1] = 0x1a;
8437 }
8438
8439 #define alc885_mb5_setup alc885_imac24_setup
8440 #define alc885_macmini3_setup alc885_imac24_setup
8441
8442 /* Macbook Air 2,1 */
8443 static void alc885_mba21_setup(struct hda_codec *codec)
8444 {
8445 struct alc_spec *spec = codec->spec;
8446
8447 spec->autocfg.hp_pins[0] = 0x14;
8448 spec->autocfg.speaker_pins[0] = 0x18;
8449 }
8450
8451
8452
8453 static void alc885_mbp3_setup(struct hda_codec *codec)
8454 {
8455 struct alc_spec *spec = codec->spec;
8456
8457 spec->autocfg.hp_pins[0] = 0x15;
8458 spec->autocfg.speaker_pins[0] = 0x14;
8459 }
8460
8461 static void alc885_imac91_setup(struct hda_codec *codec)
8462 {
8463 struct alc_spec *spec = codec->spec;
8464
8465 spec->autocfg.hp_pins[0] = 0x14;
8466 spec->autocfg.speaker_pins[0] = 0x18;
8467 spec->autocfg.speaker_pins[1] = 0x1a;
8468 }
8469
8470 static struct hda_verb alc882_targa_verbs[] = {
8471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8472 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8473
8474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8475 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8476
8477 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8478 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8479 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8480
8481 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8482 { } /* end */
8483 };
8484
8485 /* toggle speaker-output according to the hp-jack state */
8486 static void alc882_targa_automute(struct hda_codec *codec)
8487 {
8488 struct alc_spec *spec = codec->spec;
8489 alc_automute_amp(codec);
8490 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8491 spec->jack_present ? 1 : 3);
8492 }
8493
8494 static void alc882_targa_setup(struct hda_codec *codec)
8495 {
8496 struct alc_spec *spec = codec->spec;
8497
8498 spec->autocfg.hp_pins[0] = 0x14;
8499 spec->autocfg.speaker_pins[0] = 0x1b;
8500 }
8501
8502 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8503 {
8504 if ((res >> 26) == ALC880_HP_EVENT)
8505 alc882_targa_automute(codec);
8506 }
8507
8508 static struct hda_verb alc882_asus_a7j_verbs[] = {
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8511
8512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8514 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8515
8516 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8518 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8519
8520 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8521 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8522 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8523 { } /* end */
8524 };
8525
8526 static struct hda_verb alc882_asus_a7m_verbs[] = {
8527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8529
8530 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8533
8534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8535 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8536 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8537
8538 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8539 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8540 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8541 { } /* end */
8542 };
8543
8544 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8545 {
8546 unsigned int gpiostate, gpiomask, gpiodir;
8547
8548 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8549 AC_VERB_GET_GPIO_DATA, 0);
8550
8551 if (!muted)
8552 gpiostate |= (1 << pin);
8553 else
8554 gpiostate &= ~(1 << pin);
8555
8556 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8557 AC_VERB_GET_GPIO_MASK, 0);
8558 gpiomask |= (1 << pin);
8559
8560 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8561 AC_VERB_GET_GPIO_DIRECTION, 0);
8562 gpiodir |= (1 << pin);
8563
8564
8565 snd_hda_codec_write(codec, codec->afg, 0,
8566 AC_VERB_SET_GPIO_MASK, gpiomask);
8567 snd_hda_codec_write(codec, codec->afg, 0,
8568 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8569
8570 msleep(1);
8571
8572 snd_hda_codec_write(codec, codec->afg, 0,
8573 AC_VERB_SET_GPIO_DATA, gpiostate);
8574 }
8575
8576 /* set up GPIO at initialization */
8577 static void alc885_macpro_init_hook(struct hda_codec *codec)
8578 {
8579 alc882_gpio_mute(codec, 0, 0);
8580 alc882_gpio_mute(codec, 1, 0);
8581 }
8582
8583 /* set up GPIO and update auto-muting at initialization */
8584 static void alc885_imac24_init_hook(struct hda_codec *codec)
8585 {
8586 alc885_macpro_init_hook(codec);
8587 alc_automute_amp(codec);
8588 }
8589
8590 /*
8591 * generic initialization of ADC, input mixers and output mixers
8592 */
8593 static struct hda_verb alc883_auto_init_verbs[] = {
8594 /*
8595 * Unmute ADC0-2 and set the default input to mic-in
8596 */
8597 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8598 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8599 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8600 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8601
8602 /*
8603 * Set up output mixers (0x0c - 0x0f)
8604 */
8605 /* set vol=0 to output mixers */
8606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8608 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8610 /* set up input amps for analog loopback */
8611 /* Amp Indices: DAC = 0, mixer = 1 */
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8616 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8618 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8619 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8620 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8621 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8622
8623 /* FIXME: use matrix-type input source selection */
8624 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8625 /* Input mixer2 */
8626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8627 /* Input mixer3 */
8628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8629 { }
8630 };
8631
8632 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8633 static struct hda_verb alc889A_mb31_ch2_init[] = {
8634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8635 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8636 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8638 { } /* end */
8639 };
8640
8641 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8642 static struct hda_verb alc889A_mb31_ch4_init[] = {
8643 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8644 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8645 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8647 { } /* end */
8648 };
8649
8650 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8651 static struct hda_verb alc889A_mb31_ch5_init[] = {
8652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8653 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8654 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8656 { } /* end */
8657 };
8658
8659 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8660 static struct hda_verb alc889A_mb31_ch6_init[] = {
8661 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8662 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8663 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8664 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8665 { } /* end */
8666 };
8667
8668 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8669 { 2, alc889A_mb31_ch2_init },
8670 { 4, alc889A_mb31_ch4_init },
8671 { 5, alc889A_mb31_ch5_init },
8672 { 6, alc889A_mb31_ch6_init },
8673 };
8674
8675 static struct hda_verb alc883_medion_eapd_verbs[] = {
8676 /* eanable EAPD on medion laptop */
8677 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8678 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8679 { }
8680 };
8681
8682 #define alc883_base_mixer alc882_base_mixer
8683
8684 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8685 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8686 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8687 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8688 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8689 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8690 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8693 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8695 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8698 { } /* end */
8699 };
8700
8701 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8703 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8704 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8705 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8707 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8709 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8710 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8711 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8712 { } /* end */
8713 };
8714
8715 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8716 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8717 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8718 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8719 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8721 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8723 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8724 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8725 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8726 { } /* end */
8727 };
8728
8729 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8730 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8731 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8732 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8733 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8734 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8735 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8736 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8737 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8738 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8740 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8741 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8742 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8743 { } /* end */
8744 };
8745
8746 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8747 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8748 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8749 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8750 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8751 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8752 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8753 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8754 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8758 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8759 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8763 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8764 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8765 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8766 { } /* end */
8767 };
8768
8769 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8770 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8771 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8772 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8773 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8774 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8775 HDA_OUTPUT),
8776 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8777 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8778 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8780 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8781 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8782 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8783 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8785 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8786 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8787 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8788 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8789 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8790 { } /* end */
8791 };
8792
8793 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8794 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8795 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8796 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8797 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8798 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8799 HDA_OUTPUT),
8800 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8801 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8802 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8803 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8804 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8805 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8806 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8807 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8808 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8809 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8811 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8812 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8813 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8814 { } /* end */
8815 };
8816
8817 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8819 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8820 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8821 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8822 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8823 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8824 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8825 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8827 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8828 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8829 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8830 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8831 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8832 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8834 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8835 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8836 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8837 { } /* end */
8838 };
8839
8840 static struct snd_kcontrol_new alc883_targa_mixer[] = {
8841 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8842 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8844 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8845 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8846 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8847 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8848 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8849 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8850 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8851 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8852 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8853 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8854 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8856 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8858 { } /* end */
8859 };
8860
8861 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8863 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8864 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8865 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8869 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8870 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8871 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8872 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8873 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8874 { } /* end */
8875 };
8876
8877 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8878 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8879 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8880 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8881 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8882 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8883 { } /* end */
8884 };
8885
8886 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8889 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8890 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8891 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8893 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8894 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8895 { } /* end */
8896 };
8897
8898 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8899 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8900 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8901 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8902 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8903 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8906 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8907 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8908 { } /* end */
8909 };
8910
8911 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8912 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8914 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8915 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8916 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8919 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8920 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8921 { } /* end */
8922 };
8923
8924 static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8926 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8927 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8929 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8930 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8931 { } /* end */
8932 };
8933
8934 static struct hda_verb alc883_medion_wim2160_verbs[] = {
8935 /* Unmute front mixer */
8936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8937 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8938
8939 /* Set speaker pin to front mixer */
8940 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8941
8942 /* Init headphone pin */
8943 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8944 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8945 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8946 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8947
8948 { } /* end */
8949 };
8950
8951 /* toggle speaker-output according to the hp-jack state */
8952 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8953 {
8954 struct alc_spec *spec = codec->spec;
8955
8956 spec->autocfg.hp_pins[0] = 0x1a;
8957 spec->autocfg.speaker_pins[0] = 0x15;
8958 }
8959
8960 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8964 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8965 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8967 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8968 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8969 { } /* end */
8970 };
8971
8972 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8974 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8975 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8976 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8977 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8978 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8980 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8982 { } /* end */
8983 };
8984
8985 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8988 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8989 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8990 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8991 0x0d, 1, 0x0, HDA_OUTPUT),
8992 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8993 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8994 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8996 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8997 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8998 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9000 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9002 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9003 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9004 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9006 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9007 { } /* end */
9008 };
9009
9010 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9011 /* Output mixers */
9012 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9014 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9015 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9016 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9017 HDA_OUTPUT),
9018 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9019 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9020 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9021 /* Output switches */
9022 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9023 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9024 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9025 /* Boost mixers */
9026 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
9027 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
9028 /* Input mixers */
9029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9033 { } /* end */
9034 };
9035
9036 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9038 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9039 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9041 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9043 { } /* end */
9044 };
9045
9046 static struct hda_bind_ctls alc883_bind_cap_vol = {
9047 .ops = &snd_hda_bind_vol,
9048 .values = {
9049 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9050 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9051 0
9052 },
9053 };
9054
9055 static struct hda_bind_ctls alc883_bind_cap_switch = {
9056 .ops = &snd_hda_bind_sw,
9057 .values = {
9058 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9059 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9060 0
9061 },
9062 };
9063
9064 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9065 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9066 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9068 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9069 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9070 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9071 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9072 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9073 { } /* end */
9074 };
9075
9076 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9077 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9078 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9079 {
9080 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9081 /* .name = "Capture Source", */
9082 .name = "Input Source",
9083 .count = 1,
9084 .info = alc_mux_enum_info,
9085 .get = alc_mux_enum_get,
9086 .put = alc_mux_enum_put,
9087 },
9088 { } /* end */
9089 };
9090
9091 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9092 {
9093 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9094 .name = "Channel Mode",
9095 .info = alc_ch_mode_info,
9096 .get = alc_ch_mode_get,
9097 .put = alc_ch_mode_put,
9098 },
9099 { } /* end */
9100 };
9101
9102 /* toggle speaker-output according to the hp-jack state */
9103 static void alc883_mitac_setup(struct hda_codec *codec)
9104 {
9105 struct alc_spec *spec = codec->spec;
9106
9107 spec->autocfg.hp_pins[0] = 0x15;
9108 spec->autocfg.speaker_pins[0] = 0x14;
9109 spec->autocfg.speaker_pins[1] = 0x17;
9110 }
9111
9112 /* auto-toggle front mic */
9113 /*
9114 static void alc883_mitac_mic_automute(struct hda_codec *codec)
9115 {
9116 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
9117
9118 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
9119 }
9120 */
9121
9122 static struct hda_verb alc883_mitac_verbs[] = {
9123 /* HP */
9124 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9126 /* Subwoofer */
9127 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9128 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9129
9130 /* enable unsolicited event */
9131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9132 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9133
9134 { } /* end */
9135 };
9136
9137 static struct hda_verb alc883_clevo_m540r_verbs[] = {
9138 /* HP */
9139 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9141 /* Int speaker */
9142 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9143
9144 /* enable unsolicited event */
9145 /*
9146 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9147 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9148 */
9149
9150 { } /* end */
9151 };
9152
9153 static struct hda_verb alc883_clevo_m720_verbs[] = {
9154 /* HP */
9155 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9157 /* Int speaker */
9158 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9160
9161 /* enable unsolicited event */
9162 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9163 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9164
9165 { } /* end */
9166 };
9167
9168 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9169 /* HP */
9170 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9172 /* Subwoofer */
9173 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9175
9176 /* enable unsolicited event */
9177 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9178
9179 { } /* end */
9180 };
9181
9182 static struct hda_verb alc883_targa_verbs[] = {
9183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9185
9186 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9187 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9188
9189 /* Connect Line-Out side jack (SPDIF) to Side */
9190 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9191 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9192 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9193 /* Connect Mic jack to CLFE */
9194 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9195 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9196 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9197 /* Connect Line-in jack to Surround */
9198 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9199 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9200 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9201 /* Connect HP out jack to Front */
9202 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9203 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9204 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9205
9206 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9207
9208 { } /* end */
9209 };
9210
9211 static struct hda_verb alc883_lenovo_101e_verbs[] = {
9212 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9214 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9215 { } /* end */
9216 };
9217
9218 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9219 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9221 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9222 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9223 { } /* end */
9224 };
9225
9226 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9229 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9230 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9231 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9232 { } /* end */
9233 };
9234
9235 static struct hda_verb alc883_haier_w66_verbs[] = {
9236 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9237 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9238
9239 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9240
9241 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9242 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9243 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9245 { } /* end */
9246 };
9247
9248 static struct hda_verb alc888_lenovo_sky_verbs[] = {
9249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9254 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9255 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9256 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9257 { } /* end */
9258 };
9259
9260 static struct hda_verb alc888_6st_dell_verbs[] = {
9261 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9262 { }
9263 };
9264
9265 static struct hda_verb alc883_vaiott_verbs[] = {
9266 /* HP */
9267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9269
9270 /* enable unsolicited event */
9271 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9272
9273 { } /* end */
9274 };
9275
9276 static void alc888_3st_hp_setup(struct hda_codec *codec)
9277 {
9278 struct alc_spec *spec = codec->spec;
9279
9280 spec->autocfg.hp_pins[0] = 0x1b;
9281 spec->autocfg.speaker_pins[0] = 0x14;
9282 spec->autocfg.speaker_pins[1] = 0x16;
9283 spec->autocfg.speaker_pins[2] = 0x18;
9284 }
9285
9286 static struct hda_verb alc888_3st_hp_verbs[] = {
9287 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9288 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9289 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9290 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9291 { } /* end */
9292 };
9293
9294 /*
9295 * 2ch mode
9296 */
9297 static struct hda_verb alc888_3st_hp_2ch_init[] = {
9298 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9299 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9300 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9301 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9302 { } /* end */
9303 };
9304
9305 /*
9306 * 4ch mode
9307 */
9308 static struct hda_verb alc888_3st_hp_4ch_init[] = {
9309 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9310 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9311 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9312 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9313 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9314 { } /* end */
9315 };
9316
9317 /*
9318 * 6ch mode
9319 */
9320 static struct hda_verb alc888_3st_hp_6ch_init[] = {
9321 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9322 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9323 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9324 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9325 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9326 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9327 { } /* end */
9328 };
9329
9330 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
9331 { 2, alc888_3st_hp_2ch_init },
9332 { 4, alc888_3st_hp_4ch_init },
9333 { 6, alc888_3st_hp_6ch_init },
9334 };
9335
9336 /* toggle front-jack and RCA according to the hp-jack state */
9337 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9338 {
9339 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
9340
9341 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9342 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9343 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9344 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9345 }
9346
9347 /* toggle RCA according to the front-jack state */
9348 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9349 {
9350 unsigned int present = snd_hda_jack_detect(codec, 0x14);
9351
9352 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9353 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9354 }
9355
9356 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9357 unsigned int res)
9358 {
9359 if ((res >> 26) == ALC880_HP_EVENT)
9360 alc888_lenovo_ms7195_front_automute(codec);
9361 if ((res >> 26) == ALC880_FRONT_EVENT)
9362 alc888_lenovo_ms7195_rca_automute(codec);
9363 }
9364
9365 static struct hda_verb alc883_medion_md2_verbs[] = {
9366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9368
9369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9370
9371 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9372 { } /* end */
9373 };
9374
9375 /* toggle speaker-output according to the hp-jack state */
9376 static void alc883_medion_md2_setup(struct hda_codec *codec)
9377 {
9378 struct alc_spec *spec = codec->spec;
9379
9380 spec->autocfg.hp_pins[0] = 0x14;
9381 spec->autocfg.speaker_pins[0] = 0x15;
9382 }
9383
9384 /* toggle speaker-output according to the hp-jack state */
9385 #define alc883_targa_init_hook alc882_targa_init_hook
9386 #define alc883_targa_unsol_event alc882_targa_unsol_event
9387
9388 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9389 {
9390 unsigned int present;
9391
9392 present = snd_hda_jack_detect(codec, 0x18);
9393 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9394 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9395 }
9396
9397 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9398 {
9399 struct alc_spec *spec = codec->spec;
9400
9401 spec->autocfg.hp_pins[0] = 0x15;
9402 spec->autocfg.speaker_pins[0] = 0x14;
9403 }
9404
9405 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9406 {
9407 alc_automute_amp(codec);
9408 alc883_clevo_m720_mic_automute(codec);
9409 }
9410
9411 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9412 unsigned int res)
9413 {
9414 switch (res >> 26) {
9415 case ALC880_MIC_EVENT:
9416 alc883_clevo_m720_mic_automute(codec);
9417 break;
9418 default:
9419 alc_automute_amp_unsol_event(codec, res);
9420 break;
9421 }
9422 }
9423
9424 /* toggle speaker-output according to the hp-jack state */
9425 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9426 {
9427 struct alc_spec *spec = codec->spec;
9428
9429 spec->autocfg.hp_pins[0] = 0x14;
9430 spec->autocfg.speaker_pins[0] = 0x15;
9431 }
9432
9433 static void alc883_haier_w66_setup(struct hda_codec *codec)
9434 {
9435 struct alc_spec *spec = codec->spec;
9436
9437 spec->autocfg.hp_pins[0] = 0x1b;
9438 spec->autocfg.speaker_pins[0] = 0x14;
9439 }
9440
9441 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9442 {
9443 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
9444
9445 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9446 HDA_AMP_MUTE, bits);
9447 }
9448
9449 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9450 {
9451 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9452
9453 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9454 HDA_AMP_MUTE, bits);
9455 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9456 HDA_AMP_MUTE, bits);
9457 }
9458
9459 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9460 unsigned int res)
9461 {
9462 if ((res >> 26) == ALC880_HP_EVENT)
9463 alc883_lenovo_101e_all_automute(codec);
9464 if ((res >> 26) == ALC880_FRONT_EVENT)
9465 alc883_lenovo_101e_ispeaker_automute(codec);
9466 }
9467
9468 /* toggle speaker-output according to the hp-jack state */
9469 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9470 {
9471 struct alc_spec *spec = codec->spec;
9472
9473 spec->autocfg.hp_pins[0] = 0x14;
9474 spec->autocfg.speaker_pins[0] = 0x15;
9475 spec->autocfg.speaker_pins[1] = 0x16;
9476 }
9477
9478 static struct hda_verb alc883_acer_eapd_verbs[] = {
9479 /* HP Pin: output 0 (0x0c) */
9480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9483 /* Front Pin: output 0 (0x0c) */
9484 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9485 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9486 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9487 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9488 /* eanable EAPD on medion laptop */
9489 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9490 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9491 /* enable unsolicited event */
9492 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9493 { }
9494 };
9495
9496 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9497 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9498 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9500 { } /* end */
9501 };
9502
9503 static void alc888_6st_dell_setup(struct hda_codec *codec)
9504 {
9505 struct alc_spec *spec = codec->spec;
9506
9507 spec->autocfg.hp_pins[0] = 0x1b;
9508 spec->autocfg.speaker_pins[0] = 0x14;
9509 spec->autocfg.speaker_pins[1] = 0x15;
9510 spec->autocfg.speaker_pins[2] = 0x16;
9511 spec->autocfg.speaker_pins[3] = 0x17;
9512 }
9513
9514 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9515 {
9516 struct alc_spec *spec = codec->spec;
9517
9518 spec->autocfg.hp_pins[0] = 0x1b;
9519 spec->autocfg.speaker_pins[0] = 0x14;
9520 spec->autocfg.speaker_pins[1] = 0x15;
9521 spec->autocfg.speaker_pins[2] = 0x16;
9522 spec->autocfg.speaker_pins[3] = 0x17;
9523 spec->autocfg.speaker_pins[4] = 0x1a;
9524 }
9525
9526 static void alc883_vaiott_setup(struct hda_codec *codec)
9527 {
9528 struct alc_spec *spec = codec->spec;
9529
9530 spec->autocfg.hp_pins[0] = 0x15;
9531 spec->autocfg.speaker_pins[0] = 0x14;
9532 spec->autocfg.speaker_pins[1] = 0x17;
9533 }
9534
9535 static struct hda_verb alc888_asus_m90v_verbs[] = {
9536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9537 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9538 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9539 /* enable unsolicited event */
9540 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9541 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9542 { } /* end */
9543 };
9544
9545 static void alc883_mode2_setup(struct hda_codec *codec)
9546 {
9547 struct alc_spec *spec = codec->spec;
9548
9549 spec->autocfg.hp_pins[0] = 0x1b;
9550 spec->autocfg.speaker_pins[0] = 0x14;
9551 spec->autocfg.speaker_pins[1] = 0x15;
9552 spec->autocfg.speaker_pins[2] = 0x16;
9553 spec->ext_mic.pin = 0x18;
9554 spec->int_mic.pin = 0x19;
9555 spec->ext_mic.mux_idx = 0;
9556 spec->int_mic.mux_idx = 1;
9557 spec->auto_mic = 1;
9558 }
9559
9560 static struct hda_verb alc888_asus_eee1601_verbs[] = {
9561 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9566 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9567 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9568 /* enable unsolicited event */
9569 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9570 { } /* end */
9571 };
9572
9573 static void alc883_eee1601_inithook(struct hda_codec *codec)
9574 {
9575 struct alc_spec *spec = codec->spec;
9576
9577 spec->autocfg.hp_pins[0] = 0x14;
9578 spec->autocfg.speaker_pins[0] = 0x1b;
9579 alc_automute_pin(codec);
9580 }
9581
9582 static struct hda_verb alc889A_mb31_verbs[] = {
9583 /* Init rear pin (used as headphone output) */
9584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9585 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9586 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9587 /* Init line pin (used as output in 4ch and 6ch mode) */
9588 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9589 /* Init line 2 pin (used as headphone out by default) */
9590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9591 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9592 { } /* end */
9593 };
9594
9595 /* Mute speakers according to the headphone jack state */
9596 static void alc889A_mb31_automute(struct hda_codec *codec)
9597 {
9598 unsigned int present;
9599
9600 /* Mute only in 2ch or 4ch mode */
9601 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9602 == 0x00) {
9603 present = snd_hda_jack_detect(codec, 0x15);
9604 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9605 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9606 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9607 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9608 }
9609 }
9610
9611 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9612 {
9613 if ((res >> 26) == ALC880_HP_EVENT)
9614 alc889A_mb31_automute(codec);
9615 }
9616
9617
9618 #ifdef CONFIG_SND_HDA_POWER_SAVE
9619 #define alc882_loopbacks alc880_loopbacks
9620 #endif
9621
9622 /* pcm configuration: identical with ALC880 */
9623 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9624 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9625 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9626 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9627
9628 static hda_nid_t alc883_slave_dig_outs[] = {
9629 ALC1200_DIGOUT_NID, 0,
9630 };
9631
9632 static hda_nid_t alc1200_slave_dig_outs[] = {
9633 ALC883_DIGOUT_NID, 0,
9634 };
9635
9636 /*
9637 * configuration and preset
9638 */
9639 static const char *alc882_models[ALC882_MODEL_LAST] = {
9640 [ALC882_3ST_DIG] = "3stack-dig",
9641 [ALC882_6ST_DIG] = "6stack-dig",
9642 [ALC882_ARIMA] = "arima",
9643 [ALC882_W2JC] = "w2jc",
9644 [ALC882_TARGA] = "targa",
9645 [ALC882_ASUS_A7J] = "asus-a7j",
9646 [ALC882_ASUS_A7M] = "asus-a7m",
9647 [ALC885_MACPRO] = "macpro",
9648 [ALC885_MB5] = "mb5",
9649 [ALC885_MACMINI3] = "macmini3",
9650 [ALC885_MBA21] = "mba21",
9651 [ALC885_MBP3] = "mbp3",
9652 [ALC885_IMAC24] = "imac24",
9653 [ALC885_IMAC91] = "imac91",
9654 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9655 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9656 [ALC883_3ST_6ch] = "3stack-6ch",
9657 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9658 [ALC883_TARGA_DIG] = "targa-dig",
9659 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9660 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9661 [ALC883_ACER] = "acer",
9662 [ALC883_ACER_ASPIRE] = "acer-aspire",
9663 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9664 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9665 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9666 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9667 [ALC883_MEDION] = "medion",
9668 [ALC883_MEDION_MD2] = "medion-md2",
9669 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9670 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9671 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9672 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9673 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9674 [ALC888_LENOVO_SKY] = "lenovo-sky",
9675 [ALC883_HAIER_W66] = "haier-w66",
9676 [ALC888_3ST_HP] = "3stack-hp",
9677 [ALC888_6ST_DELL] = "6stack-dell",
9678 [ALC883_MITAC] = "mitac",
9679 [ALC883_CLEVO_M540R] = "clevo-m540r",
9680 [ALC883_CLEVO_M720] = "clevo-m720",
9681 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9682 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9683 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9684 [ALC889A_INTEL] = "intel-alc889a",
9685 [ALC889_INTEL] = "intel-x58",
9686 [ALC1200_ASUS_P5Q] = "asus-p5q",
9687 [ALC889A_MB31] = "mb31",
9688 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9689 [ALC882_AUTO] = "auto",
9690 };
9691
9692 static struct snd_pci_quirk alc882_cfg_tbl[] = {
9693 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9694
9695 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9696 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9697 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9698 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9699 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9700 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9701 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9702 ALC888_ACER_ASPIRE_4930G),
9703 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9704 ALC888_ACER_ASPIRE_4930G),
9705 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9706 ALC888_ACER_ASPIRE_8930G),
9707 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9708 ALC888_ACER_ASPIRE_8930G),
9709 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9710 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9711 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9712 ALC888_ACER_ASPIRE_6530G),
9713 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9714 ALC888_ACER_ASPIRE_6530G),
9715 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9716 ALC888_ACER_ASPIRE_7730G),
9717 /* default Acer -- disabled as it causes more problems.
9718 * model=auto should work fine now
9719 */
9720 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9721
9722 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9723
9724 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9725 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9726 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9727 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9728 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9729 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9730
9731 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9732 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9733 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9734 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9735 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9736 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9737 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9738 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9739 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9740 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9741 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9742
9743 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9744 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9745 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9746 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9747 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9748 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9749 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9750 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9751 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9752
9753 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9754 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9755 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9756 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9757 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9758 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9759 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9760 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9761 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9762 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9763 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9764 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9765 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9766 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9767 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9768 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9769 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9770 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9771 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9772 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9773 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9774 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9775 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9776 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9777 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9778 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9779 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9780 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9781 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9782 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9783 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9784
9785 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9786 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9787 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9788 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9789 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9790 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9791 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9792 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9793 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9794 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9795 ALC883_FUJITSU_PI2515),
9796 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9797 ALC888_FUJITSU_XA3530),
9798 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9799 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9800 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9801 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9802 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9803 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
9804 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9805 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9806 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9807
9808 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9809 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9810 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9811 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9812 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9813 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9814 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9815
9816 {}
9817 };
9818
9819 /* codec SSID table for Intel Mac */
9820 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9821 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9822 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9823 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9824 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9825 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9826 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9827 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9828 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9829 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9830 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9831 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9832 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9833 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9834 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9835 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9836 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9837 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
9838 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9839 * so apparently no perfect solution yet
9840 */
9841 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9842 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9843 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9844 {} /* terminator */
9845 };
9846
9847 static struct alc_config_preset alc882_presets[] = {
9848 [ALC882_3ST_DIG] = {
9849 .mixers = { alc882_base_mixer },
9850 .init_verbs = { alc882_base_init_verbs,
9851 alc882_adc1_init_verbs },
9852 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9853 .dac_nids = alc882_dac_nids,
9854 .dig_out_nid = ALC882_DIGOUT_NID,
9855 .dig_in_nid = ALC882_DIGIN_NID,
9856 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9857 .channel_mode = alc882_ch_modes,
9858 .need_dac_fix = 1,
9859 .input_mux = &alc882_capture_source,
9860 },
9861 [ALC882_6ST_DIG] = {
9862 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9863 .init_verbs = { alc882_base_init_verbs,
9864 alc882_adc1_init_verbs },
9865 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9866 .dac_nids = alc882_dac_nids,
9867 .dig_out_nid = ALC882_DIGOUT_NID,
9868 .dig_in_nid = ALC882_DIGIN_NID,
9869 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9870 .channel_mode = alc882_sixstack_modes,
9871 .input_mux = &alc882_capture_source,
9872 },
9873 [ALC882_ARIMA] = {
9874 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9875 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9876 alc882_eapd_verbs },
9877 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9878 .dac_nids = alc882_dac_nids,
9879 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9880 .channel_mode = alc882_sixstack_modes,
9881 .input_mux = &alc882_capture_source,
9882 },
9883 [ALC882_W2JC] = {
9884 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
9885 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9886 alc882_eapd_verbs, alc880_gpio1_init_verbs },
9887 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9888 .dac_nids = alc882_dac_nids,
9889 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9890 .channel_mode = alc880_threestack_modes,
9891 .need_dac_fix = 1,
9892 .input_mux = &alc882_capture_source,
9893 .dig_out_nid = ALC882_DIGOUT_NID,
9894 },
9895 [ALC885_MBA21] = {
9896 .mixers = { alc885_mba21_mixer },
9897 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9898 .num_dacs = 2,
9899 .dac_nids = alc882_dac_nids,
9900 .channel_mode = alc885_mba21_ch_modes,
9901 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9902 .input_mux = &alc882_capture_source,
9903 .unsol_event = alc_automute_amp_unsol_event,
9904 .setup = alc885_mba21_setup,
9905 .init_hook = alc_automute_amp,
9906 },
9907 [ALC885_MBP3] = {
9908 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9909 .init_verbs = { alc885_mbp3_init_verbs,
9910 alc880_gpio1_init_verbs },
9911 .num_dacs = 2,
9912 .dac_nids = alc882_dac_nids,
9913 .hp_nid = 0x04,
9914 .channel_mode = alc885_mbp_4ch_modes,
9915 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9916 .input_mux = &alc882_capture_source,
9917 .dig_out_nid = ALC882_DIGOUT_NID,
9918 .dig_in_nid = ALC882_DIGIN_NID,
9919 .unsol_event = alc_automute_amp_unsol_event,
9920 .setup = alc885_mbp3_setup,
9921 .init_hook = alc_automute_amp,
9922 },
9923 [ALC885_MB5] = {
9924 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9925 .init_verbs = { alc885_mb5_init_verbs,
9926 alc880_gpio1_init_verbs },
9927 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9928 .dac_nids = alc882_dac_nids,
9929 .channel_mode = alc885_mb5_6ch_modes,
9930 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9931 .input_mux = &mb5_capture_source,
9932 .dig_out_nid = ALC882_DIGOUT_NID,
9933 .dig_in_nid = ALC882_DIGIN_NID,
9934 .unsol_event = alc_automute_amp_unsol_event,
9935 .setup = alc885_mb5_setup,
9936 .init_hook = alc_automute_amp,
9937 },
9938 [ALC885_MACMINI3] = {
9939 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9940 .init_verbs = { alc885_macmini3_init_verbs,
9941 alc880_gpio1_init_verbs },
9942 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9943 .dac_nids = alc882_dac_nids,
9944 .channel_mode = alc885_macmini3_6ch_modes,
9945 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9946 .input_mux = &macmini3_capture_source,
9947 .dig_out_nid = ALC882_DIGOUT_NID,
9948 .dig_in_nid = ALC882_DIGIN_NID,
9949 .unsol_event = alc_automute_amp_unsol_event,
9950 .setup = alc885_macmini3_setup,
9951 .init_hook = alc_automute_amp,
9952 },
9953 [ALC885_MACPRO] = {
9954 .mixers = { alc882_macpro_mixer },
9955 .init_verbs = { alc882_macpro_init_verbs },
9956 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9957 .dac_nids = alc882_dac_nids,
9958 .dig_out_nid = ALC882_DIGOUT_NID,
9959 .dig_in_nid = ALC882_DIGIN_NID,
9960 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9961 .channel_mode = alc882_ch_modes,
9962 .input_mux = &alc882_capture_source,
9963 .init_hook = alc885_macpro_init_hook,
9964 },
9965 [ALC885_IMAC24] = {
9966 .mixers = { alc885_imac24_mixer },
9967 .init_verbs = { alc885_imac24_init_verbs },
9968 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9969 .dac_nids = alc882_dac_nids,
9970 .dig_out_nid = ALC882_DIGOUT_NID,
9971 .dig_in_nid = ALC882_DIGIN_NID,
9972 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9973 .channel_mode = alc882_ch_modes,
9974 .input_mux = &alc882_capture_source,
9975 .unsol_event = alc_automute_amp_unsol_event,
9976 .setup = alc885_imac24_setup,
9977 .init_hook = alc885_imac24_init_hook,
9978 },
9979 [ALC885_IMAC91] = {
9980 .mixers = {alc885_imac91_mixer},
9981 .init_verbs = { alc885_imac91_init_verbs,
9982 alc880_gpio1_init_verbs },
9983 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9984 .dac_nids = alc882_dac_nids,
9985 .channel_mode = alc885_mba21_ch_modes,
9986 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9987 .input_mux = &alc889A_imac91_capture_source,
9988 .dig_out_nid = ALC882_DIGOUT_NID,
9989 .dig_in_nid = ALC882_DIGIN_NID,
9990 .unsol_event = alc_automute_amp_unsol_event,
9991 .setup = alc885_imac91_setup,
9992 .init_hook = alc_automute_amp,
9993 },
9994 [ALC882_TARGA] = {
9995 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
9996 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9997 alc880_gpio3_init_verbs, alc882_targa_verbs},
9998 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9999 .dac_nids = alc882_dac_nids,
10000 .dig_out_nid = ALC882_DIGOUT_NID,
10001 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10002 .adc_nids = alc882_adc_nids,
10003 .capsrc_nids = alc882_capsrc_nids,
10004 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10005 .channel_mode = alc882_3ST_6ch_modes,
10006 .need_dac_fix = 1,
10007 .input_mux = &alc882_capture_source,
10008 .unsol_event = alc882_targa_unsol_event,
10009 .setup = alc882_targa_setup,
10010 .init_hook = alc882_targa_automute,
10011 },
10012 [ALC882_ASUS_A7J] = {
10013 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10014 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10015 alc882_asus_a7j_verbs},
10016 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10017 .dac_nids = alc882_dac_nids,
10018 .dig_out_nid = ALC882_DIGOUT_NID,
10019 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10020 .adc_nids = alc882_adc_nids,
10021 .capsrc_nids = alc882_capsrc_nids,
10022 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10023 .channel_mode = alc882_3ST_6ch_modes,
10024 .need_dac_fix = 1,
10025 .input_mux = &alc882_capture_source,
10026 },
10027 [ALC882_ASUS_A7M] = {
10028 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10029 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10030 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10031 alc882_asus_a7m_verbs },
10032 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10033 .dac_nids = alc882_dac_nids,
10034 .dig_out_nid = ALC882_DIGOUT_NID,
10035 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10036 .channel_mode = alc880_threestack_modes,
10037 .need_dac_fix = 1,
10038 .input_mux = &alc882_capture_source,
10039 },
10040 [ALC883_3ST_2ch_DIG] = {
10041 .mixers = { alc883_3ST_2ch_mixer },
10042 .init_verbs = { alc883_init_verbs },
10043 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10044 .dac_nids = alc883_dac_nids,
10045 .dig_out_nid = ALC883_DIGOUT_NID,
10046 .dig_in_nid = ALC883_DIGIN_NID,
10047 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10048 .channel_mode = alc883_3ST_2ch_modes,
10049 .input_mux = &alc883_capture_source,
10050 },
10051 [ALC883_3ST_6ch_DIG] = {
10052 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10053 .init_verbs = { alc883_init_verbs },
10054 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10055 .dac_nids = alc883_dac_nids,
10056 .dig_out_nid = ALC883_DIGOUT_NID,
10057 .dig_in_nid = ALC883_DIGIN_NID,
10058 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10059 .channel_mode = alc883_3ST_6ch_modes,
10060 .need_dac_fix = 1,
10061 .input_mux = &alc883_capture_source,
10062 },
10063 [ALC883_3ST_6ch] = {
10064 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10065 .init_verbs = { alc883_init_verbs },
10066 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10067 .dac_nids = alc883_dac_nids,
10068 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10069 .channel_mode = alc883_3ST_6ch_modes,
10070 .need_dac_fix = 1,
10071 .input_mux = &alc883_capture_source,
10072 },
10073 [ALC883_3ST_6ch_INTEL] = {
10074 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10075 .init_verbs = { alc883_init_verbs },
10076 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10077 .dac_nids = alc883_dac_nids,
10078 .dig_out_nid = ALC883_DIGOUT_NID,
10079 .dig_in_nid = ALC883_DIGIN_NID,
10080 .slave_dig_outs = alc883_slave_dig_outs,
10081 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10082 .channel_mode = alc883_3ST_6ch_intel_modes,
10083 .need_dac_fix = 1,
10084 .input_mux = &alc883_3stack_6ch_intel,
10085 },
10086 [ALC889A_INTEL] = {
10087 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10088 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10089 alc_hp15_unsol_verbs },
10090 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10091 .dac_nids = alc883_dac_nids,
10092 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10093 .adc_nids = alc889_adc_nids,
10094 .dig_out_nid = ALC883_DIGOUT_NID,
10095 .dig_in_nid = ALC883_DIGIN_NID,
10096 .slave_dig_outs = alc883_slave_dig_outs,
10097 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10098 .channel_mode = alc889_8ch_intel_modes,
10099 .capsrc_nids = alc889_capsrc_nids,
10100 .input_mux = &alc889_capture_source,
10101 .setup = alc889_automute_setup,
10102 .init_hook = alc_automute_amp,
10103 .unsol_event = alc_automute_amp_unsol_event,
10104 .need_dac_fix = 1,
10105 },
10106 [ALC889_INTEL] = {
10107 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10108 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10109 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10110 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10111 .dac_nids = alc883_dac_nids,
10112 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10113 .adc_nids = alc889_adc_nids,
10114 .dig_out_nid = ALC883_DIGOUT_NID,
10115 .dig_in_nid = ALC883_DIGIN_NID,
10116 .slave_dig_outs = alc883_slave_dig_outs,
10117 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10118 .channel_mode = alc889_8ch_intel_modes,
10119 .capsrc_nids = alc889_capsrc_nids,
10120 .input_mux = &alc889_capture_source,
10121 .setup = alc889_automute_setup,
10122 .init_hook = alc889_intel_init_hook,
10123 .unsol_event = alc_automute_amp_unsol_event,
10124 .need_dac_fix = 1,
10125 },
10126 [ALC883_6ST_DIG] = {
10127 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10128 .init_verbs = { alc883_init_verbs },
10129 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10130 .dac_nids = alc883_dac_nids,
10131 .dig_out_nid = ALC883_DIGOUT_NID,
10132 .dig_in_nid = ALC883_DIGIN_NID,
10133 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10134 .channel_mode = alc883_sixstack_modes,
10135 .input_mux = &alc883_capture_source,
10136 },
10137 [ALC883_TARGA_DIG] = {
10138 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10139 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10140 alc883_targa_verbs},
10141 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10142 .dac_nids = alc883_dac_nids,
10143 .dig_out_nid = ALC883_DIGOUT_NID,
10144 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10145 .channel_mode = alc883_3ST_6ch_modes,
10146 .need_dac_fix = 1,
10147 .input_mux = &alc883_capture_source,
10148 .unsol_event = alc883_targa_unsol_event,
10149 .setup = alc882_targa_setup,
10150 .init_hook = alc882_targa_automute,
10151 },
10152 [ALC883_TARGA_2ch_DIG] = {
10153 .mixers = { alc883_targa_2ch_mixer},
10154 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10155 alc883_targa_verbs},
10156 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10157 .dac_nids = alc883_dac_nids,
10158 .adc_nids = alc883_adc_nids_alt,
10159 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10160 .capsrc_nids = alc883_capsrc_nids,
10161 .dig_out_nid = ALC883_DIGOUT_NID,
10162 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10163 .channel_mode = alc883_3ST_2ch_modes,
10164 .input_mux = &alc883_capture_source,
10165 .unsol_event = alc883_targa_unsol_event,
10166 .setup = alc882_targa_setup,
10167 .init_hook = alc882_targa_automute,
10168 },
10169 [ALC883_TARGA_8ch_DIG] = {
10170 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10171 alc883_chmode_mixer },
10172 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10173 alc883_targa_verbs },
10174 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10175 .dac_nids = alc883_dac_nids,
10176 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10177 .adc_nids = alc883_adc_nids_rev,
10178 .capsrc_nids = alc883_capsrc_nids_rev,
10179 .dig_out_nid = ALC883_DIGOUT_NID,
10180 .dig_in_nid = ALC883_DIGIN_NID,
10181 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10182 .channel_mode = alc883_4ST_8ch_modes,
10183 .need_dac_fix = 1,
10184 .input_mux = &alc883_capture_source,
10185 .unsol_event = alc883_targa_unsol_event,
10186 .setup = alc882_targa_setup,
10187 .init_hook = alc882_targa_automute,
10188 },
10189 [ALC883_ACER] = {
10190 .mixers = { alc883_base_mixer },
10191 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10192 * and the headphone jack. Turn this on and rely on the
10193 * standard mute methods whenever the user wants to turn
10194 * these outputs off.
10195 */
10196 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10197 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10198 .dac_nids = alc883_dac_nids,
10199 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10200 .channel_mode = alc883_3ST_2ch_modes,
10201 .input_mux = &alc883_capture_source,
10202 },
10203 [ALC883_ACER_ASPIRE] = {
10204 .mixers = { alc883_acer_aspire_mixer },
10205 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10206 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10207 .dac_nids = alc883_dac_nids,
10208 .dig_out_nid = ALC883_DIGOUT_NID,
10209 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10210 .channel_mode = alc883_3ST_2ch_modes,
10211 .input_mux = &alc883_capture_source,
10212 .unsol_event = alc_automute_amp_unsol_event,
10213 .setup = alc883_acer_aspire_setup,
10214 .init_hook = alc_automute_amp,
10215 },
10216 [ALC888_ACER_ASPIRE_4930G] = {
10217 .mixers = { alc888_base_mixer,
10218 alc883_chmode_mixer },
10219 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10220 alc888_acer_aspire_4930g_verbs },
10221 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10222 .dac_nids = alc883_dac_nids,
10223 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10224 .adc_nids = alc883_adc_nids_rev,
10225 .capsrc_nids = alc883_capsrc_nids_rev,
10226 .dig_out_nid = ALC883_DIGOUT_NID,
10227 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10228 .channel_mode = alc883_3ST_6ch_modes,
10229 .need_dac_fix = 1,
10230 .const_channel_count = 6,
10231 .num_mux_defs =
10232 ARRAY_SIZE(alc888_2_capture_sources),
10233 .input_mux = alc888_2_capture_sources,
10234 .unsol_event = alc_automute_amp_unsol_event,
10235 .setup = alc888_acer_aspire_4930g_setup,
10236 .init_hook = alc_automute_amp,
10237 },
10238 [ALC888_ACER_ASPIRE_6530G] = {
10239 .mixers = { alc888_acer_aspire_6530_mixer },
10240 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10241 alc888_acer_aspire_6530g_verbs },
10242 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10243 .dac_nids = alc883_dac_nids,
10244 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10245 .adc_nids = alc883_adc_nids_rev,
10246 .capsrc_nids = alc883_capsrc_nids_rev,
10247 .dig_out_nid = ALC883_DIGOUT_NID,
10248 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10249 .channel_mode = alc883_3ST_2ch_modes,
10250 .num_mux_defs =
10251 ARRAY_SIZE(alc888_2_capture_sources),
10252 .input_mux = alc888_acer_aspire_6530_sources,
10253 .unsol_event = alc_automute_amp_unsol_event,
10254 .setup = alc888_acer_aspire_6530g_setup,
10255 .init_hook = alc_automute_amp,
10256 },
10257 [ALC888_ACER_ASPIRE_8930G] = {
10258 .mixers = { alc889_acer_aspire_8930g_mixer,
10259 alc883_chmode_mixer },
10260 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10261 alc889_acer_aspire_8930g_verbs,
10262 alc889_eapd_verbs},
10263 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10264 .dac_nids = alc883_dac_nids,
10265 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10266 .adc_nids = alc889_adc_nids,
10267 .capsrc_nids = alc889_capsrc_nids,
10268 .dig_out_nid = ALC883_DIGOUT_NID,
10269 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10270 .channel_mode = alc883_3ST_6ch_modes,
10271 .need_dac_fix = 1,
10272 .const_channel_count = 6,
10273 .num_mux_defs =
10274 ARRAY_SIZE(alc889_capture_sources),
10275 .input_mux = alc889_capture_sources,
10276 .unsol_event = alc_automute_amp_unsol_event,
10277 .setup = alc889_acer_aspire_8930g_setup,
10278 .init_hook = alc_automute_amp,
10279 #ifdef CONFIG_SND_HDA_POWER_SAVE
10280 .power_hook = alc_power_eapd,
10281 #endif
10282 },
10283 [ALC888_ACER_ASPIRE_7730G] = {
10284 .mixers = { alc883_3ST_6ch_mixer,
10285 alc883_chmode_mixer },
10286 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10287 alc888_acer_aspire_7730G_verbs },
10288 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10289 .dac_nids = alc883_dac_nids,
10290 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10291 .adc_nids = alc883_adc_nids_rev,
10292 .capsrc_nids = alc883_capsrc_nids_rev,
10293 .dig_out_nid = ALC883_DIGOUT_NID,
10294 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10295 .channel_mode = alc883_3ST_6ch_modes,
10296 .need_dac_fix = 1,
10297 .const_channel_count = 6,
10298 .input_mux = &alc883_capture_source,
10299 .unsol_event = alc_automute_amp_unsol_event,
10300 .setup = alc888_acer_aspire_6530g_setup,
10301 .init_hook = alc_automute_amp,
10302 },
10303 [ALC883_MEDION] = {
10304 .mixers = { alc883_fivestack_mixer,
10305 alc883_chmode_mixer },
10306 .init_verbs = { alc883_init_verbs,
10307 alc883_medion_eapd_verbs },
10308 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10309 .dac_nids = alc883_dac_nids,
10310 .adc_nids = alc883_adc_nids_alt,
10311 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10312 .capsrc_nids = alc883_capsrc_nids,
10313 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10314 .channel_mode = alc883_sixstack_modes,
10315 .input_mux = &alc883_capture_source,
10316 },
10317 [ALC883_MEDION_MD2] = {
10318 .mixers = { alc883_medion_md2_mixer},
10319 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10320 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10321 .dac_nids = alc883_dac_nids,
10322 .dig_out_nid = ALC883_DIGOUT_NID,
10323 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10324 .channel_mode = alc883_3ST_2ch_modes,
10325 .input_mux = &alc883_capture_source,
10326 .unsol_event = alc_automute_amp_unsol_event,
10327 .setup = alc883_medion_md2_setup,
10328 .init_hook = alc_automute_amp,
10329 },
10330 [ALC883_MEDION_WIM2160] = {
10331 .mixers = { alc883_medion_wim2160_mixer },
10332 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10333 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10334 .dac_nids = alc883_dac_nids,
10335 .dig_out_nid = ALC883_DIGOUT_NID,
10336 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10337 .adc_nids = alc883_adc_nids,
10338 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10339 .channel_mode = alc883_3ST_2ch_modes,
10340 .input_mux = &alc883_capture_source,
10341 .unsol_event = alc_automute_amp_unsol_event,
10342 .setup = alc883_medion_wim2160_setup,
10343 .init_hook = alc_automute_amp,
10344 },
10345 [ALC883_LAPTOP_EAPD] = {
10346 .mixers = { alc883_base_mixer },
10347 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10348 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10349 .dac_nids = alc883_dac_nids,
10350 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10351 .channel_mode = alc883_3ST_2ch_modes,
10352 .input_mux = &alc883_capture_source,
10353 },
10354 [ALC883_CLEVO_M540R] = {
10355 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10356 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10357 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10358 .dac_nids = alc883_dac_nids,
10359 .dig_out_nid = ALC883_DIGOUT_NID,
10360 .dig_in_nid = ALC883_DIGIN_NID,
10361 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10362 .channel_mode = alc883_3ST_6ch_clevo_modes,
10363 .need_dac_fix = 1,
10364 .input_mux = &alc883_capture_source,
10365 /* This machine has the hardware HP auto-muting, thus
10366 * we need no software mute via unsol event
10367 */
10368 },
10369 [ALC883_CLEVO_M720] = {
10370 .mixers = { alc883_clevo_m720_mixer },
10371 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10372 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10373 .dac_nids = alc883_dac_nids,
10374 .dig_out_nid = ALC883_DIGOUT_NID,
10375 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10376 .channel_mode = alc883_3ST_2ch_modes,
10377 .input_mux = &alc883_capture_source,
10378 .unsol_event = alc883_clevo_m720_unsol_event,
10379 .setup = alc883_clevo_m720_setup,
10380 .init_hook = alc883_clevo_m720_init_hook,
10381 },
10382 [ALC883_LENOVO_101E_2ch] = {
10383 .mixers = { alc883_lenovo_101e_2ch_mixer},
10384 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10385 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10386 .dac_nids = alc883_dac_nids,
10387 .adc_nids = alc883_adc_nids_alt,
10388 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10389 .capsrc_nids = alc883_capsrc_nids,
10390 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10391 .channel_mode = alc883_3ST_2ch_modes,
10392 .input_mux = &alc883_lenovo_101e_capture_source,
10393 .unsol_event = alc883_lenovo_101e_unsol_event,
10394 .init_hook = alc883_lenovo_101e_all_automute,
10395 },
10396 [ALC883_LENOVO_NB0763] = {
10397 .mixers = { alc883_lenovo_nb0763_mixer },
10398 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10399 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10400 .dac_nids = alc883_dac_nids,
10401 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10402 .channel_mode = alc883_3ST_2ch_modes,
10403 .need_dac_fix = 1,
10404 .input_mux = &alc883_lenovo_nb0763_capture_source,
10405 .unsol_event = alc_automute_amp_unsol_event,
10406 .setup = alc883_medion_md2_setup,
10407 .init_hook = alc_automute_amp,
10408 },
10409 [ALC888_LENOVO_MS7195_DIG] = {
10410 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10411 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10412 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10413 .dac_nids = alc883_dac_nids,
10414 .dig_out_nid = ALC883_DIGOUT_NID,
10415 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10416 .channel_mode = alc883_3ST_6ch_modes,
10417 .need_dac_fix = 1,
10418 .input_mux = &alc883_capture_source,
10419 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10420 .init_hook = alc888_lenovo_ms7195_front_automute,
10421 },
10422 [ALC883_HAIER_W66] = {
10423 .mixers = { alc883_targa_2ch_mixer},
10424 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10425 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10426 .dac_nids = alc883_dac_nids,
10427 .dig_out_nid = ALC883_DIGOUT_NID,
10428 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10429 .channel_mode = alc883_3ST_2ch_modes,
10430 .input_mux = &alc883_capture_source,
10431 .unsol_event = alc_automute_amp_unsol_event,
10432 .setup = alc883_haier_w66_setup,
10433 .init_hook = alc_automute_amp,
10434 },
10435 [ALC888_3ST_HP] = {
10436 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10437 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10438 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10439 .dac_nids = alc883_dac_nids,
10440 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10441 .channel_mode = alc888_3st_hp_modes,
10442 .need_dac_fix = 1,
10443 .input_mux = &alc883_capture_source,
10444 .unsol_event = alc_automute_amp_unsol_event,
10445 .setup = alc888_3st_hp_setup,
10446 .init_hook = alc_automute_amp,
10447 },
10448 [ALC888_6ST_DELL] = {
10449 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10450 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10451 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10452 .dac_nids = alc883_dac_nids,
10453 .dig_out_nid = ALC883_DIGOUT_NID,
10454 .dig_in_nid = ALC883_DIGIN_NID,
10455 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10456 .channel_mode = alc883_sixstack_modes,
10457 .input_mux = &alc883_capture_source,
10458 .unsol_event = alc_automute_amp_unsol_event,
10459 .setup = alc888_6st_dell_setup,
10460 .init_hook = alc_automute_amp,
10461 },
10462 [ALC883_MITAC] = {
10463 .mixers = { alc883_mitac_mixer },
10464 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10465 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10466 .dac_nids = alc883_dac_nids,
10467 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10468 .channel_mode = alc883_3ST_2ch_modes,
10469 .input_mux = &alc883_capture_source,
10470 .unsol_event = alc_automute_amp_unsol_event,
10471 .setup = alc883_mitac_setup,
10472 .init_hook = alc_automute_amp,
10473 },
10474 [ALC883_FUJITSU_PI2515] = {
10475 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10476 .init_verbs = { alc883_init_verbs,
10477 alc883_2ch_fujitsu_pi2515_verbs},
10478 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10479 .dac_nids = alc883_dac_nids,
10480 .dig_out_nid = ALC883_DIGOUT_NID,
10481 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10482 .channel_mode = alc883_3ST_2ch_modes,
10483 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10484 .unsol_event = alc_automute_amp_unsol_event,
10485 .setup = alc883_2ch_fujitsu_pi2515_setup,
10486 .init_hook = alc_automute_amp,
10487 },
10488 [ALC888_FUJITSU_XA3530] = {
10489 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10490 .init_verbs = { alc883_init_verbs,
10491 alc888_fujitsu_xa3530_verbs },
10492 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10493 .dac_nids = alc883_dac_nids,
10494 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10495 .adc_nids = alc883_adc_nids_rev,
10496 .capsrc_nids = alc883_capsrc_nids_rev,
10497 .dig_out_nid = ALC883_DIGOUT_NID,
10498 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10499 .channel_mode = alc888_4ST_8ch_intel_modes,
10500 .num_mux_defs =
10501 ARRAY_SIZE(alc888_2_capture_sources),
10502 .input_mux = alc888_2_capture_sources,
10503 .unsol_event = alc_automute_amp_unsol_event,
10504 .setup = alc888_fujitsu_xa3530_setup,
10505 .init_hook = alc_automute_amp,
10506 },
10507 [ALC888_LENOVO_SKY] = {
10508 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10509 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10510 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10511 .dac_nids = alc883_dac_nids,
10512 .dig_out_nid = ALC883_DIGOUT_NID,
10513 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10514 .channel_mode = alc883_sixstack_modes,
10515 .need_dac_fix = 1,
10516 .input_mux = &alc883_lenovo_sky_capture_source,
10517 .unsol_event = alc_automute_amp_unsol_event,
10518 .setup = alc888_lenovo_sky_setup,
10519 .init_hook = alc_automute_amp,
10520 },
10521 [ALC888_ASUS_M90V] = {
10522 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10523 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
10526 .dig_out_nid = ALC883_DIGOUT_NID,
10527 .dig_in_nid = ALC883_DIGIN_NID,
10528 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10529 .channel_mode = alc883_3ST_6ch_modes,
10530 .need_dac_fix = 1,
10531 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10532 .unsol_event = alc_sku_unsol_event,
10533 .setup = alc883_mode2_setup,
10534 .init_hook = alc_inithook,
10535 },
10536 [ALC888_ASUS_EEE1601] = {
10537 .mixers = { alc883_asus_eee1601_mixer },
10538 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10539 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10541 .dac_nids = alc883_dac_nids,
10542 .dig_out_nid = ALC883_DIGOUT_NID,
10543 .dig_in_nid = ALC883_DIGIN_NID,
10544 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10545 .channel_mode = alc883_3ST_2ch_modes,
10546 .need_dac_fix = 1,
10547 .input_mux = &alc883_asus_eee1601_capture_source,
10548 .unsol_event = alc_sku_unsol_event,
10549 .init_hook = alc883_eee1601_inithook,
10550 },
10551 [ALC1200_ASUS_P5Q] = {
10552 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10553 .init_verbs = { alc883_init_verbs },
10554 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10555 .dac_nids = alc883_dac_nids,
10556 .dig_out_nid = ALC1200_DIGOUT_NID,
10557 .dig_in_nid = ALC883_DIGIN_NID,
10558 .slave_dig_outs = alc1200_slave_dig_outs,
10559 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10560 .channel_mode = alc883_sixstack_modes,
10561 .input_mux = &alc883_capture_source,
10562 },
10563 [ALC889A_MB31] = {
10564 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10565 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10566 alc880_gpio1_init_verbs },
10567 .adc_nids = alc883_adc_nids,
10568 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10569 .capsrc_nids = alc883_capsrc_nids,
10570 .dac_nids = alc883_dac_nids,
10571 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10572 .channel_mode = alc889A_mb31_6ch_modes,
10573 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10574 .input_mux = &alc889A_mb31_capture_source,
10575 .dig_out_nid = ALC883_DIGOUT_NID,
10576 .unsol_event = alc889A_mb31_unsol_event,
10577 .init_hook = alc889A_mb31_automute,
10578 },
10579 [ALC883_SONY_VAIO_TT] = {
10580 .mixers = { alc883_vaiott_mixer },
10581 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10582 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10583 .dac_nids = alc883_dac_nids,
10584 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10585 .channel_mode = alc883_3ST_2ch_modes,
10586 .input_mux = &alc883_capture_source,
10587 .unsol_event = alc_automute_amp_unsol_event,
10588 .setup = alc883_vaiott_setup,
10589 .init_hook = alc_automute_amp,
10590 },
10591 };
10592
10593
10594 /*
10595 * Pin config fixes
10596 */
10597 enum {
10598 PINFIX_ABIT_AW9D_MAX,
10599 PINFIX_PB_M5210,
10600 };
10601
10602 static const struct alc_fixup alc882_fixups[] = {
10603 [PINFIX_ABIT_AW9D_MAX] = {
10604 .pins = (const struct alc_pincfg[]) {
10605 { 0x15, 0x01080104 }, /* side */
10606 { 0x16, 0x01011012 }, /* rear */
10607 { 0x17, 0x01016011 }, /* clfe */
10608 { }
10609 }
10610 },
10611 [PINFIX_PB_M5210] = {
10612 .verbs = (const struct hda_verb[]) {
10613 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10614 {}
10615 }
10616 },
10617 };
10618
10619 static struct snd_pci_quirk alc882_fixup_tbl[] = {
10620 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10621 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10622 {}
10623 };
10624
10625 /*
10626 * BIOS auto configuration
10627 */
10628 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10629 const struct auto_pin_cfg *cfg)
10630 {
10631 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10632 }
10633
10634 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10635 hda_nid_t nid, int pin_type,
10636 hda_nid_t dac)
10637 {
10638 int idx;
10639
10640 /* set as output */
10641 alc_set_pin_output(codec, nid, pin_type);
10642
10643 if (dac == 0x25)
10644 idx = 4;
10645 else if (dac >= 0x02 && dac <= 0x05)
10646 idx = dac - 2;
10647 else
10648 return;
10649 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10650 }
10651
10652 static void alc882_auto_init_multi_out(struct hda_codec *codec)
10653 {
10654 struct alc_spec *spec = codec->spec;
10655 int i;
10656
10657 for (i = 0; i <= HDA_SIDE; i++) {
10658 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10659 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10660 if (nid)
10661 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10662 spec->multiout.dac_nids[i]);
10663 }
10664 }
10665
10666 static void alc882_auto_init_hp_out(struct hda_codec *codec)
10667 {
10668 struct alc_spec *spec = codec->spec;
10669 hda_nid_t pin, dac;
10670 int i;
10671
10672 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10673 pin = spec->autocfg.hp_pins[i];
10674 if (!pin)
10675 break;
10676 dac = spec->multiout.hp_nid;
10677 if (!dac)
10678 dac = spec->multiout.dac_nids[0]; /* to front */
10679 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10680 }
10681 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10682 pin = spec->autocfg.speaker_pins[i];
10683 if (!pin)
10684 break;
10685 dac = spec->multiout.extra_out_nid[0];
10686 if (!dac)
10687 dac = spec->multiout.dac_nids[0]; /* to front */
10688 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10689 }
10690 }
10691
10692 static void alc882_auto_init_analog_input(struct hda_codec *codec)
10693 {
10694 struct alc_spec *spec = codec->spec;
10695 struct auto_pin_cfg *cfg = &spec->autocfg;
10696 int i;
10697
10698 for (i = 0; i < cfg->num_inputs; i++) {
10699 hda_nid_t nid = cfg->inputs[i].pin;
10700 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
10701 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10702 snd_hda_codec_write(codec, nid, 0,
10703 AC_VERB_SET_AMP_GAIN_MUTE,
10704 AMP_OUT_MUTE);
10705 }
10706 }
10707
10708 static void alc882_auto_init_input_src(struct hda_codec *codec)
10709 {
10710 struct alc_spec *spec = codec->spec;
10711 int c;
10712
10713 for (c = 0; c < spec->num_adc_nids; c++) {
10714 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10715 hda_nid_t nid = spec->capsrc_nids[c];
10716 unsigned int mux_idx;
10717 const struct hda_input_mux *imux;
10718 int conns, mute, idx, item;
10719
10720 conns = snd_hda_get_connections(codec, nid, conn_list,
10721 ARRAY_SIZE(conn_list));
10722 if (conns < 0)
10723 continue;
10724 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10725 imux = &spec->input_mux[mux_idx];
10726 if (!imux->num_items && mux_idx > 0)
10727 imux = &spec->input_mux[0];
10728 for (idx = 0; idx < conns; idx++) {
10729 /* if the current connection is the selected one,
10730 * unmute it as default - otherwise mute it
10731 */
10732 mute = AMP_IN_MUTE(idx);
10733 for (item = 0; item < imux->num_items; item++) {
10734 if (imux->items[item].index == idx) {
10735 if (spec->cur_mux[c] == item)
10736 mute = AMP_IN_UNMUTE(idx);
10737 break;
10738 }
10739 }
10740 /* check if we have a selector or mixer
10741 * we could check for the widget type instead, but
10742 * just check for Amp-In presence (in case of mixer
10743 * without amp-in there is something wrong, this
10744 * function shouldn't be used or capsrc nid is wrong)
10745 */
10746 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
10747 snd_hda_codec_write(codec, nid, 0,
10748 AC_VERB_SET_AMP_GAIN_MUTE,
10749 mute);
10750 else if (mute != AMP_IN_MUTE(idx))
10751 snd_hda_codec_write(codec, nid, 0,
10752 AC_VERB_SET_CONNECT_SEL,
10753 idx);
10754 }
10755 }
10756 }
10757
10758 /* add mic boosts if needed */
10759 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10760 {
10761 struct alc_spec *spec = codec->spec;
10762 struct auto_pin_cfg *cfg = &spec->autocfg;
10763 int i, err;
10764 hda_nid_t nid;
10765
10766 for (i = 0; i < cfg->num_inputs; i++) {
10767 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10768 break;
10769 nid = cfg->inputs[i].pin;
10770 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10771 char label[32];
10772 snprintf(label, sizeof(label), "%s Boost",
10773 hda_get_autocfg_input_label(codec, cfg, i));
10774 err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0,
10775 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10776 if (err < 0)
10777 return err;
10778 }
10779 }
10780 return 0;
10781 }
10782
10783 /* almost identical with ALC880 parser... */
10784 static int alc882_parse_auto_config(struct hda_codec *codec)
10785 {
10786 struct alc_spec *spec = codec->spec;
10787 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10788 int err;
10789
10790 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10791 alc882_ignore);
10792 if (err < 0)
10793 return err;
10794 if (!spec->autocfg.line_outs)
10795 return 0; /* can't find valid BIOS pin config */
10796
10797 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10798 if (err < 0)
10799 return err;
10800 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10801 if (err < 0)
10802 return err;
10803 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10804 "Headphone");
10805 if (err < 0)
10806 return err;
10807 err = alc880_auto_create_extra_out(spec,
10808 spec->autocfg.speaker_pins[0],
10809 "Speaker");
10810 if (err < 0)
10811 return err;
10812 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10813 if (err < 0)
10814 return err;
10815
10816 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10817
10818 alc_auto_parse_digital(codec);
10819
10820 if (spec->kctls.list)
10821 add_mixer(spec, spec->kctls.list);
10822
10823 add_verb(spec, alc883_auto_init_verbs);
10824 /* if ADC 0x07 is available, initialize it, too */
10825 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10826 add_verb(spec, alc882_adc1_init_verbs);
10827
10828 spec->num_mux_defs = 1;
10829 spec->input_mux = &spec->private_imux[0];
10830
10831 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10832
10833 err = alc_auto_add_mic_boost(codec);
10834 if (err < 0)
10835 return err;
10836
10837 return 1; /* config found */
10838 }
10839
10840 /* additional initialization for auto-configuration model */
10841 static void alc882_auto_init(struct hda_codec *codec)
10842 {
10843 struct alc_spec *spec = codec->spec;
10844 alc882_auto_init_multi_out(codec);
10845 alc882_auto_init_hp_out(codec);
10846 alc882_auto_init_analog_input(codec);
10847 alc882_auto_init_input_src(codec);
10848 alc_auto_init_digital(codec);
10849 if (spec->unsol_event)
10850 alc_inithook(codec);
10851 }
10852
10853 static int patch_alc882(struct hda_codec *codec)
10854 {
10855 struct alc_spec *spec;
10856 int err, board_config;
10857
10858 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10859 if (spec == NULL)
10860 return -ENOMEM;
10861
10862 codec->spec = spec;
10863
10864 alc_auto_parse_customize_define(codec);
10865
10866 switch (codec->vendor_id) {
10867 case 0x10ec0882:
10868 case 0x10ec0885:
10869 break;
10870 default:
10871 /* ALC883 and variants */
10872 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10873 break;
10874 }
10875
10876 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10877 alc882_models,
10878 alc882_cfg_tbl);
10879
10880 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10881 board_config = snd_hda_check_board_codec_sid_config(codec,
10882 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10883
10884 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
10885 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10886 codec->chip_name);
10887 board_config = ALC882_AUTO;
10888 }
10889
10890 if (board_config == ALC882_AUTO)
10891 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
10892
10893 if (board_config == ALC882_AUTO) {
10894 /* automatic parse from the BIOS config */
10895 err = alc882_parse_auto_config(codec);
10896 if (err < 0) {
10897 alc_free(codec);
10898 return err;
10899 } else if (!err) {
10900 printk(KERN_INFO
10901 "hda_codec: Cannot set up configuration "
10902 "from BIOS. Using base mode...\n");
10903 board_config = ALC882_3ST_DIG;
10904 }
10905 }
10906
10907 if (has_cdefine_beep(codec)) {
10908 err = snd_hda_attach_beep_device(codec, 0x1);
10909 if (err < 0) {
10910 alc_free(codec);
10911 return err;
10912 }
10913 }
10914
10915 if (board_config != ALC882_AUTO)
10916 setup_preset(codec, &alc882_presets[board_config]);
10917
10918 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10919 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10920 /* FIXME: setup DAC5 */
10921 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10922 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10923
10924 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10925 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10926
10927 if (!spec->adc_nids && spec->input_mux) {
10928 int i, j;
10929 spec->num_adc_nids = 0;
10930 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
10931 const struct hda_input_mux *imux = spec->input_mux;
10932 hda_nid_t cap;
10933 hda_nid_t items[16];
10934 hda_nid_t nid = alc882_adc_nids[i];
10935 unsigned int wcap = get_wcaps(codec, nid);
10936 /* get type */
10937 wcap = get_wcaps_type(wcap);
10938 if (wcap != AC_WID_AUD_IN)
10939 continue;
10940 spec->private_adc_nids[spec->num_adc_nids] = nid;
10941 err = snd_hda_get_connections(codec, nid, &cap, 1);
10942 if (err < 0)
10943 continue;
10944 err = snd_hda_get_connections(codec, cap, items,
10945 ARRAY_SIZE(items));
10946 if (err < 0)
10947 continue;
10948 for (j = 0; j < imux->num_items; j++)
10949 if (imux->items[j].index >= err)
10950 break;
10951 if (j < imux->num_items)
10952 continue;
10953 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10954 spec->num_adc_nids++;
10955 }
10956 spec->adc_nids = spec->private_adc_nids;
10957 spec->capsrc_nids = spec->private_capsrc_nids;
10958 }
10959
10960 set_capture_mixer(codec);
10961
10962 if (has_cdefine_beep(codec))
10963 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10964
10965 if (board_config == ALC882_AUTO)
10966 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10967
10968 spec->vmaster_nid = 0x0c;
10969
10970 codec->patch_ops = alc_patch_ops;
10971 if (board_config == ALC882_AUTO)
10972 spec->init_hook = alc882_auto_init;
10973 #ifdef CONFIG_SND_HDA_POWER_SAVE
10974 if (!spec->loopback.amplist)
10975 spec->loopback.amplist = alc882_loopbacks;
10976 #endif
10977
10978 return 0;
10979 }
10980
10981
10982 /*
10983 * ALC262 support
10984 */
10985
10986 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10987 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
10988
10989 #define alc262_dac_nids alc260_dac_nids
10990 #define alc262_adc_nids alc882_adc_nids
10991 #define alc262_adc_nids_alt alc882_adc_nids_alt
10992 #define alc262_capsrc_nids alc882_capsrc_nids
10993 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
10994
10995 #define alc262_modes alc260_modes
10996 #define alc262_capture_source alc882_capture_source
10997
10998 static hda_nid_t alc262_dmic_adc_nids[1] = {
10999 /* ADC0 */
11000 0x09
11001 };
11002
11003 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11004
11005 static struct snd_kcontrol_new alc262_base_mixer[] = {
11006 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11007 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11013 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11014 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11015 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11016 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11017 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11018 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11019 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11020 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11021 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11022 { } /* end */
11023 };
11024
11025 /* update HP, line and mono-out pins according to the master switch */
11026 static void alc262_hp_master_update(struct hda_codec *codec)
11027 {
11028 struct alc_spec *spec = codec->spec;
11029 int val = spec->master_sw;
11030
11031 /* HP & line-out */
11032 snd_hda_codec_write_cache(codec, 0x1b, 0,
11033 AC_VERB_SET_PIN_WIDGET_CONTROL,
11034 val ? PIN_HP : 0);
11035 snd_hda_codec_write_cache(codec, 0x15, 0,
11036 AC_VERB_SET_PIN_WIDGET_CONTROL,
11037 val ? PIN_HP : 0);
11038 /* mono (speaker) depending on the HP jack sense */
11039 val = val && !spec->jack_present;
11040 snd_hda_codec_write_cache(codec, 0x16, 0,
11041 AC_VERB_SET_PIN_WIDGET_CONTROL,
11042 val ? PIN_OUT : 0);
11043 }
11044
11045 static void alc262_hp_bpc_automute(struct hda_codec *codec)
11046 {
11047 struct alc_spec *spec = codec->spec;
11048
11049 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11050 alc262_hp_master_update(codec);
11051 }
11052
11053 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11054 {
11055 if ((res >> 26) != ALC880_HP_EVENT)
11056 return;
11057 alc262_hp_bpc_automute(codec);
11058 }
11059
11060 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11061 {
11062 struct alc_spec *spec = codec->spec;
11063
11064 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11065 alc262_hp_master_update(codec);
11066 }
11067
11068 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11069 unsigned int res)
11070 {
11071 if ((res >> 26) != ALC880_HP_EVENT)
11072 return;
11073 alc262_hp_wildwest_automute(codec);
11074 }
11075
11076 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11077
11078 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11079 struct snd_ctl_elem_value *ucontrol)
11080 {
11081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11082 struct alc_spec *spec = codec->spec;
11083 int val = !!*ucontrol->value.integer.value;
11084
11085 if (val == spec->master_sw)
11086 return 0;
11087 spec->master_sw = val;
11088 alc262_hp_master_update(codec);
11089 return 1;
11090 }
11091
11092 #define ALC262_HP_MASTER_SWITCH \
11093 { \
11094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11095 .name = "Master Playback Switch", \
11096 .info = snd_ctl_boolean_mono_info, \
11097 .get = alc262_hp_master_sw_get, \
11098 .put = alc262_hp_master_sw_put, \
11099 }, \
11100 { \
11101 .iface = NID_MAPPING, \
11102 .name = "Master Playback Switch", \
11103 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11104 }
11105
11106
11107 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11108 ALC262_HP_MASTER_SWITCH,
11109 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11110 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11112 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11113 HDA_OUTPUT),
11114 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11115 HDA_OUTPUT),
11116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11117 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11118 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11119 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11120 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11121 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11122 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11123 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11124 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11125 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11126 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11127 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11128 { } /* end */
11129 };
11130
11131 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11132 ALC262_HP_MASTER_SWITCH,
11133 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11134 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11135 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11137 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11138 HDA_OUTPUT),
11139 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11140 HDA_OUTPUT),
11141 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11142 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11143 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
11144 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11145 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11146 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11147 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11148 { } /* end */
11149 };
11150
11151 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11152 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11153 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11154 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
11155 { } /* end */
11156 };
11157
11158 /* mute/unmute internal speaker according to the hp jack and mute state */
11159 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11160 {
11161 struct alc_spec *spec = codec->spec;
11162
11163 spec->autocfg.hp_pins[0] = 0x15;
11164 spec->autocfg.speaker_pins[0] = 0x14;
11165 }
11166
11167 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11169 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11170 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11173 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11174 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11175 { } /* end */
11176 };
11177
11178 static struct hda_verb alc262_hp_t5735_verbs[] = {
11179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11181
11182 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11183 { }
11184 };
11185
11186 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11187 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11188 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11189 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11190 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11191 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11192 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11193 { } /* end */
11194 };
11195
11196 static struct hda_verb alc262_hp_rp5700_verbs[] = {
11197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11198 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11199 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11200 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11201 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11202 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11203 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11205 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11207 {}
11208 };
11209
11210 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11211 .num_items = 1,
11212 .items = {
11213 { "Line", 0x1 },
11214 },
11215 };
11216
11217 /* bind hp and internal speaker mute (with plug check) as master switch */
11218 static void alc262_hippo_master_update(struct hda_codec *codec)
11219 {
11220 struct alc_spec *spec = codec->spec;
11221 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11222 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11223 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11224 unsigned int mute;
11225
11226 /* HP */
11227 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11228 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11229 HDA_AMP_MUTE, mute);
11230 /* mute internal speaker per jack sense */
11231 if (spec->jack_present)
11232 mute = HDA_AMP_MUTE;
11233 if (line_nid)
11234 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11235 HDA_AMP_MUTE, mute);
11236 if (speaker_nid && speaker_nid != line_nid)
11237 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
11238 HDA_AMP_MUTE, mute);
11239 }
11240
11241 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11242
11243 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11244 struct snd_ctl_elem_value *ucontrol)
11245 {
11246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11247 struct alc_spec *spec = codec->spec;
11248 int val = !!*ucontrol->value.integer.value;
11249
11250 if (val == spec->master_sw)
11251 return 0;
11252 spec->master_sw = val;
11253 alc262_hippo_master_update(codec);
11254 return 1;
11255 }
11256
11257 #define ALC262_HIPPO_MASTER_SWITCH \
11258 { \
11259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11260 .name = "Master Playback Switch", \
11261 .info = snd_ctl_boolean_mono_info, \
11262 .get = alc262_hippo_master_sw_get, \
11263 .put = alc262_hippo_master_sw_put, \
11264 }, \
11265 { \
11266 .iface = NID_MAPPING, \
11267 .name = "Master Playback Switch", \
11268 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11269 (SUBDEV_SPEAKER(0) << 16), \
11270 }
11271
11272 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11273 ALC262_HIPPO_MASTER_SWITCH,
11274 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11275 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11276 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11277 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11278 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11279 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11280 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11281 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11282 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11283 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11284 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11285 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11286 { } /* end */
11287 };
11288
11289 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11290 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11291 ALC262_HIPPO_MASTER_SWITCH,
11292 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11293 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11295 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11299 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11300 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11301 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11302 { } /* end */
11303 };
11304
11305 /* mute/unmute internal speaker according to the hp jack and mute state */
11306 static void alc262_hippo_automute(struct hda_codec *codec)
11307 {
11308 struct alc_spec *spec = codec->spec;
11309 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11310
11311 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
11312 alc262_hippo_master_update(codec);
11313 }
11314
11315 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11316 {
11317 if ((res >> 26) != ALC880_HP_EVENT)
11318 return;
11319 alc262_hippo_automute(codec);
11320 }
11321
11322 static void alc262_hippo_setup(struct hda_codec *codec)
11323 {
11324 struct alc_spec *spec = codec->spec;
11325
11326 spec->autocfg.hp_pins[0] = 0x15;
11327 spec->autocfg.speaker_pins[0] = 0x14;
11328 }
11329
11330 static void alc262_hippo1_setup(struct hda_codec *codec)
11331 {
11332 struct alc_spec *spec = codec->spec;
11333
11334 spec->autocfg.hp_pins[0] = 0x1b;
11335 spec->autocfg.speaker_pins[0] = 0x14;
11336 }
11337
11338
11339 static struct snd_kcontrol_new alc262_sony_mixer[] = {
11340 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11341 ALC262_HIPPO_MASTER_SWITCH,
11342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11344 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11345 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11346 { } /* end */
11347 };
11348
11349 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11350 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11351 ALC262_HIPPO_MASTER_SWITCH,
11352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11355 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11356 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11357 { } /* end */
11358 };
11359
11360 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11361 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11362 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11363 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11364 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11365 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11366 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11369 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11370 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11371 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11373 { } /* end */
11374 };
11375
11376 static struct hda_verb alc262_tyan_verbs[] = {
11377 /* Headphone automute */
11378 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11379 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11380 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11381
11382 /* P11 AUX_IN, white 4-pin connector */
11383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11384 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11385 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11386 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11387
11388 {}
11389 };
11390
11391 /* unsolicited event for HP jack sensing */
11392 static void alc262_tyan_setup(struct hda_codec *codec)
11393 {
11394 struct alc_spec *spec = codec->spec;
11395
11396 spec->autocfg.hp_pins[0] = 0x1b;
11397 spec->autocfg.speaker_pins[0] = 0x15;
11398 }
11399
11400
11401 #define alc262_capture_mixer alc882_capture_mixer
11402 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11403
11404 /*
11405 * generic initialization of ADC, input mixers and output mixers
11406 */
11407 static struct hda_verb alc262_init_verbs[] = {
11408 /*
11409 * Unmute ADC0-2 and set the default input to mic-in
11410 */
11411 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11413 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11415 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11417
11418 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11419 * mixer widget
11420 * Note: PASD motherboards uses the Line In 2 as the input for
11421 * front panel mic (mic 2)
11422 */
11423 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11425 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11426 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11429
11430 /*
11431 * Set up output mixers (0x0c - 0x0e)
11432 */
11433 /* set vol=0 to output mixers */
11434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11435 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11436 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11437 /* set up input amps for analog loopback */
11438 /* Amp Indices: DAC = 0, mixer = 1 */
11439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11445
11446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11447 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11448 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11449 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11450 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11451 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11452
11453 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11455 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11458
11459 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11460 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11461
11462 /* FIXME: use matrix-type input source selection */
11463 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11464 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11465 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11466 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11467 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11469 /* Input mixer2 */
11470 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11472 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11474 /* Input mixer3 */
11475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11477 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11479
11480 { }
11481 };
11482
11483 static struct hda_verb alc262_eapd_verbs[] = {
11484 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11485 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11486 { }
11487 };
11488
11489 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11490 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11491 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11492 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11493
11494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11496 {}
11497 };
11498
11499 static struct hda_verb alc262_sony_unsol_verbs[] = {
11500 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11501 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11502 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11503
11504 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11505 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11506 {}
11507 };
11508
11509 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11510 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11511 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11515 { } /* end */
11516 };
11517
11518 static struct hda_verb alc262_toshiba_s06_verbs[] = {
11519 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11522 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11523 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11525 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11526 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11527 {}
11528 };
11529
11530 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11531 {
11532 struct alc_spec *spec = codec->spec;
11533
11534 spec->autocfg.hp_pins[0] = 0x15;
11535 spec->autocfg.speaker_pins[0] = 0x14;
11536 spec->ext_mic.pin = 0x18;
11537 spec->ext_mic.mux_idx = 0;
11538 spec->int_mic.pin = 0x12;
11539 spec->int_mic.mux_idx = 9;
11540 spec->auto_mic = 1;
11541 }
11542
11543 /*
11544 * nec model
11545 * 0x15 = headphone
11546 * 0x16 = internal speaker
11547 * 0x18 = external mic
11548 */
11549
11550 static struct snd_kcontrol_new alc262_nec_mixer[] = {
11551 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11552 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11553
11554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11556 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11557
11558 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11559 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11560 { } /* end */
11561 };
11562
11563 static struct hda_verb alc262_nec_verbs[] = {
11564 /* Unmute Speaker */
11565 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11566
11567 /* Headphone */
11568 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11570
11571 /* External mic to headphone */
11572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11573 /* External mic to speaker */
11574 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11575 {}
11576 };
11577
11578 /*
11579 * fujitsu model
11580 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11581 * 0x1b = port replicator headphone out
11582 */
11583
11584 #define ALC_HP_EVENT 0x37
11585
11586 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11587 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11591 {}
11592 };
11593
11594 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11595 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11596 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11597 {}
11598 };
11599
11600 static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11601 /* Front Mic pin: input vref at 50% */
11602 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11603 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11604 {}
11605 };
11606
11607 static struct hda_input_mux alc262_fujitsu_capture_source = {
11608 .num_items = 3,
11609 .items = {
11610 { "Mic", 0x0 },
11611 { "Int Mic", 0x1 },
11612 { "CD", 0x4 },
11613 },
11614 };
11615
11616 static struct hda_input_mux alc262_HP_capture_source = {
11617 .num_items = 5,
11618 .items = {
11619 { "Mic", 0x0 },
11620 { "Front Mic", 0x1 },
11621 { "Line", 0x2 },
11622 { "CD", 0x4 },
11623 { "AUX IN", 0x6 },
11624 },
11625 };
11626
11627 static struct hda_input_mux alc262_HP_D7000_capture_source = {
11628 .num_items = 4,
11629 .items = {
11630 { "Mic", 0x0 },
11631 { "Front Mic", 0x2 },
11632 { "Line", 0x1 },
11633 { "CD", 0x4 },
11634 },
11635 };
11636
11637 /* mute/unmute internal speaker according to the hp jacks and mute state */
11638 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11639 {
11640 struct alc_spec *spec = codec->spec;
11641 unsigned int mute;
11642
11643 if (force || !spec->sense_updated) {
11644 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11645 snd_hda_jack_detect(codec, 0x1b);
11646 spec->sense_updated = 1;
11647 }
11648 /* unmute internal speaker only if both HPs are unplugged and
11649 * master switch is on
11650 */
11651 if (spec->jack_present)
11652 mute = HDA_AMP_MUTE;
11653 else
11654 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11655 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11656 HDA_AMP_MUTE, mute);
11657 }
11658
11659 /* unsolicited event for HP jack sensing */
11660 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11661 unsigned int res)
11662 {
11663 if ((res >> 26) != ALC_HP_EVENT)
11664 return;
11665 alc262_fujitsu_automute(codec, 1);
11666 }
11667
11668 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11669 {
11670 alc262_fujitsu_automute(codec, 1);
11671 }
11672
11673 /* bind volumes of both NID 0x0c and 0x0d */
11674 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11675 .ops = &snd_hda_bind_vol,
11676 .values = {
11677 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11678 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11679 0
11680 },
11681 };
11682
11683 /* mute/unmute internal speaker according to the hp jack and mute state */
11684 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11685 {
11686 struct alc_spec *spec = codec->spec;
11687 unsigned int mute;
11688
11689 if (force || !spec->sense_updated) {
11690 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11691 spec->sense_updated = 1;
11692 }
11693 if (spec->jack_present) {
11694 /* mute internal speaker */
11695 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11696 HDA_AMP_MUTE, HDA_AMP_MUTE);
11697 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11698 HDA_AMP_MUTE, HDA_AMP_MUTE);
11699 } else {
11700 /* unmute internal speaker if necessary */
11701 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11702 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11703 HDA_AMP_MUTE, mute);
11704 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11705 HDA_AMP_MUTE, mute);
11706 }
11707 }
11708
11709 /* unsolicited event for HP jack sensing */
11710 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11711 unsigned int res)
11712 {
11713 if ((res >> 26) != ALC_HP_EVENT)
11714 return;
11715 alc262_lenovo_3000_automute(codec, 1);
11716 }
11717
11718 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11719 int dir, int idx, long *valp)
11720 {
11721 int i, change = 0;
11722
11723 for (i = 0; i < 2; i++, valp++)
11724 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11725 HDA_AMP_MUTE,
11726 *valp ? 0 : HDA_AMP_MUTE);
11727 return change;
11728 }
11729
11730 /* bind hp and internal speaker mute (with plug check) */
11731 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11732 struct snd_ctl_elem_value *ucontrol)
11733 {
11734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11735 long *valp = ucontrol->value.integer.value;
11736 int change;
11737
11738 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11739 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11740 if (change)
11741 alc262_fujitsu_automute(codec, 0);
11742 return change;
11743 }
11744
11745 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11746 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11747 {
11748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11749 .name = "Master Playback Switch",
11750 .subdevice = HDA_SUBDEV_AMP_FLAG,
11751 .info = snd_hda_mixer_amp_switch_info,
11752 .get = snd_hda_mixer_amp_switch_get,
11753 .put = alc262_fujitsu_master_sw_put,
11754 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11755 },
11756 {
11757 .iface = NID_MAPPING,
11758 .name = "Master Playback Switch",
11759 .private_value = 0x1b,
11760 },
11761 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11762 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11763 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11766 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11767 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11768 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11769 { } /* end */
11770 };
11771
11772 /* bind hp and internal speaker mute (with plug check) */
11773 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11774 struct snd_ctl_elem_value *ucontrol)
11775 {
11776 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11777 long *valp = ucontrol->value.integer.value;
11778 int change;
11779
11780 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11781 if (change)
11782 alc262_lenovo_3000_automute(codec, 0);
11783 return change;
11784 }
11785
11786 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11787 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11788 {
11789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11790 .name = "Master Playback Switch",
11791 .subdevice = HDA_SUBDEV_AMP_FLAG,
11792 .info = snd_hda_mixer_amp_switch_info,
11793 .get = snd_hda_mixer_amp_switch_get,
11794 .put = alc262_lenovo_3000_master_sw_put,
11795 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11796 },
11797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11799 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11801 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11802 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11803 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11804 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11805 { } /* end */
11806 };
11807
11808 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11809 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11810 ALC262_HIPPO_MASTER_SWITCH,
11811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11813 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11814 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11815 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11816 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11817 { } /* end */
11818 };
11819
11820 /* additional init verbs for Benq laptops */
11821 static struct hda_verb alc262_EAPD_verbs[] = {
11822 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11823 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11824 {}
11825 };
11826
11827 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11830
11831 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11832 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11833 {}
11834 };
11835
11836 /* Samsung Q1 Ultra Vista model setup */
11837 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11838 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11839 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11842 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
11843 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
11844 { } /* end */
11845 };
11846
11847 static struct hda_verb alc262_ultra_verbs[] = {
11848 /* output mixer */
11849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11852 /* speaker */
11853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11854 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11855 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11856 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11857 /* HP */
11858 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11859 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11861 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11863 /* internal mic */
11864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11865 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11866 /* ADC, choose mic */
11867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11868 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11869 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11870 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11871 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11872 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11873 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11874 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11875 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11876 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11877 {}
11878 };
11879
11880 /* mute/unmute internal speaker according to the hp jack and mute state */
11881 static void alc262_ultra_automute(struct hda_codec *codec)
11882 {
11883 struct alc_spec *spec = codec->spec;
11884 unsigned int mute;
11885
11886 mute = 0;
11887 /* auto-mute only when HP is used as HP */
11888 if (!spec->cur_mux[0]) {
11889 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11890 if (spec->jack_present)
11891 mute = HDA_AMP_MUTE;
11892 }
11893 /* mute/unmute internal speaker */
11894 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11895 HDA_AMP_MUTE, mute);
11896 /* mute/unmute HP */
11897 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11898 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11899 }
11900
11901 /* unsolicited event for HP jack sensing */
11902 static void alc262_ultra_unsol_event(struct hda_codec *codec,
11903 unsigned int res)
11904 {
11905 if ((res >> 26) != ALC880_HP_EVENT)
11906 return;
11907 alc262_ultra_automute(codec);
11908 }
11909
11910 static struct hda_input_mux alc262_ultra_capture_source = {
11911 .num_items = 2,
11912 .items = {
11913 { "Mic", 0x1 },
11914 { "Headphone", 0x7 },
11915 },
11916 };
11917
11918 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11919 struct snd_ctl_elem_value *ucontrol)
11920 {
11921 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11922 struct alc_spec *spec = codec->spec;
11923 int ret;
11924
11925 ret = alc_mux_enum_put(kcontrol, ucontrol);
11926 if (!ret)
11927 return 0;
11928 /* reprogram the HP pin as mic or HP according to the input source */
11929 snd_hda_codec_write_cache(codec, 0x15, 0,
11930 AC_VERB_SET_PIN_WIDGET_CONTROL,
11931 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11932 alc262_ultra_automute(codec); /* mute/unmute HP */
11933 return ret;
11934 }
11935
11936 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11937 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11938 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11939 {
11940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11941 .name = "Capture Source",
11942 .info = alc_mux_enum_info,
11943 .get = alc_mux_enum_get,
11944 .put = alc262_ultra_mux_enum_put,
11945 },
11946 {
11947 .iface = NID_MAPPING,
11948 .name = "Capture Source",
11949 .private_value = 0x15,
11950 },
11951 { } /* end */
11952 };
11953
11954 /* We use two mixers depending on the output pin; 0x16 is a mono output
11955 * and thus it's bound with a different mixer.
11956 * This function returns which mixer amp should be used.
11957 */
11958 static int alc262_check_volbit(hda_nid_t nid)
11959 {
11960 if (!nid)
11961 return 0;
11962 else if (nid == 0x16)
11963 return 2;
11964 else
11965 return 1;
11966 }
11967
11968 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11969 const char *pfx, int *vbits, int idx)
11970 {
11971 unsigned long val;
11972 int vbit;
11973
11974 vbit = alc262_check_volbit(nid);
11975 if (!vbit)
11976 return 0;
11977 if (*vbits & vbit) /* a volume control for this mixer already there */
11978 return 0;
11979 *vbits |= vbit;
11980 if (vbit == 2)
11981 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11982 else
11983 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11984 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
11985 }
11986
11987 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11988 const char *pfx, int idx)
11989 {
11990 unsigned long val;
11991
11992 if (!nid)
11993 return 0;
11994 if (nid == 0x16)
11995 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11996 else
11997 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11998 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
11999 }
12000
12001 /* add playback controls from the parsed DAC table */
12002 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12003 const struct auto_pin_cfg *cfg)
12004 {
12005 const char *pfx;
12006 int vbits;
12007 int i, err;
12008
12009 spec->multiout.num_dacs = 1; /* only use one dac */
12010 spec->multiout.dac_nids = spec->private_dac_nids;
12011 spec->multiout.dac_nids[0] = 2;
12012
12013 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
12014 pfx = "Master";
12015 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12016 pfx = "Speaker";
12017 else if (cfg->line_out_type == AUTO_PIN_HP_OUT)
12018 pfx = "Headphone";
12019 else
12020 pfx = "Front";
12021 for (i = 0; i < 2; i++) {
12022 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12023 if (err < 0)
12024 return err;
12025 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12026 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12027 "Speaker", i);
12028 if (err < 0)
12029 return err;
12030 }
12031 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12032 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12033 "Headphone", i);
12034 if (err < 0)
12035 return err;
12036 }
12037 }
12038
12039 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12040 alc262_check_volbit(cfg->speaker_pins[0]) |
12041 alc262_check_volbit(cfg->hp_pins[0]);
12042 if (vbits == 1 || vbits == 2)
12043 pfx = "Master"; /* only one mixer is used */
12044 vbits = 0;
12045 for (i = 0; i < 2; i++) {
12046 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12047 &vbits, i);
12048 if (err < 0)
12049 return err;
12050 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12051 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12052 "Speaker", &vbits, i);
12053 if (err < 0)
12054 return err;
12055 }
12056 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12057 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12058 "Headphone", &vbits, i);
12059 if (err < 0)
12060 return err;
12061 }
12062 }
12063 return 0;
12064 }
12065
12066 #define alc262_auto_create_input_ctls \
12067 alc882_auto_create_input_ctls
12068
12069 /*
12070 * generic initialization of ADC, input mixers and output mixers
12071 */
12072 static struct hda_verb alc262_volume_init_verbs[] = {
12073 /*
12074 * Unmute ADC0-2 and set the default input to mic-in
12075 */
12076 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12077 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12079 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12080 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12081 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12082
12083 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12084 * mixer widget
12085 * Note: PASD motherboards uses the Line In 2 as the input for
12086 * front panel mic (mic 2)
12087 */
12088 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12094
12095 /*
12096 * Set up output mixers (0x0c - 0x0f)
12097 */
12098 /* set vol=0 to output mixers */
12099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12102
12103 /* set up input amps for analog loopback */
12104 /* Amp Indices: DAC = 0, mixer = 1 */
12105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12111
12112 /* FIXME: use matrix-type input source selection */
12113 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12114 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12117 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12118 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12119 /* Input mixer2 */
12120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12123 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12124 /* Input mixer3 */
12125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12129
12130 { }
12131 };
12132
12133 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12134 /*
12135 * Unmute ADC0-2 and set the default input to mic-in
12136 */
12137 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12139 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12140 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12141 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12142 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12143
12144 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12145 * mixer widget
12146 * Note: PASD motherboards uses the Line In 2 as the input for
12147 * front panel mic (mic 2)
12148 */
12149 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12153 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12154 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12155 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12157
12158 /*
12159 * Set up output mixers (0x0c - 0x0e)
12160 */
12161 /* set vol=0 to output mixers */
12162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12163 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12164 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12165
12166 /* set up input amps for analog loopback */
12167 /* Amp Indices: DAC = 0, mixer = 1 */
12168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12170 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12171 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12172 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12173 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12174
12175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12177 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12178
12179 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12180 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12181
12182 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12183 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12184
12185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12186 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12187 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12188 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12189 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12190
12191 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12192 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12193 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12194 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12195 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12196 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12197
12198
12199 /* FIXME: use matrix-type input source selection */
12200 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12201 /* Input mixer1: only unmute Mic */
12202 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12203 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12211 /* Input mixer2 */
12212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12217 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12218 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12221 /* Input mixer3 */
12222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12223 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12225 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12229 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12230 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12231
12232 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12233
12234 { }
12235 };
12236
12237 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12238 /*
12239 * Unmute ADC0-2 and set the default input to mic-in
12240 */
12241 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12243 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12244 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12245 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12246 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12247
12248 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12249 * mixer widget
12250 * Note: PASD motherboards uses the Line In 2 as the input for front
12251 * panel mic (mic 2)
12252 */
12253 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12255 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12256 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12257 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12258 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12259 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12260 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12261 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12262 /*
12263 * Set up output mixers (0x0c - 0x0e)
12264 */
12265 /* set vol=0 to output mixers */
12266 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12268 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12269
12270 /* set up input amps for analog loopback */
12271 /* Amp Indices: DAC = 0, mixer = 1 */
12272 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12274 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12275 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12276 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12278
12279
12280 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12281 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12282 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12283 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12284 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12286 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12287
12288 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12290
12291 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12292 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12293
12294 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12295 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12296 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12297 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12298 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12299 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12300
12301 /* FIXME: use matrix-type input source selection */
12302 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12303 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12305 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12308 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12309 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12310 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12311 /* Input mixer2 */
12312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12313 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12314 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12316 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12317 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12319 /* Input mixer3 */
12320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12321 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12325 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12327
12328 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12329
12330 { }
12331 };
12332
12333 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12334
12335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12337 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12338
12339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12341 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12343
12344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12347 {}
12348 };
12349
12350 /*
12351 * Pin config fixes
12352 */
12353 enum {
12354 PINFIX_FSC_H270,
12355 };
12356
12357 static const struct alc_fixup alc262_fixups[] = {
12358 [PINFIX_FSC_H270] = {
12359 .pins = (const struct alc_pincfg[]) {
12360 { 0x14, 0x99130110 }, /* speaker */
12361 { 0x15, 0x0221142f }, /* front HP */
12362 { 0x1b, 0x0121141f }, /* rear HP */
12363 { }
12364 }
12365 },
12366 [PINFIX_PB_M5210] = {
12367 .verbs = (const struct hda_verb[]) {
12368 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
12369 {}
12370 }
12371 },
12372 };
12373
12374 static struct snd_pci_quirk alc262_fixup_tbl[] = {
12375 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12376 {}
12377 };
12378
12379
12380 #ifdef CONFIG_SND_HDA_POWER_SAVE
12381 #define alc262_loopbacks alc880_loopbacks
12382 #endif
12383
12384 /* pcm configuration: identical with ALC880 */
12385 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12386 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12387 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12388 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12389
12390 /*
12391 * BIOS auto configuration
12392 */
12393 static int alc262_parse_auto_config(struct hda_codec *codec)
12394 {
12395 struct alc_spec *spec = codec->spec;
12396 int err;
12397 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12398
12399 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12400 alc262_ignore);
12401 if (err < 0)
12402 return err;
12403 if (!spec->autocfg.line_outs) {
12404 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12405 spec->multiout.max_channels = 2;
12406 spec->no_analog = 1;
12407 goto dig_only;
12408 }
12409 return 0; /* can't find valid BIOS pin config */
12410 }
12411 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12412 if (err < 0)
12413 return err;
12414 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12415 if (err < 0)
12416 return err;
12417
12418 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12419
12420 dig_only:
12421 alc_auto_parse_digital(codec);
12422
12423 if (spec->kctls.list)
12424 add_mixer(spec, spec->kctls.list);
12425
12426 add_verb(spec, alc262_volume_init_verbs);
12427 spec->num_mux_defs = 1;
12428 spec->input_mux = &spec->private_imux[0];
12429
12430 err = alc_auto_add_mic_boost(codec);
12431 if (err < 0)
12432 return err;
12433
12434 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12435
12436 return 1;
12437 }
12438
12439 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12440 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12441 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12442 #define alc262_auto_init_input_src alc882_auto_init_input_src
12443
12444
12445 /* init callback for auto-configuration model -- overriding the default init */
12446 static void alc262_auto_init(struct hda_codec *codec)
12447 {
12448 struct alc_spec *spec = codec->spec;
12449 alc262_auto_init_multi_out(codec);
12450 alc262_auto_init_hp_out(codec);
12451 alc262_auto_init_analog_input(codec);
12452 alc262_auto_init_input_src(codec);
12453 alc_auto_init_digital(codec);
12454 if (spec->unsol_event)
12455 alc_inithook(codec);
12456 }
12457
12458 /*
12459 * configuration and preset
12460 */
12461 static const char *alc262_models[ALC262_MODEL_LAST] = {
12462 [ALC262_BASIC] = "basic",
12463 [ALC262_HIPPO] = "hippo",
12464 [ALC262_HIPPO_1] = "hippo_1",
12465 [ALC262_FUJITSU] = "fujitsu",
12466 [ALC262_HP_BPC] = "hp-bpc",
12467 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12468 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12469 [ALC262_HP_RP5700] = "hp-rp5700",
12470 [ALC262_BENQ_ED8] = "benq",
12471 [ALC262_BENQ_T31] = "benq-t31",
12472 [ALC262_SONY_ASSAMD] = "sony-assamd",
12473 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12474 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12475 [ALC262_ULTRA] = "ultra",
12476 [ALC262_LENOVO_3000] = "lenovo-3000",
12477 [ALC262_NEC] = "nec",
12478 [ALC262_TYAN] = "tyan",
12479 [ALC262_AUTO] = "auto",
12480 };
12481
12482 static struct snd_pci_quirk alc262_cfg_tbl[] = {
12483 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12484 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12485 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12486 ALC262_HP_BPC),
12487 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12488 ALC262_HP_BPC),
12489 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12490 ALC262_HP_BPC),
12491 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12492 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12493 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12494 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12495 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12496 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12497 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12498 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12499 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12500 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12501 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12502 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12503 ALC262_HP_TC_T5735),
12504 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12505 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12506 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12507 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12508 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12509 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12510 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12511 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12512 #if 0 /* disable the quirk since model=auto works better in recent versions */
12513 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12514 ALC262_SONY_ASSAMD),
12515 #endif
12516 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12517 ALC262_TOSHIBA_RX1),
12518 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12519 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12520 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12521 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12522 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12523 ALC262_ULTRA),
12524 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12525 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12526 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12527 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12528 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12529 {}
12530 };
12531
12532 static struct alc_config_preset alc262_presets[] = {
12533 [ALC262_BASIC] = {
12534 .mixers = { alc262_base_mixer },
12535 .init_verbs = { alc262_init_verbs },
12536 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12537 .dac_nids = alc262_dac_nids,
12538 .hp_nid = 0x03,
12539 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12540 .channel_mode = alc262_modes,
12541 .input_mux = &alc262_capture_source,
12542 },
12543 [ALC262_HIPPO] = {
12544 .mixers = { alc262_hippo_mixer },
12545 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12546 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12547 .dac_nids = alc262_dac_nids,
12548 .hp_nid = 0x03,
12549 .dig_out_nid = ALC262_DIGOUT_NID,
12550 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12551 .channel_mode = alc262_modes,
12552 .input_mux = &alc262_capture_source,
12553 .unsol_event = alc262_hippo_unsol_event,
12554 .setup = alc262_hippo_setup,
12555 .init_hook = alc262_hippo_automute,
12556 },
12557 [ALC262_HIPPO_1] = {
12558 .mixers = { alc262_hippo1_mixer },
12559 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12560 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12561 .dac_nids = alc262_dac_nids,
12562 .hp_nid = 0x02,
12563 .dig_out_nid = ALC262_DIGOUT_NID,
12564 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12565 .channel_mode = alc262_modes,
12566 .input_mux = &alc262_capture_source,
12567 .unsol_event = alc262_hippo_unsol_event,
12568 .setup = alc262_hippo1_setup,
12569 .init_hook = alc262_hippo_automute,
12570 },
12571 [ALC262_FUJITSU] = {
12572 .mixers = { alc262_fujitsu_mixer },
12573 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12574 alc262_fujitsu_unsol_verbs },
12575 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12576 .dac_nids = alc262_dac_nids,
12577 .hp_nid = 0x03,
12578 .dig_out_nid = ALC262_DIGOUT_NID,
12579 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12580 .channel_mode = alc262_modes,
12581 .input_mux = &alc262_fujitsu_capture_source,
12582 .unsol_event = alc262_fujitsu_unsol_event,
12583 .init_hook = alc262_fujitsu_init_hook,
12584 },
12585 [ALC262_HP_BPC] = {
12586 .mixers = { alc262_HP_BPC_mixer },
12587 .init_verbs = { alc262_HP_BPC_init_verbs },
12588 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12589 .dac_nids = alc262_dac_nids,
12590 .hp_nid = 0x03,
12591 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12592 .channel_mode = alc262_modes,
12593 .input_mux = &alc262_HP_capture_source,
12594 .unsol_event = alc262_hp_bpc_unsol_event,
12595 .init_hook = alc262_hp_bpc_automute,
12596 },
12597 [ALC262_HP_BPC_D7000_WF] = {
12598 .mixers = { alc262_HP_BPC_WildWest_mixer },
12599 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12600 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12601 .dac_nids = alc262_dac_nids,
12602 .hp_nid = 0x03,
12603 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12604 .channel_mode = alc262_modes,
12605 .input_mux = &alc262_HP_D7000_capture_source,
12606 .unsol_event = alc262_hp_wildwest_unsol_event,
12607 .init_hook = alc262_hp_wildwest_automute,
12608 },
12609 [ALC262_HP_BPC_D7000_WL] = {
12610 .mixers = { alc262_HP_BPC_WildWest_mixer,
12611 alc262_HP_BPC_WildWest_option_mixer },
12612 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12613 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12614 .dac_nids = alc262_dac_nids,
12615 .hp_nid = 0x03,
12616 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12617 .channel_mode = alc262_modes,
12618 .input_mux = &alc262_HP_D7000_capture_source,
12619 .unsol_event = alc262_hp_wildwest_unsol_event,
12620 .init_hook = alc262_hp_wildwest_automute,
12621 },
12622 [ALC262_HP_TC_T5735] = {
12623 .mixers = { alc262_hp_t5735_mixer },
12624 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12625 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12626 .dac_nids = alc262_dac_nids,
12627 .hp_nid = 0x03,
12628 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12629 .channel_mode = alc262_modes,
12630 .input_mux = &alc262_capture_source,
12631 .unsol_event = alc_sku_unsol_event,
12632 .setup = alc262_hp_t5735_setup,
12633 .init_hook = alc_inithook,
12634 },
12635 [ALC262_HP_RP5700] = {
12636 .mixers = { alc262_hp_rp5700_mixer },
12637 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12638 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12639 .dac_nids = alc262_dac_nids,
12640 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12641 .channel_mode = alc262_modes,
12642 .input_mux = &alc262_hp_rp5700_capture_source,
12643 },
12644 [ALC262_BENQ_ED8] = {
12645 .mixers = { alc262_base_mixer },
12646 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12647 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12648 .dac_nids = alc262_dac_nids,
12649 .hp_nid = 0x03,
12650 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12651 .channel_mode = alc262_modes,
12652 .input_mux = &alc262_capture_source,
12653 },
12654 [ALC262_SONY_ASSAMD] = {
12655 .mixers = { alc262_sony_mixer },
12656 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12657 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12658 .dac_nids = alc262_dac_nids,
12659 .hp_nid = 0x02,
12660 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12661 .channel_mode = alc262_modes,
12662 .input_mux = &alc262_capture_source,
12663 .unsol_event = alc262_hippo_unsol_event,
12664 .setup = alc262_hippo_setup,
12665 .init_hook = alc262_hippo_automute,
12666 },
12667 [ALC262_BENQ_T31] = {
12668 .mixers = { alc262_benq_t31_mixer },
12669 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12670 alc_hp15_unsol_verbs },
12671 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12672 .dac_nids = alc262_dac_nids,
12673 .hp_nid = 0x03,
12674 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12675 .channel_mode = alc262_modes,
12676 .input_mux = &alc262_capture_source,
12677 .unsol_event = alc262_hippo_unsol_event,
12678 .setup = alc262_hippo_setup,
12679 .init_hook = alc262_hippo_automute,
12680 },
12681 [ALC262_ULTRA] = {
12682 .mixers = { alc262_ultra_mixer },
12683 .cap_mixer = alc262_ultra_capture_mixer,
12684 .init_verbs = { alc262_ultra_verbs },
12685 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12686 .dac_nids = alc262_dac_nids,
12687 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12688 .channel_mode = alc262_modes,
12689 .input_mux = &alc262_ultra_capture_source,
12690 .adc_nids = alc262_adc_nids, /* ADC0 */
12691 .capsrc_nids = alc262_capsrc_nids,
12692 .num_adc_nids = 1, /* single ADC */
12693 .unsol_event = alc262_ultra_unsol_event,
12694 .init_hook = alc262_ultra_automute,
12695 },
12696 [ALC262_LENOVO_3000] = {
12697 .mixers = { alc262_lenovo_3000_mixer },
12698 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12699 alc262_lenovo_3000_unsol_verbs,
12700 alc262_lenovo_3000_init_verbs },
12701 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12702 .dac_nids = alc262_dac_nids,
12703 .hp_nid = 0x03,
12704 .dig_out_nid = ALC262_DIGOUT_NID,
12705 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12706 .channel_mode = alc262_modes,
12707 .input_mux = &alc262_fujitsu_capture_source,
12708 .unsol_event = alc262_lenovo_3000_unsol_event,
12709 },
12710 [ALC262_NEC] = {
12711 .mixers = { alc262_nec_mixer },
12712 .init_verbs = { alc262_nec_verbs },
12713 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12714 .dac_nids = alc262_dac_nids,
12715 .hp_nid = 0x03,
12716 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12717 .channel_mode = alc262_modes,
12718 .input_mux = &alc262_capture_source,
12719 },
12720 [ALC262_TOSHIBA_S06] = {
12721 .mixers = { alc262_toshiba_s06_mixer },
12722 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12723 alc262_eapd_verbs },
12724 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12725 .capsrc_nids = alc262_dmic_capsrc_nids,
12726 .dac_nids = alc262_dac_nids,
12727 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12728 .num_adc_nids = 1, /* single ADC */
12729 .dig_out_nid = ALC262_DIGOUT_NID,
12730 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12731 .channel_mode = alc262_modes,
12732 .unsol_event = alc_sku_unsol_event,
12733 .setup = alc262_toshiba_s06_setup,
12734 .init_hook = alc_inithook,
12735 },
12736 [ALC262_TOSHIBA_RX1] = {
12737 .mixers = { alc262_toshiba_rx1_mixer },
12738 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12739 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12740 .dac_nids = alc262_dac_nids,
12741 .hp_nid = 0x03,
12742 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12743 .channel_mode = alc262_modes,
12744 .input_mux = &alc262_capture_source,
12745 .unsol_event = alc262_hippo_unsol_event,
12746 .setup = alc262_hippo_setup,
12747 .init_hook = alc262_hippo_automute,
12748 },
12749 [ALC262_TYAN] = {
12750 .mixers = { alc262_tyan_mixer },
12751 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12752 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12753 .dac_nids = alc262_dac_nids,
12754 .hp_nid = 0x02,
12755 .dig_out_nid = ALC262_DIGOUT_NID,
12756 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12757 .channel_mode = alc262_modes,
12758 .input_mux = &alc262_capture_source,
12759 .unsol_event = alc_automute_amp_unsol_event,
12760 .setup = alc262_tyan_setup,
12761 .init_hook = alc_automute_amp,
12762 },
12763 };
12764
12765 static int patch_alc262(struct hda_codec *codec)
12766 {
12767 struct alc_spec *spec;
12768 int board_config;
12769 int err;
12770
12771 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12772 if (spec == NULL)
12773 return -ENOMEM;
12774
12775 codec->spec = spec;
12776 #if 0
12777 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12778 * under-run
12779 */
12780 {
12781 int tmp;
12782 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12783 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12784 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12785 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12786 }
12787 #endif
12788 alc_auto_parse_customize_define(codec);
12789
12790 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12791
12792 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12793 alc262_models,
12794 alc262_cfg_tbl);
12795
12796 if (board_config < 0) {
12797 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12798 codec->chip_name);
12799 board_config = ALC262_AUTO;
12800 }
12801
12802 if (board_config == ALC262_AUTO)
12803 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1);
12804
12805 if (board_config == ALC262_AUTO) {
12806 /* automatic parse from the BIOS config */
12807 err = alc262_parse_auto_config(codec);
12808 if (err < 0) {
12809 alc_free(codec);
12810 return err;
12811 } else if (!err) {
12812 printk(KERN_INFO
12813 "hda_codec: Cannot set up configuration "
12814 "from BIOS. Using base mode...\n");
12815 board_config = ALC262_BASIC;
12816 }
12817 }
12818
12819 if (!spec->no_analog && has_cdefine_beep(codec)) {
12820 err = snd_hda_attach_beep_device(codec, 0x1);
12821 if (err < 0) {
12822 alc_free(codec);
12823 return err;
12824 }
12825 }
12826
12827 if (board_config != ALC262_AUTO)
12828 setup_preset(codec, &alc262_presets[board_config]);
12829
12830 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12831 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12832
12833 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12834 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12835
12836 if (!spec->adc_nids && spec->input_mux) {
12837 int i;
12838 /* check whether the digital-mic has to be supported */
12839 for (i = 0; i < spec->input_mux->num_items; i++) {
12840 if (spec->input_mux->items[i].index >= 9)
12841 break;
12842 }
12843 if (i < spec->input_mux->num_items) {
12844 /* use only ADC0 */
12845 spec->adc_nids = alc262_dmic_adc_nids;
12846 spec->num_adc_nids = 1;
12847 spec->capsrc_nids = alc262_dmic_capsrc_nids;
12848 } else {
12849 /* all analog inputs */
12850 /* check whether NID 0x07 is valid */
12851 unsigned int wcap = get_wcaps(codec, 0x07);
12852
12853 /* get type */
12854 wcap = get_wcaps_type(wcap);
12855 if (wcap != AC_WID_AUD_IN) {
12856 spec->adc_nids = alc262_adc_nids_alt;
12857 spec->num_adc_nids =
12858 ARRAY_SIZE(alc262_adc_nids_alt);
12859 spec->capsrc_nids = alc262_capsrc_nids_alt;
12860 } else {
12861 spec->adc_nids = alc262_adc_nids;
12862 spec->num_adc_nids =
12863 ARRAY_SIZE(alc262_adc_nids);
12864 spec->capsrc_nids = alc262_capsrc_nids;
12865 }
12866 }
12867 }
12868 if (!spec->cap_mixer && !spec->no_analog)
12869 set_capture_mixer(codec);
12870 if (!spec->no_analog && has_cdefine_beep(codec))
12871 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12872
12873 if (board_config == ALC262_AUTO)
12874 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0);
12875
12876 spec->vmaster_nid = 0x0c;
12877
12878 codec->patch_ops = alc_patch_ops;
12879 if (board_config == ALC262_AUTO)
12880 spec->init_hook = alc262_auto_init;
12881 #ifdef CONFIG_SND_HDA_POWER_SAVE
12882 if (!spec->loopback.amplist)
12883 spec->loopback.amplist = alc262_loopbacks;
12884 #endif
12885
12886 return 0;
12887 }
12888
12889 /*
12890 * ALC268 channel source setting (2 channel)
12891 */
12892 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12893 #define alc268_modes alc260_modes
12894
12895 static hda_nid_t alc268_dac_nids[2] = {
12896 /* front, hp */
12897 0x02, 0x03
12898 };
12899
12900 static hda_nid_t alc268_adc_nids[2] = {
12901 /* ADC0-1 */
12902 0x08, 0x07
12903 };
12904
12905 static hda_nid_t alc268_adc_nids_alt[1] = {
12906 /* ADC0 */
12907 0x08
12908 };
12909
12910 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12911
12912 static struct snd_kcontrol_new alc268_base_mixer[] = {
12913 /* output mixer control */
12914 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12915 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12918 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12919 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12920 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12921 { }
12922 };
12923
12924 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12925 /* output mixer control */
12926 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12927 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12928 ALC262_HIPPO_MASTER_SWITCH,
12929 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12930 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12931 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12932 { }
12933 };
12934
12935 /* bind Beep switches of both NID 0x0f and 0x10 */
12936 static struct hda_bind_ctls alc268_bind_beep_sw = {
12937 .ops = &snd_hda_bind_sw,
12938 .values = {
12939 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12940 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12941 0
12942 },
12943 };
12944
12945 static struct snd_kcontrol_new alc268_beep_mixer[] = {
12946 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12947 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12948 { }
12949 };
12950
12951 static struct hda_verb alc268_eapd_verbs[] = {
12952 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12953 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12954 { }
12955 };
12956
12957 /* Toshiba specific */
12958 static struct hda_verb alc268_toshiba_verbs[] = {
12959 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12960 { } /* end */
12961 };
12962
12963 /* Acer specific */
12964 /* bind volumes of both NID 0x02 and 0x03 */
12965 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12966 .ops = &snd_hda_bind_vol,
12967 .values = {
12968 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12969 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12970 0
12971 },
12972 };
12973
12974 /* mute/unmute internal speaker according to the hp jack and mute state */
12975 static void alc268_acer_automute(struct hda_codec *codec, int force)
12976 {
12977 struct alc_spec *spec = codec->spec;
12978 unsigned int mute;
12979
12980 if (force || !spec->sense_updated) {
12981 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
12982 spec->sense_updated = 1;
12983 }
12984 if (spec->jack_present)
12985 mute = HDA_AMP_MUTE; /* mute internal speaker */
12986 else /* unmute internal speaker if necessary */
12987 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12988 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12989 HDA_AMP_MUTE, mute);
12990 }
12991
12992
12993 /* bind hp and internal speaker mute (with plug check) */
12994 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12995 struct snd_ctl_elem_value *ucontrol)
12996 {
12997 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12998 long *valp = ucontrol->value.integer.value;
12999 int change;
13000
13001 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
13002 if (change)
13003 alc268_acer_automute(codec, 0);
13004 return change;
13005 }
13006
13007 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13008 /* output mixer control */
13009 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13010 {
13011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13012 .name = "Master Playback Switch",
13013 .subdevice = HDA_SUBDEV_AMP_FLAG,
13014 .info = snd_hda_mixer_amp_switch_info,
13015 .get = snd_hda_mixer_amp_switch_get,
13016 .put = alc268_acer_master_sw_put,
13017 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13018 },
13019 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13020 { }
13021 };
13022
13023 static struct snd_kcontrol_new alc268_acer_mixer[] = {
13024 /* output mixer control */
13025 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13026 {
13027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13028 .name = "Master Playback Switch",
13029 .subdevice = HDA_SUBDEV_AMP_FLAG,
13030 .info = snd_hda_mixer_amp_switch_info,
13031 .get = snd_hda_mixer_amp_switch_get,
13032 .put = alc268_acer_master_sw_put,
13033 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13034 },
13035 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13036 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13037 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
13038 { }
13039 };
13040
13041 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13042 /* output mixer control */
13043 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13044 {
13045 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13046 .name = "Master Playback Switch",
13047 .subdevice = HDA_SUBDEV_AMP_FLAG,
13048 .info = snd_hda_mixer_amp_switch_info,
13049 .get = snd_hda_mixer_amp_switch_get,
13050 .put = alc268_acer_master_sw_put,
13051 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13052 },
13053 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13054 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
13055 { }
13056 };
13057
13058 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13059 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13060 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13061 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13062 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13063 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13065 { }
13066 };
13067
13068 static struct hda_verb alc268_acer_verbs[] = {
13069 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13070 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13072 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13073 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13074 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13075 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13076 { }
13077 };
13078
13079 /* unsolicited event for HP jack sensing */
13080 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
13081 #define alc268_toshiba_setup alc262_hippo_setup
13082 #define alc268_toshiba_automute alc262_hippo_automute
13083
13084 static void alc268_acer_unsol_event(struct hda_codec *codec,
13085 unsigned int res)
13086 {
13087 if ((res >> 26) != ALC880_HP_EVENT)
13088 return;
13089 alc268_acer_automute(codec, 1);
13090 }
13091
13092 static void alc268_acer_init_hook(struct hda_codec *codec)
13093 {
13094 alc268_acer_automute(codec, 1);
13095 }
13096
13097 /* toggle speaker-output according to the hp-jack state */
13098 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13099 {
13100 unsigned int present;
13101 unsigned char bits;
13102
13103 present = snd_hda_jack_detect(codec, 0x15);
13104 bits = present ? HDA_AMP_MUTE : 0;
13105 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
13106 HDA_AMP_MUTE, bits);
13107 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
13108 HDA_AMP_MUTE, bits);
13109 }
13110
13111 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13112 unsigned int res)
13113 {
13114 switch (res >> 26) {
13115 case ALC880_HP_EVENT:
13116 alc268_aspire_one_speaker_automute(codec);
13117 break;
13118 case ALC880_MIC_EVENT:
13119 alc_mic_automute(codec);
13120 break;
13121 }
13122 }
13123
13124 static void alc268_acer_lc_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 = 6;
13131 spec->auto_mic = 1;
13132 }
13133
13134 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13135 {
13136 alc268_aspire_one_speaker_automute(codec);
13137 alc_mic_automute(codec);
13138 }
13139
13140 static struct snd_kcontrol_new alc268_dell_mixer[] = {
13141 /* output mixer control */
13142 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13143 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13144 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13145 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13146 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13147 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13148 { }
13149 };
13150
13151 static struct hda_verb alc268_dell_verbs[] = {
13152 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13153 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13154 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13155 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13156 { }
13157 };
13158
13159 /* mute/unmute internal speaker according to the hp jack and mute state */
13160 static void alc268_dell_setup(struct hda_codec *codec)
13161 {
13162 struct alc_spec *spec = codec->spec;
13163
13164 spec->autocfg.hp_pins[0] = 0x15;
13165 spec->autocfg.speaker_pins[0] = 0x14;
13166 spec->ext_mic.pin = 0x18;
13167 spec->ext_mic.mux_idx = 0;
13168 spec->int_mic.pin = 0x19;
13169 spec->int_mic.mux_idx = 1;
13170 spec->auto_mic = 1;
13171 }
13172
13173 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13174 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13175 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13176 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13178 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13179 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13180 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13181 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13182 { }
13183 };
13184
13185 static struct hda_verb alc267_quanta_il1_verbs[] = {
13186 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13187 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13188 { }
13189 };
13190
13191 static void alc267_quanta_il1_setup(struct hda_codec *codec)
13192 {
13193 struct alc_spec *spec = codec->spec;
13194 spec->autocfg.hp_pins[0] = 0x15;
13195 spec->autocfg.speaker_pins[0] = 0x14;
13196 spec->ext_mic.pin = 0x18;
13197 spec->ext_mic.mux_idx = 0;
13198 spec->int_mic.pin = 0x19;
13199 spec->int_mic.mux_idx = 1;
13200 spec->auto_mic = 1;
13201 }
13202
13203 /*
13204 * generic initialization of ADC, input mixers and output mixers
13205 */
13206 static struct hda_verb alc268_base_init_verbs[] = {
13207 /* Unmute DAC0-1 and set vol = 0 */
13208 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13209 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13210
13211 /*
13212 * Set up output mixers (0x0c - 0x0e)
13213 */
13214 /* set vol=0 to output mixers */
13215 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13216 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13217
13218 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13219 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13220
13221 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13222 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13223 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13225 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13226 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13227 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13228 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13229
13230 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13231 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13232 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13233 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13234 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13235
13236 /* set PCBEEP vol = 0, mute connections */
13237 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13238 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13239 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13240
13241 /* Unmute Selector 23h,24h and set the default input to mic-in */
13242
13243 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13244 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13245 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13247
13248 { }
13249 };
13250
13251 /*
13252 * generic initialization of ADC, input mixers and output mixers
13253 */
13254 static struct hda_verb alc268_volume_init_verbs[] = {
13255 /* set output DAC */
13256 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13257 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13258
13259 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13260 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13261 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13262 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13263 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13264
13265 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13267 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13268
13269 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13271
13272 /* set PCBEEP vol = 0, mute connections */
13273 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13274 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13275 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13276
13277 { }
13278 };
13279
13280 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13281 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13282 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13283 { } /* end */
13284 };
13285
13286 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13287 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13288 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13289 _DEFINE_CAPSRC(1),
13290 { } /* end */
13291 };
13292
13293 static struct snd_kcontrol_new alc268_capture_mixer[] = {
13294 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13295 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13296 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13297 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13298 _DEFINE_CAPSRC(2),
13299 { } /* end */
13300 };
13301
13302 static struct hda_input_mux alc268_capture_source = {
13303 .num_items = 4,
13304 .items = {
13305 { "Mic", 0x0 },
13306 { "Front Mic", 0x1 },
13307 { "Line", 0x2 },
13308 { "CD", 0x3 },
13309 },
13310 };
13311
13312 static struct hda_input_mux alc268_acer_capture_source = {
13313 .num_items = 3,
13314 .items = {
13315 { "Mic", 0x0 },
13316 { "Internal Mic", 0x1 },
13317 { "Line", 0x2 },
13318 },
13319 };
13320
13321 static struct hda_input_mux alc268_acer_dmic_capture_source = {
13322 .num_items = 3,
13323 .items = {
13324 { "Mic", 0x0 },
13325 { "Internal Mic", 0x6 },
13326 { "Line", 0x2 },
13327 },
13328 };
13329
13330 #ifdef CONFIG_SND_DEBUG
13331 static struct snd_kcontrol_new alc268_test_mixer[] = {
13332 /* Volume widgets */
13333 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13334 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13335 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13336 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13337 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13338 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13339 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13340 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13341 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13342 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13343 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13344 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13345 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13346 /* The below appears problematic on some hardwares */
13347 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13348 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13349 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13350 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13351 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13352
13353 /* Modes for retasking pin widgets */
13354 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13355 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13356 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13357 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13358
13359 /* Controls for GPIO pins, assuming they are configured as outputs */
13360 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13361 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13362 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13363 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13364
13365 /* Switches to allow the digital SPDIF output pin to be enabled.
13366 * The ALC268 does not have an SPDIF input.
13367 */
13368 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13369
13370 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13371 * this output to turn on an external amplifier.
13372 */
13373 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13374 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13375
13376 { } /* end */
13377 };
13378 #endif
13379
13380 /* create input playback/capture controls for the given pin */
13381 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13382 const char *ctlname, int idx)
13383 {
13384 hda_nid_t dac;
13385 int err;
13386
13387 switch (nid) {
13388 case 0x14:
13389 case 0x16:
13390 dac = 0x02;
13391 break;
13392 case 0x15:
13393 case 0x1a: /* ALC259/269 only */
13394 case 0x1b: /* ALC259/269 only */
13395 case 0x21: /* ALC269vb has this pin, too */
13396 dac = 0x03;
13397 break;
13398 default:
13399 snd_printd(KERN_WARNING "hda_codec: "
13400 "ignoring pin 0x%x as unknown\n", nid);
13401 return 0;
13402 }
13403 if (spec->multiout.dac_nids[0] != dac &&
13404 spec->multiout.dac_nids[1] != dac) {
13405 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13406 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13407 HDA_OUTPUT));
13408 if (err < 0)
13409 return err;
13410 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13411 }
13412
13413 if (nid != 0x16)
13414 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13415 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13416 else /* mono */
13417 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13418 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13419 if (err < 0)
13420 return err;
13421 return 0;
13422 }
13423
13424 /* add playback controls from the parsed DAC table */
13425 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13426 const struct auto_pin_cfg *cfg)
13427 {
13428 hda_nid_t nid;
13429 int err;
13430
13431 spec->multiout.dac_nids = spec->private_dac_nids;
13432
13433 nid = cfg->line_out_pins[0];
13434 if (nid) {
13435 const char *name;
13436 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13437 name = "Speaker";
13438 else
13439 name = "Front";
13440 err = alc268_new_analog_output(spec, nid, name, 0);
13441 if (err < 0)
13442 return err;
13443 }
13444
13445 nid = cfg->speaker_pins[0];
13446 if (nid == 0x1d) {
13447 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13448 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13449 if (err < 0)
13450 return err;
13451 } else if (nid) {
13452 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13453 if (err < 0)
13454 return err;
13455 }
13456 nid = cfg->hp_pins[0];
13457 if (nid) {
13458 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13459 if (err < 0)
13460 return err;
13461 }
13462
13463 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13464 if (nid == 0x16) {
13465 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13466 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13467 if (err < 0)
13468 return err;
13469 }
13470 return 0;
13471 }
13472
13473 /* create playback/capture controls for input pins */
13474 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13475 const struct auto_pin_cfg *cfg)
13476 {
13477 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13478 }
13479
13480 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13481 hda_nid_t nid, int pin_type)
13482 {
13483 int idx;
13484
13485 alc_set_pin_output(codec, nid, pin_type);
13486 if (nid == 0x14 || nid == 0x16)
13487 idx = 0;
13488 else
13489 idx = 1;
13490 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13491 }
13492
13493 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13494 {
13495 struct alc_spec *spec = codec->spec;
13496 int i;
13497
13498 for (i = 0; i < spec->autocfg.line_outs; i++) {
13499 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13500 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13501 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13502 }
13503 }
13504
13505 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13506 {
13507 struct alc_spec *spec = codec->spec;
13508 hda_nid_t pin;
13509 int i;
13510
13511 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13512 pin = spec->autocfg.hp_pins[i];
13513 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13514 }
13515 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13516 pin = spec->autocfg.speaker_pins[i];
13517 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13518 }
13519 if (spec->autocfg.mono_out_pin)
13520 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13521 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13522 }
13523
13524 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13525 {
13526 struct alc_spec *spec = codec->spec;
13527 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13528 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13529 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13530 unsigned int dac_vol1, dac_vol2;
13531
13532 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13533 snd_hda_codec_write(codec, speaker_nid, 0,
13534 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13535 /* mute mixer inputs from 0x1d */
13536 snd_hda_codec_write(codec, 0x0f, 0,
13537 AC_VERB_SET_AMP_GAIN_MUTE,
13538 AMP_IN_UNMUTE(1));
13539 snd_hda_codec_write(codec, 0x10, 0,
13540 AC_VERB_SET_AMP_GAIN_MUTE,
13541 AMP_IN_UNMUTE(1));
13542 } else {
13543 /* unmute mixer inputs from 0x1d */
13544 snd_hda_codec_write(codec, 0x0f, 0,
13545 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13546 snd_hda_codec_write(codec, 0x10, 0,
13547 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13548 }
13549
13550 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13551 if (line_nid == 0x14)
13552 dac_vol2 = AMP_OUT_ZERO;
13553 else if (line_nid == 0x15)
13554 dac_vol1 = AMP_OUT_ZERO;
13555 if (hp_nid == 0x14)
13556 dac_vol2 = AMP_OUT_ZERO;
13557 else if (hp_nid == 0x15)
13558 dac_vol1 = AMP_OUT_ZERO;
13559 if (line_nid != 0x16 || hp_nid != 0x16 ||
13560 spec->autocfg.line_out_pins[1] != 0x16 ||
13561 spec->autocfg.line_out_pins[2] != 0x16)
13562 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13563
13564 snd_hda_codec_write(codec, 0x02, 0,
13565 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13566 snd_hda_codec_write(codec, 0x03, 0,
13567 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13568 }
13569
13570 /* pcm configuration: identical with ALC880 */
13571 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13572 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13573 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13574 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13575
13576 /*
13577 * BIOS auto configuration
13578 */
13579 static int alc268_parse_auto_config(struct hda_codec *codec)
13580 {
13581 struct alc_spec *spec = codec->spec;
13582 int err;
13583 static hda_nid_t alc268_ignore[] = { 0 };
13584
13585 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13586 alc268_ignore);
13587 if (err < 0)
13588 return err;
13589 if (!spec->autocfg.line_outs) {
13590 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13591 spec->multiout.max_channels = 2;
13592 spec->no_analog = 1;
13593 goto dig_only;
13594 }
13595 return 0; /* can't find valid BIOS pin config */
13596 }
13597 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13598 if (err < 0)
13599 return err;
13600 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13601 if (err < 0)
13602 return err;
13603
13604 spec->multiout.max_channels = 2;
13605
13606 dig_only:
13607 /* digital only support output */
13608 alc_auto_parse_digital(codec);
13609 if (spec->kctls.list)
13610 add_mixer(spec, spec->kctls.list);
13611
13612 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13613 add_mixer(spec, alc268_beep_mixer);
13614
13615 add_verb(spec, alc268_volume_init_verbs);
13616 spec->num_mux_defs = 2;
13617 spec->input_mux = &spec->private_imux[0];
13618
13619 err = alc_auto_add_mic_boost(codec);
13620 if (err < 0)
13621 return err;
13622
13623 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13624
13625 return 1;
13626 }
13627
13628 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13629
13630 /* init callback for auto-configuration model -- overriding the default init */
13631 static void alc268_auto_init(struct hda_codec *codec)
13632 {
13633 struct alc_spec *spec = codec->spec;
13634 alc268_auto_init_multi_out(codec);
13635 alc268_auto_init_hp_out(codec);
13636 alc268_auto_init_mono_speaker_out(codec);
13637 alc268_auto_init_analog_input(codec);
13638 alc_auto_init_digital(codec);
13639 if (spec->unsol_event)
13640 alc_inithook(codec);
13641 }
13642
13643 /*
13644 * configuration and preset
13645 */
13646 static const char *alc268_models[ALC268_MODEL_LAST] = {
13647 [ALC267_QUANTA_IL1] = "quanta-il1",
13648 [ALC268_3ST] = "3stack",
13649 [ALC268_TOSHIBA] = "toshiba",
13650 [ALC268_ACER] = "acer",
13651 [ALC268_ACER_DMIC] = "acer-dmic",
13652 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13653 [ALC268_DELL] = "dell",
13654 [ALC268_ZEPTO] = "zepto",
13655 #ifdef CONFIG_SND_DEBUG
13656 [ALC268_TEST] = "test",
13657 #endif
13658 [ALC268_AUTO] = "auto",
13659 };
13660
13661 static struct snd_pci_quirk alc268_cfg_tbl[] = {
13662 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13663 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13664 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13665 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13666 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13667 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13668 ALC268_ACER_ASPIRE_ONE),
13669 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13670 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13671 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13672 /* almost compatible with toshiba but with optional digital outs;
13673 * auto-probing seems working fine
13674 */
13675 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13676 ALC268_AUTO),
13677 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13678 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13679 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13680 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13681 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13682 {}
13683 };
13684
13685 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13686 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13687 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13688 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13689 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13690 ALC268_TOSHIBA),
13691 {}
13692 };
13693
13694 static struct alc_config_preset alc268_presets[] = {
13695 [ALC267_QUANTA_IL1] = {
13696 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13697 alc268_capture_nosrc_mixer },
13698 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13699 alc267_quanta_il1_verbs },
13700 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13701 .dac_nids = alc268_dac_nids,
13702 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13703 .adc_nids = alc268_adc_nids_alt,
13704 .hp_nid = 0x03,
13705 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13706 .channel_mode = alc268_modes,
13707 .unsol_event = alc_sku_unsol_event,
13708 .setup = alc267_quanta_il1_setup,
13709 .init_hook = alc_inithook,
13710 },
13711 [ALC268_3ST] = {
13712 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13713 alc268_beep_mixer },
13714 .init_verbs = { alc268_base_init_verbs },
13715 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13716 .dac_nids = alc268_dac_nids,
13717 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13718 .adc_nids = alc268_adc_nids_alt,
13719 .capsrc_nids = alc268_capsrc_nids,
13720 .hp_nid = 0x03,
13721 .dig_out_nid = ALC268_DIGOUT_NID,
13722 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13723 .channel_mode = alc268_modes,
13724 .input_mux = &alc268_capture_source,
13725 },
13726 [ALC268_TOSHIBA] = {
13727 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13728 alc268_beep_mixer },
13729 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13730 alc268_toshiba_verbs },
13731 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13732 .dac_nids = alc268_dac_nids,
13733 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13734 .adc_nids = alc268_adc_nids_alt,
13735 .capsrc_nids = alc268_capsrc_nids,
13736 .hp_nid = 0x03,
13737 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13738 .channel_mode = alc268_modes,
13739 .input_mux = &alc268_capture_source,
13740 .unsol_event = alc268_toshiba_unsol_event,
13741 .setup = alc268_toshiba_setup,
13742 .init_hook = alc268_toshiba_automute,
13743 },
13744 [ALC268_ACER] = {
13745 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13746 alc268_beep_mixer },
13747 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13748 alc268_acer_verbs },
13749 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13750 .dac_nids = alc268_dac_nids,
13751 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13752 .adc_nids = alc268_adc_nids_alt,
13753 .capsrc_nids = alc268_capsrc_nids,
13754 .hp_nid = 0x02,
13755 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13756 .channel_mode = alc268_modes,
13757 .input_mux = &alc268_acer_capture_source,
13758 .unsol_event = alc268_acer_unsol_event,
13759 .init_hook = alc268_acer_init_hook,
13760 },
13761 [ALC268_ACER_DMIC] = {
13762 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13763 alc268_beep_mixer },
13764 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13765 alc268_acer_verbs },
13766 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13767 .dac_nids = alc268_dac_nids,
13768 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13769 .adc_nids = alc268_adc_nids_alt,
13770 .capsrc_nids = alc268_capsrc_nids,
13771 .hp_nid = 0x02,
13772 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13773 .channel_mode = alc268_modes,
13774 .input_mux = &alc268_acer_dmic_capture_source,
13775 .unsol_event = alc268_acer_unsol_event,
13776 .init_hook = alc268_acer_init_hook,
13777 },
13778 [ALC268_ACER_ASPIRE_ONE] = {
13779 .mixers = { alc268_acer_aspire_one_mixer,
13780 alc268_beep_mixer,
13781 alc268_capture_nosrc_mixer },
13782 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13783 alc268_acer_aspire_one_verbs },
13784 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13785 .dac_nids = alc268_dac_nids,
13786 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13787 .adc_nids = alc268_adc_nids_alt,
13788 .capsrc_nids = alc268_capsrc_nids,
13789 .hp_nid = 0x03,
13790 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13791 .channel_mode = alc268_modes,
13792 .unsol_event = alc268_acer_lc_unsol_event,
13793 .setup = alc268_acer_lc_setup,
13794 .init_hook = alc268_acer_lc_init_hook,
13795 },
13796 [ALC268_DELL] = {
13797 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13798 alc268_capture_nosrc_mixer },
13799 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13800 alc268_dell_verbs },
13801 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13802 .dac_nids = alc268_dac_nids,
13803 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13804 .adc_nids = alc268_adc_nids_alt,
13805 .capsrc_nids = alc268_capsrc_nids,
13806 .hp_nid = 0x02,
13807 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13808 .channel_mode = alc268_modes,
13809 .unsol_event = alc_sku_unsol_event,
13810 .setup = alc268_dell_setup,
13811 .init_hook = alc_inithook,
13812 },
13813 [ALC268_ZEPTO] = {
13814 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13815 alc268_beep_mixer },
13816 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13817 alc268_toshiba_verbs },
13818 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13819 .dac_nids = alc268_dac_nids,
13820 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13821 .adc_nids = alc268_adc_nids_alt,
13822 .capsrc_nids = alc268_capsrc_nids,
13823 .hp_nid = 0x03,
13824 .dig_out_nid = ALC268_DIGOUT_NID,
13825 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13826 .channel_mode = alc268_modes,
13827 .input_mux = &alc268_capture_source,
13828 .setup = alc268_toshiba_setup,
13829 .init_hook = alc268_toshiba_automute,
13830 },
13831 #ifdef CONFIG_SND_DEBUG
13832 [ALC268_TEST] = {
13833 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13834 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13835 alc268_volume_init_verbs },
13836 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13837 .dac_nids = alc268_dac_nids,
13838 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13839 .adc_nids = alc268_adc_nids_alt,
13840 .capsrc_nids = alc268_capsrc_nids,
13841 .hp_nid = 0x03,
13842 .dig_out_nid = ALC268_DIGOUT_NID,
13843 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13844 .channel_mode = alc268_modes,
13845 .input_mux = &alc268_capture_source,
13846 },
13847 #endif
13848 };
13849
13850 static int patch_alc268(struct hda_codec *codec)
13851 {
13852 struct alc_spec *spec;
13853 int board_config;
13854 int i, has_beep, err;
13855
13856 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13857 if (spec == NULL)
13858 return -ENOMEM;
13859
13860 codec->spec = spec;
13861
13862 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13863 alc268_models,
13864 alc268_cfg_tbl);
13865
13866 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13867 board_config = snd_hda_check_board_codec_sid_config(codec,
13868 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13869
13870 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13871 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13872 codec->chip_name);
13873 board_config = ALC268_AUTO;
13874 }
13875
13876 if (board_config == ALC268_AUTO) {
13877 /* automatic parse from the BIOS config */
13878 err = alc268_parse_auto_config(codec);
13879 if (err < 0) {
13880 alc_free(codec);
13881 return err;
13882 } else if (!err) {
13883 printk(KERN_INFO
13884 "hda_codec: Cannot set up configuration "
13885 "from BIOS. Using base mode...\n");
13886 board_config = ALC268_3ST;
13887 }
13888 }
13889
13890 if (board_config != ALC268_AUTO)
13891 setup_preset(codec, &alc268_presets[board_config]);
13892
13893 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13894 spec->stream_analog_capture = &alc268_pcm_analog_capture;
13895 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
13896
13897 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13898
13899 has_beep = 0;
13900 for (i = 0; i < spec->num_mixers; i++) {
13901 if (spec->mixers[i] == alc268_beep_mixer) {
13902 has_beep = 1;
13903 break;
13904 }
13905 }
13906
13907 if (has_beep) {
13908 err = snd_hda_attach_beep_device(codec, 0x1);
13909 if (err < 0) {
13910 alc_free(codec);
13911 return err;
13912 }
13913 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13914 /* override the amp caps for beep generator */
13915 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
13916 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13917 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13918 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13919 (0 << AC_AMPCAP_MUTE_SHIFT));
13920 }
13921
13922 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
13923 /* check whether NID 0x07 is valid */
13924 unsigned int wcap = get_wcaps(codec, 0x07);
13925 int i;
13926
13927 spec->capsrc_nids = alc268_capsrc_nids;
13928 /* get type */
13929 wcap = get_wcaps_type(wcap);
13930 if (spec->auto_mic ||
13931 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
13932 spec->adc_nids = alc268_adc_nids_alt;
13933 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
13934 if (spec->auto_mic)
13935 fixup_automic_adc(codec);
13936 if (spec->auto_mic || spec->input_mux->num_items == 1)
13937 add_mixer(spec, alc268_capture_nosrc_mixer);
13938 else
13939 add_mixer(spec, alc268_capture_alt_mixer);
13940 } else {
13941 spec->adc_nids = alc268_adc_nids;
13942 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
13943 add_mixer(spec, alc268_capture_mixer);
13944 }
13945 /* set default input source */
13946 for (i = 0; i < spec->num_adc_nids; i++)
13947 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13948 0, AC_VERB_SET_CONNECT_SEL,
13949 i < spec->num_mux_defs ?
13950 spec->input_mux[i].items[0].index :
13951 spec->input_mux->items[0].index);
13952 }
13953
13954 spec->vmaster_nid = 0x02;
13955
13956 codec->patch_ops = alc_patch_ops;
13957 if (board_config == ALC268_AUTO)
13958 spec->init_hook = alc268_auto_init;
13959
13960 return 0;
13961 }
13962
13963 /*
13964 * ALC269 channel source setting (2 channel)
13965 */
13966 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13967
13968 #define alc269_dac_nids alc260_dac_nids
13969
13970 static hda_nid_t alc269_adc_nids[1] = {
13971 /* ADC1 */
13972 0x08,
13973 };
13974
13975 static hda_nid_t alc269_capsrc_nids[1] = {
13976 0x23,
13977 };
13978
13979 static hda_nid_t alc269vb_adc_nids[1] = {
13980 /* ADC1 */
13981 0x09,
13982 };
13983
13984 static hda_nid_t alc269vb_capsrc_nids[1] = {
13985 0x22,
13986 };
13987
13988 static hda_nid_t alc269_adc_candidates[] = {
13989 0x08, 0x09, 0x07,
13990 };
13991
13992 #define alc269_modes alc260_modes
13993 #define alc269_capture_source alc880_lg_lw_capture_source
13994
13995 static struct snd_kcontrol_new alc269_base_mixer[] = {
13996 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13997 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14002 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14003 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14004 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14005 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14006 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14007 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14008 { } /* end */
14009 };
14010
14011 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14012 /* output mixer control */
14013 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14014 {
14015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14016 .name = "Master Playback Switch",
14017 .subdevice = HDA_SUBDEV_AMP_FLAG,
14018 .info = snd_hda_mixer_amp_switch_info,
14019 .get = snd_hda_mixer_amp_switch_get,
14020 .put = alc268_acer_master_sw_put,
14021 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14022 },
14023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14024 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14025 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14026 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14027 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14028 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
14029 { }
14030 };
14031
14032 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14033 /* output mixer control */
14034 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14035 {
14036 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14037 .name = "Master Playback Switch",
14038 .subdevice = HDA_SUBDEV_AMP_FLAG,
14039 .info = snd_hda_mixer_amp_switch_info,
14040 .get = snd_hda_mixer_amp_switch_get,
14041 .put = alc268_acer_master_sw_put,
14042 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14043 },
14044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14046 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14047 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14048 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14049 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
14050 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14051 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14052 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
14053 { }
14054 };
14055
14056 static struct snd_kcontrol_new alc269_laptop_mixer[] = {
14057 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14058 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14060 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14061 { } /* end */
14062 };
14063
14064 static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14065 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14066 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14068 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14069 { } /* end */
14070 };
14071
14072 static struct snd_kcontrol_new alc269_asus_mixer[] = {
14073 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14074 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14075 { } /* end */
14076 };
14077
14078 /* capture mixer elements */
14079 static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14080 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14081 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14082 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14083 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
14084 { } /* end */
14085 };
14086
14087 static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14088 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14089 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14090 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14091 { } /* end */
14092 };
14093
14094 static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14095 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14096 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14098 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
14099 { } /* end */
14100 };
14101
14102 static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14103 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14104 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14105 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14106 { } /* end */
14107 };
14108
14109 /* FSC amilo */
14110 #define alc269_fujitsu_mixer alc269_laptop_mixer
14111
14112 static struct hda_verb alc269_quanta_fl1_verbs[] = {
14113 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14116 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14117 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14118 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14119 { }
14120 };
14121
14122 static struct hda_verb alc269_lifebook_verbs[] = {
14123 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14124 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14125 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14128 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14129 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14130 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14131 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14132 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14133 { }
14134 };
14135
14136 /* toggle speaker-output according to the hp-jack state */
14137 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14138 {
14139 unsigned int present;
14140 unsigned char bits;
14141
14142 present = snd_hda_jack_detect(codec, 0x15);
14143 bits = present ? HDA_AMP_MUTE : 0;
14144 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14145 HDA_AMP_MUTE, bits);
14146 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14147 HDA_AMP_MUTE, bits);
14148
14149 snd_hda_codec_write(codec, 0x20, 0,
14150 AC_VERB_SET_COEF_INDEX, 0x0c);
14151 snd_hda_codec_write(codec, 0x20, 0,
14152 AC_VERB_SET_PROC_COEF, 0x680);
14153
14154 snd_hda_codec_write(codec, 0x20, 0,
14155 AC_VERB_SET_COEF_INDEX, 0x0c);
14156 snd_hda_codec_write(codec, 0x20, 0,
14157 AC_VERB_SET_PROC_COEF, 0x480);
14158 }
14159
14160 /* toggle speaker-output according to the hp-jacks state */
14161 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14162 {
14163 unsigned int present;
14164 unsigned char bits;
14165
14166 /* Check laptop headphone socket */
14167 present = snd_hda_jack_detect(codec, 0x15);
14168
14169 /* Check port replicator headphone socket */
14170 present |= snd_hda_jack_detect(codec, 0x1a);
14171
14172 bits = present ? HDA_AMP_MUTE : 0;
14173 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14174 HDA_AMP_MUTE, bits);
14175 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14176 HDA_AMP_MUTE, bits);
14177
14178 snd_hda_codec_write(codec, 0x20, 0,
14179 AC_VERB_SET_COEF_INDEX, 0x0c);
14180 snd_hda_codec_write(codec, 0x20, 0,
14181 AC_VERB_SET_PROC_COEF, 0x680);
14182
14183 snd_hda_codec_write(codec, 0x20, 0,
14184 AC_VERB_SET_COEF_INDEX, 0x0c);
14185 snd_hda_codec_write(codec, 0x20, 0,
14186 AC_VERB_SET_PROC_COEF, 0x480);
14187 }
14188
14189 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14190 {
14191 unsigned int present_laptop;
14192 unsigned int present_dock;
14193
14194 present_laptop = snd_hda_jack_detect(codec, 0x18);
14195 present_dock = snd_hda_jack_detect(codec, 0x1b);
14196
14197 /* Laptop mic port overrides dock mic port, design decision */
14198 if (present_dock)
14199 snd_hda_codec_write(codec, 0x23, 0,
14200 AC_VERB_SET_CONNECT_SEL, 0x3);
14201 if (present_laptop)
14202 snd_hda_codec_write(codec, 0x23, 0,
14203 AC_VERB_SET_CONNECT_SEL, 0x0);
14204 if (!present_dock && !present_laptop)
14205 snd_hda_codec_write(codec, 0x23, 0,
14206 AC_VERB_SET_CONNECT_SEL, 0x1);
14207 }
14208
14209 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14210 unsigned int res)
14211 {
14212 switch (res >> 26) {
14213 case ALC880_HP_EVENT:
14214 alc269_quanta_fl1_speaker_automute(codec);
14215 break;
14216 case ALC880_MIC_EVENT:
14217 alc_mic_automute(codec);
14218 break;
14219 }
14220 }
14221
14222 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14223 unsigned int res)
14224 {
14225 if ((res >> 26) == ALC880_HP_EVENT)
14226 alc269_lifebook_speaker_automute(codec);
14227 if ((res >> 26) == ALC880_MIC_EVENT)
14228 alc269_lifebook_mic_autoswitch(codec);
14229 }
14230
14231 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14232 {
14233 struct alc_spec *spec = codec->spec;
14234 spec->autocfg.hp_pins[0] = 0x15;
14235 spec->autocfg.speaker_pins[0] = 0x14;
14236 spec->ext_mic.pin = 0x18;
14237 spec->ext_mic.mux_idx = 0;
14238 spec->int_mic.pin = 0x19;
14239 spec->int_mic.mux_idx = 1;
14240 spec->auto_mic = 1;
14241 }
14242
14243 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14244 {
14245 alc269_quanta_fl1_speaker_automute(codec);
14246 alc_mic_automute(codec);
14247 }
14248
14249 static void alc269_lifebook_init_hook(struct hda_codec *codec)
14250 {
14251 alc269_lifebook_speaker_automute(codec);
14252 alc269_lifebook_mic_autoswitch(codec);
14253 }
14254
14255 static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14257 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14258 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14259 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14260 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14261 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14262 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14263 {}
14264 };
14265
14266 static struct hda_verb alc269_laptop_amic_init_verbs[] = {
14267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14268 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14269 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14270 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14271 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14272 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14273 {}
14274 };
14275
14276 static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14277 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14278 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14279 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14280 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14281 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14282 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14283 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14284 {}
14285 };
14286
14287 static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14288 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14289 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14290 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14292 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14294 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14295 {}
14296 };
14297
14298 static struct hda_verb alc271_acer_dmic_verbs[] = {
14299 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14300 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14301 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14303 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14304 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14305 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14306 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14307 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14308 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14309 { }
14310 };
14311
14312 /* toggle speaker-output according to the hp-jack state */
14313 static void alc269_speaker_automute(struct hda_codec *codec)
14314 {
14315 struct alc_spec *spec = codec->spec;
14316 unsigned int nid = spec->autocfg.hp_pins[0];
14317 unsigned int present;
14318 unsigned char bits;
14319
14320 present = snd_hda_jack_detect(codec, nid);
14321 bits = present ? HDA_AMP_MUTE : 0;
14322 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14323 HDA_AMP_MUTE, bits);
14324 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14325 HDA_AMP_MUTE, bits);
14326 }
14327
14328 /* unsolicited event for HP jack sensing */
14329 static void alc269_laptop_unsol_event(struct hda_codec *codec,
14330 unsigned int res)
14331 {
14332 switch (res >> 26) {
14333 case ALC880_HP_EVENT:
14334 alc269_speaker_automute(codec);
14335 break;
14336 case ALC880_MIC_EVENT:
14337 alc_mic_automute(codec);
14338 break;
14339 }
14340 }
14341
14342 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14343 {
14344 struct alc_spec *spec = codec->spec;
14345 spec->autocfg.hp_pins[0] = 0x15;
14346 spec->autocfg.speaker_pins[0] = 0x14;
14347 spec->ext_mic.pin = 0x18;
14348 spec->ext_mic.mux_idx = 0;
14349 spec->int_mic.pin = 0x19;
14350 spec->int_mic.mux_idx = 1;
14351 spec->auto_mic = 1;
14352 }
14353
14354 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14355 {
14356 struct alc_spec *spec = codec->spec;
14357 spec->autocfg.hp_pins[0] = 0x15;
14358 spec->autocfg.speaker_pins[0] = 0x14;
14359 spec->ext_mic.pin = 0x18;
14360 spec->ext_mic.mux_idx = 0;
14361 spec->int_mic.pin = 0x12;
14362 spec->int_mic.mux_idx = 5;
14363 spec->auto_mic = 1;
14364 }
14365
14366 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14367 {
14368 struct alc_spec *spec = codec->spec;
14369 spec->autocfg.hp_pins[0] = 0x21;
14370 spec->autocfg.speaker_pins[0] = 0x14;
14371 spec->ext_mic.pin = 0x18;
14372 spec->ext_mic.mux_idx = 0;
14373 spec->int_mic.pin = 0x19;
14374 spec->int_mic.mux_idx = 1;
14375 spec->auto_mic = 1;
14376 }
14377
14378 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14379 {
14380 struct alc_spec *spec = codec->spec;
14381 spec->autocfg.hp_pins[0] = 0x21;
14382 spec->autocfg.speaker_pins[0] = 0x14;
14383 spec->ext_mic.pin = 0x18;
14384 spec->ext_mic.mux_idx = 0;
14385 spec->int_mic.pin = 0x12;
14386 spec->int_mic.mux_idx = 6;
14387 spec->auto_mic = 1;
14388 }
14389
14390 static void alc269_laptop_inithook(struct hda_codec *codec)
14391 {
14392 alc269_speaker_automute(codec);
14393 alc_mic_automute(codec);
14394 }
14395
14396 /*
14397 * generic initialization of ADC, input mixers and output mixers
14398 */
14399 static struct hda_verb alc269_init_verbs[] = {
14400 /*
14401 * Unmute ADC0 and set the default input to mic-in
14402 */
14403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14404
14405 /*
14406 * Set up output mixers (0x02 - 0x03)
14407 */
14408 /* set vol=0 to output mixers */
14409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14411
14412 /* set up input amps for analog loopback */
14413 /* Amp Indices: DAC = 0, mixer = 1 */
14414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14420
14421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14428
14429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14431
14432 /* FIXME: use Mux-type input source selection */
14433 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14434 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14435 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14436
14437 /* set EAPD */
14438 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14439 { }
14440 };
14441
14442 static struct hda_verb alc269vb_init_verbs[] = {
14443 /*
14444 * Unmute ADC0 and set the default input to mic-in
14445 */
14446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14447
14448 /*
14449 * Set up output mixers (0x02 - 0x03)
14450 */
14451 /* set vol=0 to output mixers */
14452 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14453 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14454
14455 /* set up input amps for analog loopback */
14456 /* Amp Indices: DAC = 0, mixer = 1 */
14457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14463
14464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14465 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14471
14472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14474
14475 /* FIXME: use Mux-type input source selection */
14476 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14477 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14478 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14479
14480 /* set EAPD */
14481 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14482 { }
14483 };
14484
14485 #define alc269_auto_create_multi_out_ctls \
14486 alc268_auto_create_multi_out_ctls
14487 #define alc269_auto_create_input_ctls \
14488 alc268_auto_create_input_ctls
14489
14490 #ifdef CONFIG_SND_HDA_POWER_SAVE
14491 #define alc269_loopbacks alc880_loopbacks
14492 #endif
14493
14494 /* pcm configuration: identical with ALC880 */
14495 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14496 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14497 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14498 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14499
14500 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14501 .substreams = 1,
14502 .channels_min = 2,
14503 .channels_max = 8,
14504 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14505 /* NID is set in alc_build_pcms */
14506 .ops = {
14507 .open = alc880_playback_pcm_open,
14508 .prepare = alc880_playback_pcm_prepare,
14509 .cleanup = alc880_playback_pcm_cleanup
14510 },
14511 };
14512
14513 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14514 .substreams = 1,
14515 .channels_min = 2,
14516 .channels_max = 2,
14517 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14518 /* NID is set in alc_build_pcms */
14519 };
14520
14521 #ifdef CONFIG_SND_HDA_POWER_SAVE
14522 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14523 {
14524 switch (codec->subsystem_id) {
14525 case 0x103c1586:
14526 return 1;
14527 }
14528 return 0;
14529 }
14530
14531 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14532 {
14533 /* update mute-LED according to the speaker mute state */
14534 if (nid == 0x01 || nid == 0x14) {
14535 int pinval;
14536 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14537 HDA_AMP_MUTE)
14538 pinval = 0x24;
14539 else
14540 pinval = 0x20;
14541 /* mic2 vref pin is used for mute LED control */
14542 snd_hda_codec_update_cache(codec, 0x19, 0,
14543 AC_VERB_SET_PIN_WIDGET_CONTROL,
14544 pinval);
14545 }
14546 return alc_check_power_status(codec, nid);
14547 }
14548 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14549
14550 static int alc275_setup_dual_adc(struct hda_codec *codec)
14551 {
14552 struct alc_spec *spec = codec->spec;
14553
14554 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14555 return 0;
14556 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14557 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14558 if (spec->ext_mic.pin <= 0x12) {
14559 spec->private_adc_nids[0] = 0x08;
14560 spec->private_adc_nids[1] = 0x11;
14561 spec->private_capsrc_nids[0] = 0x23;
14562 spec->private_capsrc_nids[1] = 0x22;
14563 } else {
14564 spec->private_adc_nids[0] = 0x11;
14565 spec->private_adc_nids[1] = 0x08;
14566 spec->private_capsrc_nids[0] = 0x22;
14567 spec->private_capsrc_nids[1] = 0x23;
14568 }
14569 spec->adc_nids = spec->private_adc_nids;
14570 spec->capsrc_nids = spec->private_capsrc_nids;
14571 spec->num_adc_nids = 2;
14572 spec->dual_adc_switch = 1;
14573 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14574 spec->adc_nids[0], spec->adc_nids[1]);
14575 return 1;
14576 }
14577 return 0;
14578 }
14579
14580 /* different alc269-variants */
14581 enum {
14582 ALC269_TYPE_NORMAL,
14583 ALC269_TYPE_ALC259,
14584 ALC269_TYPE_ALC271X,
14585 };
14586
14587 /*
14588 * BIOS auto configuration
14589 */
14590 static int alc269_parse_auto_config(struct hda_codec *codec)
14591 {
14592 struct alc_spec *spec = codec->spec;
14593 int err;
14594 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14595
14596 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14597 alc269_ignore);
14598 if (err < 0)
14599 return err;
14600
14601 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14602 if (err < 0)
14603 return err;
14604 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14605 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14606 else
14607 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14608 0x22, 0);
14609 if (err < 0)
14610 return err;
14611
14612 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14613
14614 alc_auto_parse_digital(codec);
14615
14616 if (spec->kctls.list)
14617 add_mixer(spec, spec->kctls.list);
14618
14619 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14620 add_verb(spec, alc269vb_init_verbs);
14621 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14622 } else {
14623 add_verb(spec, alc269_init_verbs);
14624 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14625 }
14626
14627 spec->num_mux_defs = 1;
14628 spec->input_mux = &spec->private_imux[0];
14629
14630 if (!alc275_setup_dual_adc(codec))
14631 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14632 sizeof(alc269_adc_candidates));
14633
14634 /* set default input source */
14635 if (!spec->dual_adc_switch)
14636 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14637 spec->input_mux->items[0].index);
14638
14639 err = alc_auto_add_mic_boost(codec);
14640 if (err < 0)
14641 return err;
14642
14643 if (!spec->cap_mixer && !spec->no_analog)
14644 set_capture_mixer(codec);
14645
14646 return 1;
14647 }
14648
14649 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14650 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14651 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14652
14653
14654 /* init callback for auto-configuration model -- overriding the default init */
14655 static void alc269_auto_init(struct hda_codec *codec)
14656 {
14657 struct alc_spec *spec = codec->spec;
14658 alc269_auto_init_multi_out(codec);
14659 alc269_auto_init_hp_out(codec);
14660 alc269_auto_init_analog_input(codec);
14661 alc_auto_init_digital(codec);
14662 alc_init_jacks(codec);
14663 if (spec->unsol_event)
14664 alc_inithook(codec);
14665 }
14666
14667 #ifdef SND_HDA_NEEDS_RESUME
14668 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14669 {
14670 int val = alc_read_coef_idx(codec, 0x04);
14671 if (power_up)
14672 val |= 1 << 11;
14673 else
14674 val &= ~(1 << 11);
14675 alc_write_coef_idx(codec, 0x04, val);
14676 }
14677
14678 #ifdef CONFIG_SND_HDA_POWER_SAVE
14679 static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14680 {
14681 struct alc_spec *spec = codec->spec;
14682
14683 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14684 alc269_toggle_power_output(codec, 0);
14685 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14686 alc269_toggle_power_output(codec, 0);
14687 msleep(150);
14688 }
14689
14690 alc_shutup(codec);
14691 if (spec && spec->power_hook)
14692 spec->power_hook(codec);
14693 return 0;
14694 }
14695 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14696
14697 static int alc269_resume(struct hda_codec *codec)
14698 {
14699 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14700 alc269_toggle_power_output(codec, 0);
14701 msleep(150);
14702 }
14703
14704 codec->patch_ops.init(codec);
14705
14706 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14707 alc269_toggle_power_output(codec, 1);
14708 msleep(200);
14709 }
14710
14711 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14712 alc269_toggle_power_output(codec, 1);
14713
14714 snd_hda_codec_resume_amp(codec);
14715 snd_hda_codec_resume_cache(codec);
14716 hda_call_check_power_status(codec, 0x01);
14717 return 0;
14718 }
14719 #endif /* SND_HDA_NEEDS_RESUME */
14720
14721 enum {
14722 ALC269_FIXUP_SONY_VAIO,
14723 ALC269_FIXUP_DELL_M101Z,
14724 };
14725
14726 static const struct alc_fixup alc269_fixups[] = {
14727 [ALC269_FIXUP_SONY_VAIO] = {
14728 .verbs = (const struct hda_verb[]) {
14729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14730 {}
14731 }
14732 },
14733 [ALC269_FIXUP_DELL_M101Z] = {
14734 .verbs = (const struct hda_verb[]) {
14735 /* Enables internal speaker */
14736 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14737 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14738 {}
14739 }
14740 },
14741 };
14742
14743 static struct snd_pci_quirk alc269_fixup_tbl[] = {
14744 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14745 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14746 {}
14747 };
14748
14749
14750 /*
14751 * configuration and preset
14752 */
14753 static const char *alc269_models[ALC269_MODEL_LAST] = {
14754 [ALC269_BASIC] = "basic",
14755 [ALC269_QUANTA_FL1] = "quanta",
14756 [ALC269_AMIC] = "laptop-amic",
14757 [ALC269_DMIC] = "laptop-dmic",
14758 [ALC269_FUJITSU] = "fujitsu",
14759 [ALC269_LIFEBOOK] = "lifebook",
14760 [ALC269_AUTO] = "auto",
14761 };
14762
14763 static struct snd_pci_quirk alc269_cfg_tbl[] = {
14764 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14765 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14766 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14767 ALC269_AMIC),
14768 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14769 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14770 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14771 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14772 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14773 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14774 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14775 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14776 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14777 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14778 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14779 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14780 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14781 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14782 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14783 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14784 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14785 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14786 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14787 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14788 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14789 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14790 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14791 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14792 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14793 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14794 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14795 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14796 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14797 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14798 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14799 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14800 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14801 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14802 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14803 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14804 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14805 ALC269_DMIC),
14806 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14807 ALC269_DMIC),
14808 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14809 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14810 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14811 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14812 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14813 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14814 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14815 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14816 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14817 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14818 {}
14819 };
14820
14821 static struct alc_config_preset alc269_presets[] = {
14822 [ALC269_BASIC] = {
14823 .mixers = { alc269_base_mixer },
14824 .init_verbs = { alc269_init_verbs },
14825 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14826 .dac_nids = alc269_dac_nids,
14827 .hp_nid = 0x03,
14828 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14829 .channel_mode = alc269_modes,
14830 .input_mux = &alc269_capture_source,
14831 },
14832 [ALC269_QUANTA_FL1] = {
14833 .mixers = { alc269_quanta_fl1_mixer },
14834 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14835 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14836 .dac_nids = alc269_dac_nids,
14837 .hp_nid = 0x03,
14838 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14839 .channel_mode = alc269_modes,
14840 .input_mux = &alc269_capture_source,
14841 .unsol_event = alc269_quanta_fl1_unsol_event,
14842 .setup = alc269_quanta_fl1_setup,
14843 .init_hook = alc269_quanta_fl1_init_hook,
14844 },
14845 [ALC269_AMIC] = {
14846 .mixers = { alc269_laptop_mixer },
14847 .cap_mixer = alc269_laptop_analog_capture_mixer,
14848 .init_verbs = { alc269_init_verbs,
14849 alc269_laptop_amic_init_verbs },
14850 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14851 .dac_nids = alc269_dac_nids,
14852 .hp_nid = 0x03,
14853 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14854 .channel_mode = alc269_modes,
14855 .unsol_event = alc269_laptop_unsol_event,
14856 .setup = alc269_laptop_amic_setup,
14857 .init_hook = alc269_laptop_inithook,
14858 },
14859 [ALC269_DMIC] = {
14860 .mixers = { alc269_laptop_mixer },
14861 .cap_mixer = alc269_laptop_digital_capture_mixer,
14862 .init_verbs = { alc269_init_verbs,
14863 alc269_laptop_dmic_init_verbs },
14864 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14865 .dac_nids = alc269_dac_nids,
14866 .hp_nid = 0x03,
14867 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14868 .channel_mode = alc269_modes,
14869 .unsol_event = alc269_laptop_unsol_event,
14870 .setup = alc269_laptop_dmic_setup,
14871 .init_hook = alc269_laptop_inithook,
14872 },
14873 [ALC269VB_AMIC] = {
14874 .mixers = { alc269vb_laptop_mixer },
14875 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14876 .init_verbs = { alc269vb_init_verbs,
14877 alc269vb_laptop_amic_init_verbs },
14878 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14879 .dac_nids = alc269_dac_nids,
14880 .hp_nid = 0x03,
14881 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14882 .channel_mode = alc269_modes,
14883 .unsol_event = alc269_laptop_unsol_event,
14884 .setup = alc269vb_laptop_amic_setup,
14885 .init_hook = alc269_laptop_inithook,
14886 },
14887 [ALC269VB_DMIC] = {
14888 .mixers = { alc269vb_laptop_mixer },
14889 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14890 .init_verbs = { alc269vb_init_verbs,
14891 alc269vb_laptop_dmic_init_verbs },
14892 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14893 .dac_nids = alc269_dac_nids,
14894 .hp_nid = 0x03,
14895 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14896 .channel_mode = alc269_modes,
14897 .unsol_event = alc269_laptop_unsol_event,
14898 .setup = alc269vb_laptop_dmic_setup,
14899 .init_hook = alc269_laptop_inithook,
14900 },
14901 [ALC269_FUJITSU] = {
14902 .mixers = { alc269_fujitsu_mixer },
14903 .cap_mixer = alc269_laptop_digital_capture_mixer,
14904 .init_verbs = { alc269_init_verbs,
14905 alc269_laptop_dmic_init_verbs },
14906 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14907 .dac_nids = alc269_dac_nids,
14908 .hp_nid = 0x03,
14909 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14910 .channel_mode = alc269_modes,
14911 .unsol_event = alc269_laptop_unsol_event,
14912 .setup = alc269_laptop_dmic_setup,
14913 .init_hook = alc269_laptop_inithook,
14914 },
14915 [ALC269_LIFEBOOK] = {
14916 .mixers = { alc269_lifebook_mixer },
14917 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14918 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14919 .dac_nids = alc269_dac_nids,
14920 .hp_nid = 0x03,
14921 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14922 .channel_mode = alc269_modes,
14923 .input_mux = &alc269_capture_source,
14924 .unsol_event = alc269_lifebook_unsol_event,
14925 .init_hook = alc269_lifebook_init_hook,
14926 },
14927 [ALC271_ACER] = {
14928 .mixers = { alc269_asus_mixer },
14929 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14930 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14931 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14932 .dac_nids = alc269_dac_nids,
14933 .adc_nids = alc262_dmic_adc_nids,
14934 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14935 .capsrc_nids = alc262_dmic_capsrc_nids,
14936 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14937 .channel_mode = alc269_modes,
14938 .input_mux = &alc269_capture_source,
14939 .dig_out_nid = ALC880_DIGOUT_NID,
14940 .unsol_event = alc_sku_unsol_event,
14941 .setup = alc269vb_laptop_dmic_setup,
14942 .init_hook = alc_inithook,
14943 },
14944 };
14945
14946 static int alc269_fill_coef(struct hda_codec *codec)
14947 {
14948 int val;
14949
14950 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
14951 alc_write_coef_idx(codec, 0xf, 0x960b);
14952 alc_write_coef_idx(codec, 0xe, 0x8817);
14953 }
14954
14955 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
14956 alc_write_coef_idx(codec, 0xf, 0x960b);
14957 alc_write_coef_idx(codec, 0xe, 0x8814);
14958 }
14959
14960 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14961 val = alc_read_coef_idx(codec, 0x04);
14962 /* Power up output pin */
14963 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14964 }
14965
14966 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14967 val = alc_read_coef_idx(codec, 0xd);
14968 if ((val & 0x0c00) >> 10 != 0x1) {
14969 /* Capless ramp up clock control */
14970 alc_write_coef_idx(codec, 0xd, val | 1<<10);
14971 }
14972 val = alc_read_coef_idx(codec, 0x17);
14973 if ((val & 0x01c0) >> 6 != 0x4) {
14974 /* Class D power on reset */
14975 alc_write_coef_idx(codec, 0x17, val | 1<<7);
14976 }
14977 }
14978 return 0;
14979 }
14980
14981 static int patch_alc269(struct hda_codec *codec)
14982 {
14983 struct alc_spec *spec;
14984 int board_config;
14985 int err;
14986
14987 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14988 if (spec == NULL)
14989 return -ENOMEM;
14990
14991 codec->spec = spec;
14992
14993 alc_auto_parse_customize_define(codec);
14994
14995 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14996 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14997 spec->cdefine.platform_type == 1) {
14998 alc_codec_rename(codec, "ALC271X");
14999 spec->codec_variant = ALC269_TYPE_ALC271X;
15000 } else {
15001 alc_codec_rename(codec, "ALC259");
15002 spec->codec_variant = ALC269_TYPE_ALC259;
15003 }
15004 } else
15005 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15006
15007 alc269_fill_coef(codec);
15008
15009 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15010 alc269_models,
15011 alc269_cfg_tbl);
15012
15013 if (board_config < 0) {
15014 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15015 codec->chip_name);
15016 board_config = ALC269_AUTO;
15017 }
15018
15019 if (board_config == ALC269_AUTO)
15020 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
15021
15022 if (board_config == ALC269_AUTO) {
15023 /* automatic parse from the BIOS config */
15024 err = alc269_parse_auto_config(codec);
15025 if (err < 0) {
15026 alc_free(codec);
15027 return err;
15028 } else if (!err) {
15029 printk(KERN_INFO
15030 "hda_codec: Cannot set up configuration "
15031 "from BIOS. Using base mode...\n");
15032 board_config = ALC269_BASIC;
15033 }
15034 }
15035
15036 if (has_cdefine_beep(codec)) {
15037 err = snd_hda_attach_beep_device(codec, 0x1);
15038 if (err < 0) {
15039 alc_free(codec);
15040 return err;
15041 }
15042 }
15043
15044 if (board_config != ALC269_AUTO)
15045 setup_preset(codec, &alc269_presets[board_config]);
15046
15047 if (board_config == ALC269_QUANTA_FL1) {
15048 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15049 * fix the sample rate of analog I/O to 44.1kHz
15050 */
15051 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15052 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15053 } else if (spec->dual_adc_switch) {
15054 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15055 /* switch ADC dynamically */
15056 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15057 } else {
15058 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15059 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15060 }
15061 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15062 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15063
15064 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15065 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
15066 spec->adc_nids = alc269_adc_nids;
15067 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15068 spec->capsrc_nids = alc269_capsrc_nids;
15069 } else {
15070 spec->adc_nids = alc269vb_adc_nids;
15071 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15072 spec->capsrc_nids = alc269vb_capsrc_nids;
15073 }
15074 }
15075
15076 if (!spec->cap_mixer)
15077 set_capture_mixer(codec);
15078 if (has_cdefine_beep(codec))
15079 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15080
15081 if (board_config == ALC269_AUTO)
15082 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
15083
15084 spec->vmaster_nid = 0x02;
15085
15086 codec->patch_ops = alc_patch_ops;
15087 #ifdef CONFIG_SND_HDA_POWER_SAVE
15088 codec->patch_ops.suspend = alc269_suspend;
15089 #endif
15090 #ifdef SND_HDA_NEEDS_RESUME
15091 codec->patch_ops.resume = alc269_resume;
15092 #endif
15093 if (board_config == ALC269_AUTO)
15094 spec->init_hook = alc269_auto_init;
15095 #ifdef CONFIG_SND_HDA_POWER_SAVE
15096 if (!spec->loopback.amplist)
15097 spec->loopback.amplist = alc269_loopbacks;
15098 if (alc269_mic2_for_mute_led(codec))
15099 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15100 #endif
15101
15102 return 0;
15103 }
15104
15105 /*
15106 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15107 */
15108
15109 /*
15110 * set the path ways for 2 channel output
15111 * need to set the codec line out and mic 1 pin widgets to inputs
15112 */
15113 static struct hda_verb alc861_threestack_ch2_init[] = {
15114 /* set pin widget 1Ah (line in) for input */
15115 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15116 /* set pin widget 18h (mic1/2) for input, for mic also enable
15117 * the vref
15118 */
15119 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15120
15121 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15122 #if 0
15123 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15124 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15125 #endif
15126 { } /* end */
15127 };
15128 /*
15129 * 6ch mode
15130 * need to set the codec line out and mic 1 pin widgets to outputs
15131 */
15132 static struct hda_verb alc861_threestack_ch6_init[] = {
15133 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15134 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15135 /* set pin widget 18h (mic1) for output (CLFE)*/
15136 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15137
15138 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15139 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15140
15141 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15142 #if 0
15143 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15144 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15145 #endif
15146 { } /* end */
15147 };
15148
15149 static struct hda_channel_mode alc861_threestack_modes[2] = {
15150 { 2, alc861_threestack_ch2_init },
15151 { 6, alc861_threestack_ch6_init },
15152 };
15153 /* Set mic1 as input and unmute the mixer */
15154 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15155 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15156 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15157 { } /* end */
15158 };
15159 /* Set mic1 as output and mute mixer */
15160 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15161 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15162 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15163 { } /* end */
15164 };
15165
15166 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15167 { 2, alc861_uniwill_m31_ch2_init },
15168 { 4, alc861_uniwill_m31_ch4_init },
15169 };
15170
15171 /* Set mic1 and line-in as input and unmute the mixer */
15172 static struct hda_verb alc861_asus_ch2_init[] = {
15173 /* set pin widget 1Ah (line in) for input */
15174 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15175 /* set pin widget 18h (mic1/2) for input, for mic also enable
15176 * the vref
15177 */
15178 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15179
15180 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15181 #if 0
15182 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15183 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15184 #endif
15185 { } /* end */
15186 };
15187 /* Set mic1 nad line-in as output and mute mixer */
15188 static struct hda_verb alc861_asus_ch6_init[] = {
15189 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15190 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15191 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15192 /* set pin widget 18h (mic1) for output (CLFE)*/
15193 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15194 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15195 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15196 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15197
15198 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15199 #if 0
15200 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15201 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15202 #endif
15203 { } /* end */
15204 };
15205
15206 static struct hda_channel_mode alc861_asus_modes[2] = {
15207 { 2, alc861_asus_ch2_init },
15208 { 6, alc861_asus_ch6_init },
15209 };
15210
15211 /* patch-ALC861 */
15212
15213 static struct snd_kcontrol_new alc861_base_mixer[] = {
15214 /* output mixer control */
15215 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15216 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15217 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15218 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15219 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15220
15221 /*Input mixer control */
15222 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15223 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15224 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15225 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15226 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15227 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15229 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15230 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15232
15233 { } /* end */
15234 };
15235
15236 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15237 /* output mixer control */
15238 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15239 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15240 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15241 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15242 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15243
15244 /* Input mixer control */
15245 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15246 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15247 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15248 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15249 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15250 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15252 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15255
15256 {
15257 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15258 .name = "Channel Mode",
15259 .info = alc_ch_mode_info,
15260 .get = alc_ch_mode_get,
15261 .put = alc_ch_mode_put,
15262 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15263 },
15264 { } /* end */
15265 };
15266
15267 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15268 /* output mixer control */
15269 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15270 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15271 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15272
15273 { } /* end */
15274 };
15275
15276 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15277 /* output mixer control */
15278 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15279 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15280 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15281 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15282 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15283
15284 /* Input mixer control */
15285 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15286 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15287 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15288 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15289 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15290 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15291 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15292 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15293 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15294 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15295
15296 {
15297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15298 .name = "Channel Mode",
15299 .info = alc_ch_mode_info,
15300 .get = alc_ch_mode_get,
15301 .put = alc_ch_mode_put,
15302 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15303 },
15304 { } /* end */
15305 };
15306
15307 static struct snd_kcontrol_new alc861_asus_mixer[] = {
15308 /* output mixer control */
15309 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15310 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15311 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15312 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15313 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15314
15315 /* Input mixer control */
15316 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15317 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15318 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15319 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15320 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15321 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15322 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15323 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15324 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15326
15327 {
15328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15329 .name = "Channel Mode",
15330 .info = alc_ch_mode_info,
15331 .get = alc_ch_mode_get,
15332 .put = alc_ch_mode_put,
15333 .private_value = ARRAY_SIZE(alc861_asus_modes),
15334 },
15335 { }
15336 };
15337
15338 /* additional mixer */
15339 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15340 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15341 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15342 { }
15343 };
15344
15345 /*
15346 * generic initialization of ADC, input mixers and output mixers
15347 */
15348 static struct hda_verb alc861_base_init_verbs[] = {
15349 /*
15350 * Unmute ADC0 and set the default input to mic-in
15351 */
15352 /* port-A for surround (rear panel) */
15353 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15354 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15355 /* port-B for mic-in (rear panel) with vref */
15356 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15357 /* port-C for line-in (rear panel) */
15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15359 /* port-D for Front */
15360 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15361 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15362 /* port-E for HP out (front panel) */
15363 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15364 /* route front PCM to HP */
15365 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15366 /* port-F for mic-in (front panel) with vref */
15367 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15368 /* port-G for CLFE (rear panel) */
15369 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15370 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15371 /* port-H for side (rear panel) */
15372 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15373 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15374 /* CD-in */
15375 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15376 /* route front mic to ADC1*/
15377 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15378 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15379
15380 /* Unmute DAC0~3 & spdif out*/
15381 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15382 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15383 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15384 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15386
15387 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15388 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15389 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15390 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15391 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15392
15393 /* Unmute Stereo Mixer 15 */
15394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15397 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15398
15399 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15400 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15401 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15402 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15403 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15405 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15406 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15407 /* hp used DAC 3 (Front) */
15408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15409 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15410
15411 { }
15412 };
15413
15414 static struct hda_verb alc861_threestack_init_verbs[] = {
15415 /*
15416 * Unmute ADC0 and set the default input to mic-in
15417 */
15418 /* port-A for surround (rear panel) */
15419 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15420 /* port-B for mic-in (rear panel) with vref */
15421 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15422 /* port-C for line-in (rear panel) */
15423 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15424 /* port-D for Front */
15425 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15426 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15427 /* port-E for HP out (front panel) */
15428 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15429 /* route front PCM to HP */
15430 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15431 /* port-F for mic-in (front panel) with vref */
15432 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15433 /* port-G for CLFE (rear panel) */
15434 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15435 /* port-H for side (rear panel) */
15436 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15437 /* CD-in */
15438 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15439 /* route front mic to ADC1*/
15440 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15442 /* Unmute DAC0~3 & spdif out*/
15443 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15444 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15445 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15446 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15447 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15448
15449 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15450 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15451 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15452 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15453 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15454
15455 /* Unmute Stereo Mixer 15 */
15456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15457 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15458 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15459 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15460
15461 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15462 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15463 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15464 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15465 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15466 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15467 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15468 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15469 /* hp used DAC 3 (Front) */
15470 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15472 { }
15473 };
15474
15475 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15476 /*
15477 * Unmute ADC0 and set the default input to mic-in
15478 */
15479 /* port-A for surround (rear panel) */
15480 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15481 /* port-B for mic-in (rear panel) with vref */
15482 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15483 /* port-C for line-in (rear panel) */
15484 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15485 /* port-D for Front */
15486 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15487 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15488 /* port-E for HP out (front panel) */
15489 /* this has to be set to VREF80 */
15490 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15491 /* route front PCM to HP */
15492 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15493 /* port-F for mic-in (front panel) with vref */
15494 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15495 /* port-G for CLFE (rear panel) */
15496 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15497 /* port-H for side (rear panel) */
15498 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15499 /* CD-in */
15500 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15501 /* route front mic to ADC1*/
15502 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15504 /* Unmute DAC0~3 & spdif out*/
15505 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15506 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15507 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15508 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15510
15511 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15512 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15513 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15514 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15515 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15516
15517 /* Unmute Stereo Mixer 15 */
15518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15519 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15521 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15522
15523 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15524 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15525 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15526 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15528 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15530 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15531 /* hp used DAC 3 (Front) */
15532 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15533 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15534 { }
15535 };
15536
15537 static struct hda_verb alc861_asus_init_verbs[] = {
15538 /*
15539 * Unmute ADC0 and set the default input to mic-in
15540 */
15541 /* port-A for surround (rear panel)
15542 * according to codec#0 this is the HP jack
15543 */
15544 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15545 /* route front PCM to HP */
15546 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15547 /* port-B for mic-in (rear panel) with vref */
15548 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15549 /* port-C for line-in (rear panel) */
15550 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15551 /* port-D for Front */
15552 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15553 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15554 /* port-E for HP out (front panel) */
15555 /* this has to be set to VREF80 */
15556 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15557 /* route front PCM to HP */
15558 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15559 /* port-F for mic-in (front panel) with vref */
15560 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15561 /* port-G for CLFE (rear panel) */
15562 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15563 /* port-H for side (rear panel) */
15564 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15565 /* CD-in */
15566 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15567 /* route front mic to ADC1*/
15568 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15570 /* Unmute DAC0~3 & spdif out*/
15571 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15572 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15573 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15574 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15576 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15577 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15578 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15579 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15580 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15581
15582 /* Unmute Stereo Mixer 15 */
15583 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15584 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15585 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15587
15588 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15589 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15590 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15591 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15592 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15593 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15594 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15595 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15596 /* hp used DAC 3 (Front) */
15597 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15599 { }
15600 };
15601
15602 /* additional init verbs for ASUS laptops */
15603 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15604 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15605 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15606 { }
15607 };
15608
15609 /*
15610 * generic initialization of ADC, input mixers and output mixers
15611 */
15612 static struct hda_verb alc861_auto_init_verbs[] = {
15613 /*
15614 * Unmute ADC0 and set the default input to mic-in
15615 */
15616 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15618
15619 /* Unmute DAC0~3 & spdif out*/
15620 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15621 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15622 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15623 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15625
15626 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15627 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15628 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15629 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15630 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15631
15632 /* Unmute Stereo Mixer 15 */
15633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15635 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15636 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15637
15638 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15639 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15640 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15641 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15645 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15646
15647 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15648 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15649 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15650 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15651 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15652 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15653 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15654 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15655
15656 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15657
15658 { }
15659 };
15660
15661 static struct hda_verb alc861_toshiba_init_verbs[] = {
15662 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15663
15664 { }
15665 };
15666
15667 /* toggle speaker-output according to the hp-jack state */
15668 static void alc861_toshiba_automute(struct hda_codec *codec)
15669 {
15670 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15671
15672 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15673 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15674 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15675 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15676 }
15677
15678 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15679 unsigned int res)
15680 {
15681 if ((res >> 26) == ALC880_HP_EVENT)
15682 alc861_toshiba_automute(codec);
15683 }
15684
15685 /* pcm configuration: identical with ALC880 */
15686 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15687 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15688 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15689 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15690
15691
15692 #define ALC861_DIGOUT_NID 0x07
15693
15694 static struct hda_channel_mode alc861_8ch_modes[1] = {
15695 { 8, NULL }
15696 };
15697
15698 static hda_nid_t alc861_dac_nids[4] = {
15699 /* front, surround, clfe, side */
15700 0x03, 0x06, 0x05, 0x04
15701 };
15702
15703 static hda_nid_t alc660_dac_nids[3] = {
15704 /* front, clfe, surround */
15705 0x03, 0x05, 0x06
15706 };
15707
15708 static hda_nid_t alc861_adc_nids[1] = {
15709 /* ADC0-2 */
15710 0x08,
15711 };
15712
15713 static struct hda_input_mux alc861_capture_source = {
15714 .num_items = 5,
15715 .items = {
15716 { "Mic", 0x0 },
15717 { "Front Mic", 0x3 },
15718 { "Line", 0x1 },
15719 { "CD", 0x4 },
15720 { "Mixer", 0x5 },
15721 },
15722 };
15723
15724 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15725 {
15726 struct alc_spec *spec = codec->spec;
15727 hda_nid_t mix, srcs[5];
15728 int i, j, num;
15729
15730 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15731 return 0;
15732 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15733 if (num < 0)
15734 return 0;
15735 for (i = 0; i < num; i++) {
15736 unsigned int type;
15737 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15738 if (type != AC_WID_AUD_OUT)
15739 continue;
15740 for (j = 0; j < spec->multiout.num_dacs; j++)
15741 if (spec->multiout.dac_nids[j] == srcs[i])
15742 break;
15743 if (j >= spec->multiout.num_dacs)
15744 return srcs[i];
15745 }
15746 return 0;
15747 }
15748
15749 /* fill in the dac_nids table from the parsed pin configuration */
15750 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15751 const struct auto_pin_cfg *cfg)
15752 {
15753 struct alc_spec *spec = codec->spec;
15754 int i;
15755 hda_nid_t nid, dac;
15756
15757 spec->multiout.dac_nids = spec->private_dac_nids;
15758 for (i = 0; i < cfg->line_outs; i++) {
15759 nid = cfg->line_out_pins[i];
15760 dac = alc861_look_for_dac(codec, nid);
15761 if (!dac)
15762 continue;
15763 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
15764 }
15765 return 0;
15766 }
15767
15768 static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15769 hda_nid_t nid, unsigned int chs)
15770 {
15771 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
15772 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15773 }
15774
15775 /* add playback controls from the parsed DAC table */
15776 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15777 const struct auto_pin_cfg *cfg)
15778 {
15779 struct alc_spec *spec = codec->spec;
15780 static const char *chname[4] = {
15781 "Front", "Surround", NULL /*CLFE*/, "Side"
15782 };
15783 hda_nid_t nid;
15784 int i, err;
15785
15786 if (cfg->line_outs == 1) {
15787 const char *pfx = NULL;
15788 if (!cfg->hp_outs)
15789 pfx = "Master";
15790 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15791 pfx = "Speaker";
15792 if (pfx) {
15793 nid = spec->multiout.dac_nids[0];
15794 return alc861_create_out_sw(codec, pfx, nid, 3);
15795 }
15796 }
15797
15798 for (i = 0; i < cfg->line_outs; i++) {
15799 nid = spec->multiout.dac_nids[i];
15800 if (!nid)
15801 continue;
15802 if (i == 2) {
15803 /* Center/LFE */
15804 err = alc861_create_out_sw(codec, "Center", nid, 1);
15805 if (err < 0)
15806 return err;
15807 err = alc861_create_out_sw(codec, "LFE", nid, 2);
15808 if (err < 0)
15809 return err;
15810 } else {
15811 err = alc861_create_out_sw(codec, chname[i], nid, 3);
15812 if (err < 0)
15813 return err;
15814 }
15815 }
15816 return 0;
15817 }
15818
15819 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
15820 {
15821 struct alc_spec *spec = codec->spec;
15822 int err;
15823 hda_nid_t nid;
15824
15825 if (!pin)
15826 return 0;
15827
15828 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
15829 nid = alc861_look_for_dac(codec, pin);
15830 if (nid) {
15831 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15832 if (err < 0)
15833 return err;
15834 spec->multiout.hp_nid = nid;
15835 }
15836 }
15837 return 0;
15838 }
15839
15840 /* create playback/capture controls for input pins */
15841 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
15842 const struct auto_pin_cfg *cfg)
15843 {
15844 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
15845 }
15846
15847 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15848 hda_nid_t nid,
15849 int pin_type, hda_nid_t dac)
15850 {
15851 hda_nid_t mix, srcs[5];
15852 int i, num;
15853
15854 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15855 pin_type);
15856 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15857 AMP_OUT_UNMUTE);
15858 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15859 return;
15860 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15861 if (num < 0)
15862 return;
15863 for (i = 0; i < num; i++) {
15864 unsigned int mute;
15865 if (srcs[i] == dac || srcs[i] == 0x15)
15866 mute = AMP_IN_UNMUTE(i);
15867 else
15868 mute = AMP_IN_MUTE(i);
15869 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15870 mute);
15871 }
15872 }
15873
15874 static void alc861_auto_init_multi_out(struct hda_codec *codec)
15875 {
15876 struct alc_spec *spec = codec->spec;
15877 int i;
15878
15879 for (i = 0; i < spec->autocfg.line_outs; i++) {
15880 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15881 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15882 if (nid)
15883 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
15884 spec->multiout.dac_nids[i]);
15885 }
15886 }
15887
15888 static void alc861_auto_init_hp_out(struct hda_codec *codec)
15889 {
15890 struct alc_spec *spec = codec->spec;
15891
15892 if (spec->autocfg.hp_outs)
15893 alc861_auto_set_output_and_unmute(codec,
15894 spec->autocfg.hp_pins[0],
15895 PIN_HP,
15896 spec->multiout.hp_nid);
15897 if (spec->autocfg.speaker_outs)
15898 alc861_auto_set_output_and_unmute(codec,
15899 spec->autocfg.speaker_pins[0],
15900 PIN_OUT,
15901 spec->multiout.dac_nids[0]);
15902 }
15903
15904 static void alc861_auto_init_analog_input(struct hda_codec *codec)
15905 {
15906 struct alc_spec *spec = codec->spec;
15907 struct auto_pin_cfg *cfg = &spec->autocfg;
15908 int i;
15909
15910 for (i = 0; i < cfg->num_inputs; i++) {
15911 hda_nid_t nid = cfg->inputs[i].pin;
15912 if (nid >= 0x0c && nid <= 0x11)
15913 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
15914 }
15915 }
15916
15917 /* parse the BIOS configuration and set up the alc_spec */
15918 /* return 1 if successful, 0 if the proper config is not found,
15919 * or a negative error code
15920 */
15921 static int alc861_parse_auto_config(struct hda_codec *codec)
15922 {
15923 struct alc_spec *spec = codec->spec;
15924 int err;
15925 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15926
15927 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15928 alc861_ignore);
15929 if (err < 0)
15930 return err;
15931 if (!spec->autocfg.line_outs)
15932 return 0; /* can't find valid BIOS pin config */
15933
15934 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
15935 if (err < 0)
15936 return err;
15937 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
15938 if (err < 0)
15939 return err;
15940 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
15941 if (err < 0)
15942 return err;
15943 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
15944 if (err < 0)
15945 return err;
15946
15947 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15948
15949 alc_auto_parse_digital(codec);
15950
15951 if (spec->kctls.list)
15952 add_mixer(spec, spec->kctls.list);
15953
15954 add_verb(spec, alc861_auto_init_verbs);
15955
15956 spec->num_mux_defs = 1;
15957 spec->input_mux = &spec->private_imux[0];
15958
15959 spec->adc_nids = alc861_adc_nids;
15960 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
15961 set_capture_mixer(codec);
15962
15963 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
15964
15965 return 1;
15966 }
15967
15968 /* additional initialization for auto-configuration model */
15969 static void alc861_auto_init(struct hda_codec *codec)
15970 {
15971 struct alc_spec *spec = codec->spec;
15972 alc861_auto_init_multi_out(codec);
15973 alc861_auto_init_hp_out(codec);
15974 alc861_auto_init_analog_input(codec);
15975 alc_auto_init_digital(codec);
15976 if (spec->unsol_event)
15977 alc_inithook(codec);
15978 }
15979
15980 #ifdef CONFIG_SND_HDA_POWER_SAVE
15981 static struct hda_amp_list alc861_loopbacks[] = {
15982 { 0x15, HDA_INPUT, 0 },
15983 { 0x15, HDA_INPUT, 1 },
15984 { 0x15, HDA_INPUT, 2 },
15985 { 0x15, HDA_INPUT, 3 },
15986 { } /* end */
15987 };
15988 #endif
15989
15990
15991 /*
15992 * configuration and preset
15993 */
15994 static const char *alc861_models[ALC861_MODEL_LAST] = {
15995 [ALC861_3ST] = "3stack",
15996 [ALC660_3ST] = "3stack-660",
15997 [ALC861_3ST_DIG] = "3stack-dig",
15998 [ALC861_6ST_DIG] = "6stack-dig",
15999 [ALC861_UNIWILL_M31] = "uniwill-m31",
16000 [ALC861_TOSHIBA] = "toshiba",
16001 [ALC861_ASUS] = "asus",
16002 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16003 [ALC861_AUTO] = "auto",
16004 };
16005
16006 static struct snd_pci_quirk alc861_cfg_tbl[] = {
16007 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16008 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16009 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16010 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16011 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16012 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16013 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16014 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16015 * Any other models that need this preset?
16016 */
16017 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16018 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16019 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16020 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16021 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16022 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16023 /* FIXME: the below seems conflict */
16024 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16025 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16026 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16027 {}
16028 };
16029
16030 static struct alc_config_preset alc861_presets[] = {
16031 [ALC861_3ST] = {
16032 .mixers = { alc861_3ST_mixer },
16033 .init_verbs = { alc861_threestack_init_verbs },
16034 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16035 .dac_nids = alc861_dac_nids,
16036 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16037 .channel_mode = alc861_threestack_modes,
16038 .need_dac_fix = 1,
16039 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16040 .adc_nids = alc861_adc_nids,
16041 .input_mux = &alc861_capture_source,
16042 },
16043 [ALC861_3ST_DIG] = {
16044 .mixers = { alc861_base_mixer },
16045 .init_verbs = { alc861_threestack_init_verbs },
16046 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16047 .dac_nids = alc861_dac_nids,
16048 .dig_out_nid = ALC861_DIGOUT_NID,
16049 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16050 .channel_mode = alc861_threestack_modes,
16051 .need_dac_fix = 1,
16052 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16053 .adc_nids = alc861_adc_nids,
16054 .input_mux = &alc861_capture_source,
16055 },
16056 [ALC861_6ST_DIG] = {
16057 .mixers = { alc861_base_mixer },
16058 .init_verbs = { alc861_base_init_verbs },
16059 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16060 .dac_nids = alc861_dac_nids,
16061 .dig_out_nid = ALC861_DIGOUT_NID,
16062 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16063 .channel_mode = alc861_8ch_modes,
16064 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16065 .adc_nids = alc861_adc_nids,
16066 .input_mux = &alc861_capture_source,
16067 },
16068 [ALC660_3ST] = {
16069 .mixers = { alc861_3ST_mixer },
16070 .init_verbs = { alc861_threestack_init_verbs },
16071 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16072 .dac_nids = alc660_dac_nids,
16073 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16074 .channel_mode = alc861_threestack_modes,
16075 .need_dac_fix = 1,
16076 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16077 .adc_nids = alc861_adc_nids,
16078 .input_mux = &alc861_capture_source,
16079 },
16080 [ALC861_UNIWILL_M31] = {
16081 .mixers = { alc861_uniwill_m31_mixer },
16082 .init_verbs = { alc861_uniwill_m31_init_verbs },
16083 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16084 .dac_nids = alc861_dac_nids,
16085 .dig_out_nid = ALC861_DIGOUT_NID,
16086 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16087 .channel_mode = alc861_uniwill_m31_modes,
16088 .need_dac_fix = 1,
16089 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16090 .adc_nids = alc861_adc_nids,
16091 .input_mux = &alc861_capture_source,
16092 },
16093 [ALC861_TOSHIBA] = {
16094 .mixers = { alc861_toshiba_mixer },
16095 .init_verbs = { alc861_base_init_verbs,
16096 alc861_toshiba_init_verbs },
16097 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16098 .dac_nids = alc861_dac_nids,
16099 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16100 .channel_mode = alc883_3ST_2ch_modes,
16101 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16102 .adc_nids = alc861_adc_nids,
16103 .input_mux = &alc861_capture_source,
16104 .unsol_event = alc861_toshiba_unsol_event,
16105 .init_hook = alc861_toshiba_automute,
16106 },
16107 [ALC861_ASUS] = {
16108 .mixers = { alc861_asus_mixer },
16109 .init_verbs = { alc861_asus_init_verbs },
16110 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16111 .dac_nids = alc861_dac_nids,
16112 .dig_out_nid = ALC861_DIGOUT_NID,
16113 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16114 .channel_mode = alc861_asus_modes,
16115 .need_dac_fix = 1,
16116 .hp_nid = 0x06,
16117 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16118 .adc_nids = alc861_adc_nids,
16119 .input_mux = &alc861_capture_source,
16120 },
16121 [ALC861_ASUS_LAPTOP] = {
16122 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16123 .init_verbs = { alc861_asus_init_verbs,
16124 alc861_asus_laptop_init_verbs },
16125 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16126 .dac_nids = alc861_dac_nids,
16127 .dig_out_nid = ALC861_DIGOUT_NID,
16128 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16129 .channel_mode = alc883_3ST_2ch_modes,
16130 .need_dac_fix = 1,
16131 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16132 .adc_nids = alc861_adc_nids,
16133 .input_mux = &alc861_capture_source,
16134 },
16135 };
16136
16137 /* Pin config fixes */
16138 enum {
16139 PINFIX_FSC_AMILO_PI1505,
16140 };
16141
16142 static const struct alc_fixup alc861_fixups[] = {
16143 [PINFIX_FSC_AMILO_PI1505] = {
16144 .pins = (const struct alc_pincfg[]) {
16145 { 0x0b, 0x0221101f }, /* HP */
16146 { 0x0f, 0x90170310 }, /* speaker */
16147 { }
16148 }
16149 },
16150 };
16151
16152 static struct snd_pci_quirk alc861_fixup_tbl[] = {
16153 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16154 {}
16155 };
16156
16157 static int patch_alc861(struct hda_codec *codec)
16158 {
16159 struct alc_spec *spec;
16160 int board_config;
16161 int err;
16162
16163 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16164 if (spec == NULL)
16165 return -ENOMEM;
16166
16167 codec->spec = spec;
16168
16169 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16170 alc861_models,
16171 alc861_cfg_tbl);
16172
16173 if (board_config < 0) {
16174 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16175 codec->chip_name);
16176 board_config = ALC861_AUTO;
16177 }
16178
16179 if (board_config == ALC861_AUTO)
16180 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
16181
16182 if (board_config == ALC861_AUTO) {
16183 /* automatic parse from the BIOS config */
16184 err = alc861_parse_auto_config(codec);
16185 if (err < 0) {
16186 alc_free(codec);
16187 return err;
16188 } else if (!err) {
16189 printk(KERN_INFO
16190 "hda_codec: Cannot set up configuration "
16191 "from BIOS. Using base mode...\n");
16192 board_config = ALC861_3ST_DIG;
16193 }
16194 }
16195
16196 err = snd_hda_attach_beep_device(codec, 0x23);
16197 if (err < 0) {
16198 alc_free(codec);
16199 return err;
16200 }
16201
16202 if (board_config != ALC861_AUTO)
16203 setup_preset(codec, &alc861_presets[board_config]);
16204
16205 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16206 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16207
16208 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16209 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16210
16211 if (!spec->cap_mixer)
16212 set_capture_mixer(codec);
16213 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16214
16215 spec->vmaster_nid = 0x03;
16216
16217 if (board_config == ALC861_AUTO)
16218 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
16219
16220 codec->patch_ops = alc_patch_ops;
16221 if (board_config == ALC861_AUTO) {
16222 spec->init_hook = alc861_auto_init;
16223 #ifdef CONFIG_SND_HDA_POWER_SAVE
16224 spec->power_hook = alc_power_eapd;
16225 #endif
16226 }
16227 #ifdef CONFIG_SND_HDA_POWER_SAVE
16228 if (!spec->loopback.amplist)
16229 spec->loopback.amplist = alc861_loopbacks;
16230 #endif
16231
16232 return 0;
16233 }
16234
16235 /*
16236 * ALC861-VD support
16237 *
16238 * Based on ALC882
16239 *
16240 * In addition, an independent DAC
16241 */
16242 #define ALC861VD_DIGOUT_NID 0x06
16243
16244 static hda_nid_t alc861vd_dac_nids[4] = {
16245 /* front, surr, clfe, side surr */
16246 0x02, 0x03, 0x04, 0x05
16247 };
16248
16249 /* dac_nids for ALC660vd are in a different order - according to
16250 * Realtek's driver.
16251 * This should probably result in a different mixer for 6stack models
16252 * of ALC660vd codecs, but for now there is only 3stack mixer
16253 * - and it is the same as in 861vd.
16254 * adc_nids in ALC660vd are (is) the same as in 861vd
16255 */
16256 static hda_nid_t alc660vd_dac_nids[3] = {
16257 /* front, rear, clfe, rear_surr */
16258 0x02, 0x04, 0x03
16259 };
16260
16261 static hda_nid_t alc861vd_adc_nids[1] = {
16262 /* ADC0 */
16263 0x09,
16264 };
16265
16266 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16267
16268 /* input MUX */
16269 /* FIXME: should be a matrix-type input source selection */
16270 static struct hda_input_mux alc861vd_capture_source = {
16271 .num_items = 4,
16272 .items = {
16273 { "Mic", 0x0 },
16274 { "Front Mic", 0x1 },
16275 { "Line", 0x2 },
16276 { "CD", 0x4 },
16277 },
16278 };
16279
16280 static struct hda_input_mux alc861vd_dallas_capture_source = {
16281 .num_items = 2,
16282 .items = {
16283 { "Ext Mic", 0x0 },
16284 { "Int Mic", 0x1 },
16285 },
16286 };
16287
16288 static struct hda_input_mux alc861vd_hp_capture_source = {
16289 .num_items = 2,
16290 .items = {
16291 { "Front Mic", 0x0 },
16292 { "ATAPI Mic", 0x1 },
16293 },
16294 };
16295
16296 /*
16297 * 2ch mode
16298 */
16299 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16300 { 2, NULL }
16301 };
16302
16303 /*
16304 * 6ch mode
16305 */
16306 static struct hda_verb alc861vd_6stack_ch6_init[] = {
16307 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16308 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16309 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16310 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16311 { } /* end */
16312 };
16313
16314 /*
16315 * 8ch mode
16316 */
16317 static struct hda_verb alc861vd_6stack_ch8_init[] = {
16318 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16319 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16320 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16321 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16322 { } /* end */
16323 };
16324
16325 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16326 { 6, alc861vd_6stack_ch6_init },
16327 { 8, alc861vd_6stack_ch8_init },
16328 };
16329
16330 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16331 {
16332 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16333 .name = "Channel Mode",
16334 .info = alc_ch_mode_info,
16335 .get = alc_ch_mode_get,
16336 .put = alc_ch_mode_put,
16337 },
16338 { } /* end */
16339 };
16340
16341 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16342 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16343 */
16344 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16345 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16346 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16347
16348 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16349 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16350
16351 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16352 HDA_OUTPUT),
16353 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16354 HDA_OUTPUT),
16355 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16356 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16357
16358 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16359 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16360
16361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16362
16363 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16366
16367 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16368 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16369 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16370
16371 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16372 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16373
16374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16376
16377 { } /* end */
16378 };
16379
16380 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16381 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16382 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16383
16384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16385
16386 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16389
16390 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16391 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16392 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16393
16394 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16395 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16396
16397 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16398 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16399
16400 { } /* end */
16401 };
16402
16403 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16404 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16405 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16406 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16407
16408 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16409
16410 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16411 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16412 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16413
16414 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16415 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16416 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16417
16418 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16419 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16420
16421 { } /* end */
16422 };
16423
16424 /* Pin assignment: Speaker=0x14, HP = 0x15,
16425 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16426 */
16427 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16428 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16429 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16430 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16431 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16432 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16433 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16434 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16435 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16436 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16437 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16438 { } /* end */
16439 };
16440
16441 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16442 * Front Mic=0x18, ATAPI Mic = 0x19,
16443 */
16444 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16445 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16446 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16448 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16451 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16452 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16453
16454 { } /* end */
16455 };
16456
16457 /*
16458 * generic initialization of ADC, input mixers and output mixers
16459 */
16460 static struct hda_verb alc861vd_volume_init_verbs[] = {
16461 /*
16462 * Unmute ADC0 and set the default input to mic-in
16463 */
16464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16465 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16466
16467 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16468 * the analog-loopback mixer widget
16469 */
16470 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16471 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16472 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16473 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16474 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16475 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16476
16477 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16482
16483 /*
16484 * Set up output mixers (0x02 - 0x05)
16485 */
16486 /* set vol=0 to output mixers */
16487 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16488 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16489 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16490 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16491
16492 /* set up input amps for analog loopback */
16493 /* Amp Indices: DAC = 0, mixer = 1 */
16494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16495 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16496 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16497 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16498 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16501 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16502
16503 { }
16504 };
16505
16506 /*
16507 * 3-stack pin configuration:
16508 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16509 */
16510 static struct hda_verb alc861vd_3stack_init_verbs[] = {
16511 /*
16512 * Set pin mode and muting
16513 */
16514 /* set front pin widgets 0x14 for output */
16515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16516 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16517 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16518
16519 /* Mic (rear) pin: input vref at 80% */
16520 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16521 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16522 /* Front Mic pin: input vref at 80% */
16523 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16524 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16525 /* Line In pin: input */
16526 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16527 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16528 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16530 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16531 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16532 /* CD pin widget for input */
16533 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16534
16535 { }
16536 };
16537
16538 /*
16539 * 6-stack pin configuration:
16540 */
16541 static struct hda_verb alc861vd_6stack_init_verbs[] = {
16542 /*
16543 * Set pin mode and muting
16544 */
16545 /* set front pin widgets 0x14 for output */
16546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16547 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16548 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16549
16550 /* Rear Pin: output 1 (0x0d) */
16551 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16553 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16554 /* CLFE Pin: output 2 (0x0e) */
16555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16556 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16557 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16558 /* Side Pin: output 3 (0x0f) */
16559 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16560 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16561 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16562
16563 /* Mic (rear) pin: input vref at 80% */
16564 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16565 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16566 /* Front Mic pin: input vref at 80% */
16567 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16568 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16569 /* Line In pin: input */
16570 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16571 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16572 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16573 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16574 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16575 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16576 /* CD pin widget for input */
16577 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16578
16579 { }
16580 };
16581
16582 static struct hda_verb alc861vd_eapd_verbs[] = {
16583 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16584 { }
16585 };
16586
16587 static struct hda_verb alc660vd_eapd_verbs[] = {
16588 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16589 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16590 { }
16591 };
16592
16593 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16594 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16596 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16597 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16598 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16599 {}
16600 };
16601
16602 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16603 {
16604 unsigned int present;
16605 unsigned char bits;
16606
16607 present = snd_hda_jack_detect(codec, 0x18);
16608 bits = present ? HDA_AMP_MUTE : 0;
16609
16610 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16611 HDA_AMP_MUTE, bits);
16612 }
16613
16614 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16615 {
16616 struct alc_spec *spec = codec->spec;
16617 spec->autocfg.hp_pins[0] = 0x1b;
16618 spec->autocfg.speaker_pins[0] = 0x14;
16619 }
16620
16621 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16622 {
16623 alc_automute_amp(codec);
16624 alc861vd_lenovo_mic_automute(codec);
16625 }
16626
16627 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16628 unsigned int res)
16629 {
16630 switch (res >> 26) {
16631 case ALC880_MIC_EVENT:
16632 alc861vd_lenovo_mic_automute(codec);
16633 break;
16634 default:
16635 alc_automute_amp_unsol_event(codec, res);
16636 break;
16637 }
16638 }
16639
16640 static struct hda_verb alc861vd_dallas_verbs[] = {
16641 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16642 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16643 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16644 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16645
16646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16650 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16652 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16653 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16654
16655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16656 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16658 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16659 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16660 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16661 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16662 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16663
16664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16666 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16667 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16668 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16669 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16670 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16671 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16672
16673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16677
16678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16679 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16680 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16681
16682 { } /* end */
16683 };
16684
16685 /* toggle speaker-output according to the hp-jack state */
16686 static void alc861vd_dallas_setup(struct hda_codec *codec)
16687 {
16688 struct alc_spec *spec = codec->spec;
16689
16690 spec->autocfg.hp_pins[0] = 0x15;
16691 spec->autocfg.speaker_pins[0] = 0x14;
16692 }
16693
16694 #ifdef CONFIG_SND_HDA_POWER_SAVE
16695 #define alc861vd_loopbacks alc880_loopbacks
16696 #endif
16697
16698 /* pcm configuration: identical with ALC880 */
16699 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16700 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16701 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16702 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16703
16704 /*
16705 * configuration and preset
16706 */
16707 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16708 [ALC660VD_3ST] = "3stack-660",
16709 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16710 [ALC660VD_ASUS_V1S] = "asus-v1s",
16711 [ALC861VD_3ST] = "3stack",
16712 [ALC861VD_3ST_DIG] = "3stack-digout",
16713 [ALC861VD_6ST_DIG] = "6stack-digout",
16714 [ALC861VD_LENOVO] = "lenovo",
16715 [ALC861VD_DALLAS] = "dallas",
16716 [ALC861VD_HP] = "hp",
16717 [ALC861VD_AUTO] = "auto",
16718 };
16719
16720 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16721 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16722 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16723 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16724 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16725 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16726 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16727 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16728 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16729 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16730 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16731 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16732 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16733 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16734 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16735 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16736 {}
16737 };
16738
16739 static struct alc_config_preset alc861vd_presets[] = {
16740 [ALC660VD_3ST] = {
16741 .mixers = { alc861vd_3st_mixer },
16742 .init_verbs = { alc861vd_volume_init_verbs,
16743 alc861vd_3stack_init_verbs },
16744 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16745 .dac_nids = alc660vd_dac_nids,
16746 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16747 .channel_mode = alc861vd_3stack_2ch_modes,
16748 .input_mux = &alc861vd_capture_source,
16749 },
16750 [ALC660VD_3ST_DIG] = {
16751 .mixers = { alc861vd_3st_mixer },
16752 .init_verbs = { alc861vd_volume_init_verbs,
16753 alc861vd_3stack_init_verbs },
16754 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16755 .dac_nids = alc660vd_dac_nids,
16756 .dig_out_nid = ALC861VD_DIGOUT_NID,
16757 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16758 .channel_mode = alc861vd_3stack_2ch_modes,
16759 .input_mux = &alc861vd_capture_source,
16760 },
16761 [ALC861VD_3ST] = {
16762 .mixers = { alc861vd_3st_mixer },
16763 .init_verbs = { alc861vd_volume_init_verbs,
16764 alc861vd_3stack_init_verbs },
16765 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16766 .dac_nids = alc861vd_dac_nids,
16767 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16768 .channel_mode = alc861vd_3stack_2ch_modes,
16769 .input_mux = &alc861vd_capture_source,
16770 },
16771 [ALC861VD_3ST_DIG] = {
16772 .mixers = { alc861vd_3st_mixer },
16773 .init_verbs = { alc861vd_volume_init_verbs,
16774 alc861vd_3stack_init_verbs },
16775 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16776 .dac_nids = alc861vd_dac_nids,
16777 .dig_out_nid = ALC861VD_DIGOUT_NID,
16778 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16779 .channel_mode = alc861vd_3stack_2ch_modes,
16780 .input_mux = &alc861vd_capture_source,
16781 },
16782 [ALC861VD_6ST_DIG] = {
16783 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16784 .init_verbs = { alc861vd_volume_init_verbs,
16785 alc861vd_6stack_init_verbs },
16786 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16787 .dac_nids = alc861vd_dac_nids,
16788 .dig_out_nid = ALC861VD_DIGOUT_NID,
16789 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16790 .channel_mode = alc861vd_6stack_modes,
16791 .input_mux = &alc861vd_capture_source,
16792 },
16793 [ALC861VD_LENOVO] = {
16794 .mixers = { alc861vd_lenovo_mixer },
16795 .init_verbs = { alc861vd_volume_init_verbs,
16796 alc861vd_3stack_init_verbs,
16797 alc861vd_eapd_verbs,
16798 alc861vd_lenovo_unsol_verbs },
16799 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16800 .dac_nids = alc660vd_dac_nids,
16801 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16802 .channel_mode = alc861vd_3stack_2ch_modes,
16803 .input_mux = &alc861vd_capture_source,
16804 .unsol_event = alc861vd_lenovo_unsol_event,
16805 .setup = alc861vd_lenovo_setup,
16806 .init_hook = alc861vd_lenovo_init_hook,
16807 },
16808 [ALC861VD_DALLAS] = {
16809 .mixers = { alc861vd_dallas_mixer },
16810 .init_verbs = { alc861vd_dallas_verbs },
16811 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16812 .dac_nids = alc861vd_dac_nids,
16813 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16814 .channel_mode = alc861vd_3stack_2ch_modes,
16815 .input_mux = &alc861vd_dallas_capture_source,
16816 .unsol_event = alc_automute_amp_unsol_event,
16817 .setup = alc861vd_dallas_setup,
16818 .init_hook = alc_automute_amp,
16819 },
16820 [ALC861VD_HP] = {
16821 .mixers = { alc861vd_hp_mixer },
16822 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16823 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16824 .dac_nids = alc861vd_dac_nids,
16825 .dig_out_nid = ALC861VD_DIGOUT_NID,
16826 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16827 .channel_mode = alc861vd_3stack_2ch_modes,
16828 .input_mux = &alc861vd_hp_capture_source,
16829 .unsol_event = alc_automute_amp_unsol_event,
16830 .setup = alc861vd_dallas_setup,
16831 .init_hook = alc_automute_amp,
16832 },
16833 [ALC660VD_ASUS_V1S] = {
16834 .mixers = { alc861vd_lenovo_mixer },
16835 .init_verbs = { alc861vd_volume_init_verbs,
16836 alc861vd_3stack_init_verbs,
16837 alc861vd_eapd_verbs,
16838 alc861vd_lenovo_unsol_verbs },
16839 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16840 .dac_nids = alc660vd_dac_nids,
16841 .dig_out_nid = ALC861VD_DIGOUT_NID,
16842 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16843 .channel_mode = alc861vd_3stack_2ch_modes,
16844 .input_mux = &alc861vd_capture_source,
16845 .unsol_event = alc861vd_lenovo_unsol_event,
16846 .setup = alc861vd_lenovo_setup,
16847 .init_hook = alc861vd_lenovo_init_hook,
16848 },
16849 };
16850
16851 /*
16852 * BIOS auto configuration
16853 */
16854 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16855 const struct auto_pin_cfg *cfg)
16856 {
16857 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
16858 }
16859
16860
16861 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16862 hda_nid_t nid, int pin_type, int dac_idx)
16863 {
16864 alc_set_pin_output(codec, nid, pin_type);
16865 }
16866
16867 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16868 {
16869 struct alc_spec *spec = codec->spec;
16870 int i;
16871
16872 for (i = 0; i <= HDA_SIDE; i++) {
16873 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16874 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16875 if (nid)
16876 alc861vd_auto_set_output_and_unmute(codec, nid,
16877 pin_type, i);
16878 }
16879 }
16880
16881
16882 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16883 {
16884 struct alc_spec *spec = codec->spec;
16885 hda_nid_t pin;
16886
16887 pin = spec->autocfg.hp_pins[0];
16888 if (pin) /* connect to front and use dac 0 */
16889 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16890 pin = spec->autocfg.speaker_pins[0];
16891 if (pin)
16892 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16893 }
16894
16895 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16896
16897 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16898 {
16899 struct alc_spec *spec = codec->spec;
16900 struct auto_pin_cfg *cfg = &spec->autocfg;
16901 int i;
16902
16903 for (i = 0; i < cfg->num_inputs; i++) {
16904 hda_nid_t nid = cfg->inputs[i].pin;
16905 if (alc_is_input_pin(codec, nid)) {
16906 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16907 if (nid != ALC861VD_PIN_CD_NID &&
16908 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16909 snd_hda_codec_write(codec, nid, 0,
16910 AC_VERB_SET_AMP_GAIN_MUTE,
16911 AMP_OUT_MUTE);
16912 }
16913 }
16914 }
16915
16916 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
16917
16918 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16919 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16920
16921 /* add playback controls from the parsed DAC table */
16922 /* Based on ALC880 version. But ALC861VD has separate,
16923 * different NIDs for mute/unmute switch and volume control */
16924 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16925 const struct auto_pin_cfg *cfg)
16926 {
16927 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16928 hda_nid_t nid_v, nid_s;
16929 int i, err;
16930
16931 for (i = 0; i < cfg->line_outs; i++) {
16932 if (!spec->multiout.dac_nids[i])
16933 continue;
16934 nid_v = alc861vd_idx_to_mixer_vol(
16935 alc880_dac_to_idx(
16936 spec->multiout.dac_nids[i]));
16937 nid_s = alc861vd_idx_to_mixer_switch(
16938 alc880_dac_to_idx(
16939 spec->multiout.dac_nids[i]));
16940
16941 if (i == 2) {
16942 /* Center/LFE */
16943 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16944 "Center",
16945 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16946 HDA_OUTPUT));
16947 if (err < 0)
16948 return err;
16949 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16950 "LFE",
16951 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16952 HDA_OUTPUT));
16953 if (err < 0)
16954 return err;
16955 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16956 "Center",
16957 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16958 HDA_INPUT));
16959 if (err < 0)
16960 return err;
16961 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16962 "LFE",
16963 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16964 HDA_INPUT));
16965 if (err < 0)
16966 return err;
16967 } else {
16968 const char *pfx;
16969 if (cfg->line_outs == 1 &&
16970 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16971 if (!cfg->hp_pins)
16972 pfx = "Speaker";
16973 else
16974 pfx = "PCM";
16975 } else
16976 pfx = chname[i];
16977 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16978 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16979 HDA_OUTPUT));
16980 if (err < 0)
16981 return err;
16982 if (cfg->line_outs == 1 &&
16983 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16984 pfx = "Speaker";
16985 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16986 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
16987 HDA_INPUT));
16988 if (err < 0)
16989 return err;
16990 }
16991 }
16992 return 0;
16993 }
16994
16995 /* add playback controls for speaker and HP outputs */
16996 /* Based on ALC880 version. But ALC861VD has separate,
16997 * different NIDs for mute/unmute switch and volume control */
16998 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16999 hda_nid_t pin, const char *pfx)
17000 {
17001 hda_nid_t nid_v, nid_s;
17002 int err;
17003
17004 if (!pin)
17005 return 0;
17006
17007 if (alc880_is_fixed_pin(pin)) {
17008 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17009 /* specify the DAC as the extra output */
17010 if (!spec->multiout.hp_nid)
17011 spec->multiout.hp_nid = nid_v;
17012 else
17013 spec->multiout.extra_out_nid[0] = nid_v;
17014 /* control HP volume/switch on the output mixer amp */
17015 nid_v = alc861vd_idx_to_mixer_vol(
17016 alc880_fixed_pin_idx(pin));
17017 nid_s = alc861vd_idx_to_mixer_switch(
17018 alc880_fixed_pin_idx(pin));
17019
17020 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17021 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17022 if (err < 0)
17023 return err;
17024 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17025 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17026 if (err < 0)
17027 return err;
17028 } else if (alc880_is_multi_pin(pin)) {
17029 /* set manual connection */
17030 /* we have only a switch on HP-out PIN */
17031 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17032 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17033 if (err < 0)
17034 return err;
17035 }
17036 return 0;
17037 }
17038
17039 /* parse the BIOS configuration and set up the alc_spec
17040 * return 1 if successful, 0 if the proper config is not found,
17041 * or a negative error code
17042 * Based on ALC880 version - had to change it to override
17043 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17044 static int alc861vd_parse_auto_config(struct hda_codec *codec)
17045 {
17046 struct alc_spec *spec = codec->spec;
17047 int err;
17048 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17049
17050 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17051 alc861vd_ignore);
17052 if (err < 0)
17053 return err;
17054 if (!spec->autocfg.line_outs)
17055 return 0; /* can't find valid BIOS pin config */
17056
17057 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17058 if (err < 0)
17059 return err;
17060 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17061 if (err < 0)
17062 return err;
17063 err = alc861vd_auto_create_extra_out(spec,
17064 spec->autocfg.speaker_pins[0],
17065 "Speaker");
17066 if (err < 0)
17067 return err;
17068 err = alc861vd_auto_create_extra_out(spec,
17069 spec->autocfg.hp_pins[0],
17070 "Headphone");
17071 if (err < 0)
17072 return err;
17073 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17074 if (err < 0)
17075 return err;
17076
17077 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17078
17079 alc_auto_parse_digital(codec);
17080
17081 if (spec->kctls.list)
17082 add_mixer(spec, spec->kctls.list);
17083
17084 add_verb(spec, alc861vd_volume_init_verbs);
17085
17086 spec->num_mux_defs = 1;
17087 spec->input_mux = &spec->private_imux[0];
17088
17089 err = alc_auto_add_mic_boost(codec);
17090 if (err < 0)
17091 return err;
17092
17093 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17094
17095 return 1;
17096 }
17097
17098 /* additional initialization for auto-configuration model */
17099 static void alc861vd_auto_init(struct hda_codec *codec)
17100 {
17101 struct alc_spec *spec = codec->spec;
17102 alc861vd_auto_init_multi_out(codec);
17103 alc861vd_auto_init_hp_out(codec);
17104 alc861vd_auto_init_analog_input(codec);
17105 alc861vd_auto_init_input_src(codec);
17106 alc_auto_init_digital(codec);
17107 if (spec->unsol_event)
17108 alc_inithook(codec);
17109 }
17110
17111 enum {
17112 ALC660VD_FIX_ASUS_GPIO1
17113 };
17114
17115 /* reset GPIO1 */
17116 static const struct alc_fixup alc861vd_fixups[] = {
17117 [ALC660VD_FIX_ASUS_GPIO1] = {
17118 .verbs = (const struct hda_verb[]) {
17119 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17120 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17121 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17122 { }
17123 }
17124 },
17125 };
17126
17127 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17128 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17129 {}
17130 };
17131
17132 static int patch_alc861vd(struct hda_codec *codec)
17133 {
17134 struct alc_spec *spec;
17135 int err, board_config;
17136
17137 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17138 if (spec == NULL)
17139 return -ENOMEM;
17140
17141 codec->spec = spec;
17142
17143 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17144 alc861vd_models,
17145 alc861vd_cfg_tbl);
17146
17147 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17148 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17149 codec->chip_name);
17150 board_config = ALC861VD_AUTO;
17151 }
17152
17153 if (board_config == ALC861VD_AUTO)
17154 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
17155
17156 if (board_config == ALC861VD_AUTO) {
17157 /* automatic parse from the BIOS config */
17158 err = alc861vd_parse_auto_config(codec);
17159 if (err < 0) {
17160 alc_free(codec);
17161 return err;
17162 } else if (!err) {
17163 printk(KERN_INFO
17164 "hda_codec: Cannot set up configuration "
17165 "from BIOS. Using base mode...\n");
17166 board_config = ALC861VD_3ST;
17167 }
17168 }
17169
17170 err = snd_hda_attach_beep_device(codec, 0x23);
17171 if (err < 0) {
17172 alc_free(codec);
17173 return err;
17174 }
17175
17176 if (board_config != ALC861VD_AUTO)
17177 setup_preset(codec, &alc861vd_presets[board_config]);
17178
17179 if (codec->vendor_id == 0x10ec0660) {
17180 /* always turn on EAPD */
17181 add_verb(spec, alc660vd_eapd_verbs);
17182 }
17183
17184 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17185 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17186
17187 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17188 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17189
17190 if (!spec->adc_nids) {
17191 spec->adc_nids = alc861vd_adc_nids;
17192 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17193 }
17194 if (!spec->capsrc_nids)
17195 spec->capsrc_nids = alc861vd_capsrc_nids;
17196
17197 set_capture_mixer(codec);
17198 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17199
17200 spec->vmaster_nid = 0x02;
17201
17202 if (board_config == ALC861VD_AUTO)
17203 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
17204
17205 codec->patch_ops = alc_patch_ops;
17206
17207 if (board_config == ALC861VD_AUTO)
17208 spec->init_hook = alc861vd_auto_init;
17209 #ifdef CONFIG_SND_HDA_POWER_SAVE
17210 if (!spec->loopback.amplist)
17211 spec->loopback.amplist = alc861vd_loopbacks;
17212 #endif
17213
17214 return 0;
17215 }
17216
17217 /*
17218 * ALC662 support
17219 *
17220 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17221 * configuration. Each pin widget can choose any input DACs and a mixer.
17222 * Each ADC is connected from a mixer of all inputs. This makes possible
17223 * 6-channel independent captures.
17224 *
17225 * In addition, an independent DAC for the multi-playback (not used in this
17226 * driver yet).
17227 */
17228 #define ALC662_DIGOUT_NID 0x06
17229 #define ALC662_DIGIN_NID 0x0a
17230
17231 static hda_nid_t alc662_dac_nids[4] = {
17232 /* front, rear, clfe, rear_surr */
17233 0x02, 0x03, 0x04
17234 };
17235
17236 static hda_nid_t alc272_dac_nids[2] = {
17237 0x02, 0x03
17238 };
17239
17240 static hda_nid_t alc662_adc_nids[2] = {
17241 /* ADC1-2 */
17242 0x09, 0x08
17243 };
17244
17245 static hda_nid_t alc272_adc_nids[1] = {
17246 /* ADC1-2 */
17247 0x08,
17248 };
17249
17250 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17251 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17252
17253
17254 /* input MUX */
17255 /* FIXME: should be a matrix-type input source selection */
17256 static struct hda_input_mux alc662_capture_source = {
17257 .num_items = 4,
17258 .items = {
17259 { "Mic", 0x0 },
17260 { "Front Mic", 0x1 },
17261 { "Line", 0x2 },
17262 { "CD", 0x4 },
17263 },
17264 };
17265
17266 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17267 .num_items = 2,
17268 .items = {
17269 { "Mic", 0x1 },
17270 { "Line", 0x2 },
17271 },
17272 };
17273
17274 static struct hda_input_mux alc663_capture_source = {
17275 .num_items = 3,
17276 .items = {
17277 { "Mic", 0x0 },
17278 { "Front Mic", 0x1 },
17279 { "Line", 0x2 },
17280 },
17281 };
17282
17283 #if 0 /* set to 1 for testing other input sources below */
17284 static struct hda_input_mux alc272_nc10_capture_source = {
17285 .num_items = 16,
17286 .items = {
17287 { "Autoselect Mic", 0x0 },
17288 { "Internal Mic", 0x1 },
17289 { "In-0x02", 0x2 },
17290 { "In-0x03", 0x3 },
17291 { "In-0x04", 0x4 },
17292 { "In-0x05", 0x5 },
17293 { "In-0x06", 0x6 },
17294 { "In-0x07", 0x7 },
17295 { "In-0x08", 0x8 },
17296 { "In-0x09", 0x9 },
17297 { "In-0x0a", 0x0a },
17298 { "In-0x0b", 0x0b },
17299 { "In-0x0c", 0x0c },
17300 { "In-0x0d", 0x0d },
17301 { "In-0x0e", 0x0e },
17302 { "In-0x0f", 0x0f },
17303 },
17304 };
17305 #endif
17306
17307 /*
17308 * 2ch mode
17309 */
17310 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17311 { 2, NULL }
17312 };
17313
17314 /*
17315 * 2ch mode
17316 */
17317 static struct hda_verb alc662_3ST_ch2_init[] = {
17318 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17319 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17320 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17321 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17322 { } /* end */
17323 };
17324
17325 /*
17326 * 6ch mode
17327 */
17328 static struct hda_verb alc662_3ST_ch6_init[] = {
17329 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17330 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17331 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17332 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17333 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17334 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17335 { } /* end */
17336 };
17337
17338 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17339 { 2, alc662_3ST_ch2_init },
17340 { 6, alc662_3ST_ch6_init },
17341 };
17342
17343 /*
17344 * 2ch mode
17345 */
17346 static struct hda_verb alc662_sixstack_ch6_init[] = {
17347 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17348 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17349 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17350 { } /* end */
17351 };
17352
17353 /*
17354 * 6ch mode
17355 */
17356 static struct hda_verb alc662_sixstack_ch8_init[] = {
17357 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17358 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17359 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17360 { } /* end */
17361 };
17362
17363 static struct hda_channel_mode alc662_5stack_modes[2] = {
17364 { 2, alc662_sixstack_ch6_init },
17365 { 6, alc662_sixstack_ch8_init },
17366 };
17367
17368 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17369 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17370 */
17371
17372 static struct snd_kcontrol_new alc662_base_mixer[] = {
17373 /* output mixer control */
17374 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17375 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17376 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17377 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17378 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17379 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17380 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17381 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17383
17384 /*Input mixer control */
17385 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17386 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17387 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17388 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17389 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17390 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17391 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17392 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17393 { } /* end */
17394 };
17395
17396 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17397 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17398 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17401 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17402 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17403 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17408 { } /* end */
17409 };
17410
17411 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17412 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17413 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17414 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17415 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17416 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17417 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17418 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17419 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17427 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17429 { } /* end */
17430 };
17431
17432 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17433 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17434 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17435 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17436 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17438 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17439 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17442 { } /* end */
17443 };
17444
17445 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17446 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17447 ALC262_HIPPO_MASTER_SWITCH,
17448
17449 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17450 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17451 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17452
17453 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17454 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17455 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17456 { } /* end */
17457 };
17458
17459 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17460 ALC262_HIPPO_MASTER_SWITCH,
17461 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17462 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17463 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17464 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17465 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17466 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17470 { } /* end */
17471 };
17472
17473 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17474 .ops = &snd_hda_bind_vol,
17475 .values = {
17476 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17477 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17478 0
17479 },
17480 };
17481
17482 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17483 .ops = &snd_hda_bind_sw,
17484 .values = {
17485 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17486 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17487 0
17488 },
17489 };
17490
17491 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
17492 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17493 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17495 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17496 { } /* end */
17497 };
17498
17499 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17500 .ops = &snd_hda_bind_sw,
17501 .values = {
17502 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17503 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17504 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17505 0
17506 },
17507 };
17508
17509 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17510 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17511 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17513 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17514 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17515 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17516
17517 { } /* end */
17518 };
17519
17520 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17521 .ops = &snd_hda_bind_sw,
17522 .values = {
17523 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17524 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17525 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17526 0
17527 },
17528 };
17529
17530 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17531 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17532 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17535 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17536 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17537 { } /* end */
17538 };
17539
17540 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17541 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17542 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17544 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17546 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17547 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17548 { } /* end */
17549 };
17550
17551 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17552 .ops = &snd_hda_bind_vol,
17553 .values = {
17554 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17555 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17556 0
17557 },
17558 };
17559
17560 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17561 .ops = &snd_hda_bind_sw,
17562 .values = {
17563 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17564 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17565 0
17566 },
17567 };
17568
17569 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17570 HDA_BIND_VOL("Master Playback Volume",
17571 &alc663_asus_two_bind_master_vol),
17572 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17577 { } /* end */
17578 };
17579
17580 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17581 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17582 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17587 { } /* end */
17588 };
17589
17590 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17591 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17592 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17593 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17594 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17596
17597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17598 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17599 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17600 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17601 { } /* end */
17602 };
17603
17604 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17605 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17606 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17608
17609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17611 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17612 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17613 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17614 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17615 { } /* end */
17616 };
17617
17618 static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17619 .ops = &snd_hda_bind_sw,
17620 .values = {
17621 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17622 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17623 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17624 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17625 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17626 0
17627 },
17628 };
17629
17630 static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17631 .ops = &snd_hda_bind_sw,
17632 .values = {
17633 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17634 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17635 0
17636 },
17637 };
17638
17639 static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17640 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17641 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17642 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17643 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17644 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17645 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17646 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17649 { } /* end */
17650 };
17651
17652 static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17653 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17654 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17655 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17656 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17657 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17658 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17660 { } /* end */
17661 };
17662
17663
17664 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17665 {
17666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17667 .name = "Channel Mode",
17668 .info = alc_ch_mode_info,
17669 .get = alc_ch_mode_get,
17670 .put = alc_ch_mode_put,
17671 },
17672 { } /* end */
17673 };
17674
17675 static struct hda_verb alc662_init_verbs[] = {
17676 /* ADC: mute amp left and right */
17677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17678 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17679
17680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17682 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17683 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17684 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17685 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17686
17687 /* Front Pin: output 0 (0x0c) */
17688 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17689 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17690
17691 /* Rear Pin: output 1 (0x0d) */
17692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17694
17695 /* CLFE Pin: output 2 (0x0e) */
17696 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17697 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17698
17699 /* Mic (rear) pin: input vref at 80% */
17700 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17701 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17702 /* Front Mic pin: input vref at 80% */
17703 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17705 /* Line In pin: input */
17706 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17708 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17711 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17712 /* CD pin widget for input */
17713 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17714
17715 /* FIXME: use matrix-type input source selection */
17716 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17717 /* Input mixer */
17718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17720
17721 /* always trun on EAPD */
17722 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17723 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17724
17725 { }
17726 };
17727
17728 static struct hda_verb alc663_init_verbs[] = {
17729 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17730 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17731 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17732 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17733 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17734 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17735 { }
17736 };
17737
17738 static struct hda_verb alc272_init_verbs[] = {
17739 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17741 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17742 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17743 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17744 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17745 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17746 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17747 { }
17748 };
17749
17750 static struct hda_verb alc662_sue_init_verbs[] = {
17751 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17752 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17753 {}
17754 };
17755
17756 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17757 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17758 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17759 {}
17760 };
17761
17762 /* Set Unsolicited Event*/
17763 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17764 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17765 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17766 {}
17767 };
17768
17769 static struct hda_verb alc663_m51va_init_verbs[] = {
17770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17771 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17772 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17773 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17774 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17777 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17778 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17779 {}
17780 };
17781
17782 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17783 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17784 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17785 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17786 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17788 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17789 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17790 {}
17791 };
17792
17793 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17794 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17795 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17796 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17797 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17798 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17799 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17800 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17801 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17802 {}
17803 };
17804
17805 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17808 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17809 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17810 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17811 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17812 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17813 {}
17814 };
17815
17816 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17817 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17818 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17819 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17820 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17821 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17823 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17826 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17827 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17828 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17829 {}
17830 };
17831
17832 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17833 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17834 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17835 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17836 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17837 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17838 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17839 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17840 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17842 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17843 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17844 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17845 {}
17846 };
17847
17848 static struct hda_verb alc663_g71v_init_verbs[] = {
17849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17850 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17851 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17852
17853 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17854 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17855 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17856
17857 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17858 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17859 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17860 {}
17861 };
17862
17863 static struct hda_verb alc663_g50v_init_verbs[] = {
17864 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17865 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17866 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17867
17868 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17869 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17870 {}
17871 };
17872
17873 static struct hda_verb alc662_ecs_init_verbs[] = {
17874 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17876 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17877 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17878 {}
17879 };
17880
17881 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17882 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17883 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17885 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17886 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17887 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17888 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17889 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17890 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17891 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17892 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17893 {}
17894 };
17895
17896 static struct hda_verb alc272_dell_init_verbs[] = {
17897 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17898 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17899 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17901 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17902 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17903 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17906 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17907 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17908 {}
17909 };
17910
17911 static struct hda_verb alc663_mode7_init_verbs[] = {
17912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17913 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17915 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17918 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17919 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17920 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17921 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17924 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17925 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17926 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17927 {}
17928 };
17929
17930 static struct hda_verb alc663_mode8_init_verbs[] = {
17931 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17933 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17934 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17935 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17936 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17937 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17939 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17940 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17941 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17943 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17944 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17945 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17946 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17947 {}
17948 };
17949
17950 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17951 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17952 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17953 { } /* end */
17954 };
17955
17956 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17957 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17958 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17959 { } /* end */
17960 };
17961
17962 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17963 {
17964 unsigned int present;
17965 unsigned char bits;
17966
17967 present = snd_hda_jack_detect(codec, 0x14);
17968 bits = present ? HDA_AMP_MUTE : 0;
17969
17970 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17971 HDA_AMP_MUTE, bits);
17972 }
17973
17974 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17975 {
17976 unsigned int present;
17977 unsigned char bits;
17978
17979 present = snd_hda_jack_detect(codec, 0x1b);
17980 bits = present ? HDA_AMP_MUTE : 0;
17981
17982 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17983 HDA_AMP_MUTE, bits);
17984 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17985 HDA_AMP_MUTE, bits);
17986 }
17987
17988 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17989 unsigned int res)
17990 {
17991 if ((res >> 26) == ALC880_HP_EVENT)
17992 alc662_lenovo_101e_all_automute(codec);
17993 if ((res >> 26) == ALC880_FRONT_EVENT)
17994 alc662_lenovo_101e_ispeaker_automute(codec);
17995 }
17996
17997 /* unsolicited event for HP jack sensing */
17998 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17999 unsigned int res)
18000 {
18001 if ((res >> 26) == ALC880_MIC_EVENT)
18002 alc_mic_automute(codec);
18003 else
18004 alc262_hippo_unsol_event(codec, res);
18005 }
18006
18007 static void alc662_eeepc_setup(struct hda_codec *codec)
18008 {
18009 struct alc_spec *spec = codec->spec;
18010
18011 alc262_hippo1_setup(codec);
18012 spec->ext_mic.pin = 0x18;
18013 spec->ext_mic.mux_idx = 0;
18014 spec->int_mic.pin = 0x19;
18015 spec->int_mic.mux_idx = 1;
18016 spec->auto_mic = 1;
18017 }
18018
18019 static void alc662_eeepc_inithook(struct hda_codec *codec)
18020 {
18021 alc262_hippo_automute(codec);
18022 alc_mic_automute(codec);
18023 }
18024
18025 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18026 {
18027 struct alc_spec *spec = codec->spec;
18028
18029 spec->autocfg.hp_pins[0] = 0x14;
18030 spec->autocfg.speaker_pins[0] = 0x1b;
18031 }
18032
18033 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18034
18035 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18036 {
18037 unsigned int present;
18038 unsigned char bits;
18039
18040 present = snd_hda_jack_detect(codec, 0x21);
18041 bits = present ? HDA_AMP_MUTE : 0;
18042 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18043 HDA_AMP_MUTE, bits);
18044 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18045 HDA_AMP_MUTE, bits);
18046 }
18047
18048 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18049 {
18050 unsigned int present;
18051 unsigned char bits;
18052
18053 present = snd_hda_jack_detect(codec, 0x21);
18054 bits = present ? HDA_AMP_MUTE : 0;
18055 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18056 HDA_AMP_MUTE, bits);
18057 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18058 HDA_AMP_MUTE, bits);
18059 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18060 HDA_AMP_MUTE, bits);
18061 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18062 HDA_AMP_MUTE, bits);
18063 }
18064
18065 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18066 {
18067 unsigned int present;
18068 unsigned char bits;
18069
18070 present = snd_hda_jack_detect(codec, 0x15);
18071 bits = present ? HDA_AMP_MUTE : 0;
18072 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18073 HDA_AMP_MUTE, bits);
18074 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18075 HDA_AMP_MUTE, bits);
18076 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18077 HDA_AMP_MUTE, bits);
18078 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18079 HDA_AMP_MUTE, bits);
18080 }
18081
18082 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18083 {
18084 unsigned int present;
18085 unsigned char bits;
18086
18087 present = snd_hda_jack_detect(codec, 0x1b);
18088 bits = present ? 0 : PIN_OUT;
18089 snd_hda_codec_write(codec, 0x14, 0,
18090 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18091 }
18092
18093 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18094 {
18095 unsigned int present1, present2;
18096
18097 present1 = snd_hda_jack_detect(codec, 0x21);
18098 present2 = snd_hda_jack_detect(codec, 0x15);
18099
18100 if (present1 || present2) {
18101 snd_hda_codec_write_cache(codec, 0x14, 0,
18102 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18103 } else {
18104 snd_hda_codec_write_cache(codec, 0x14, 0,
18105 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18106 }
18107 }
18108
18109 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18110 {
18111 unsigned int present1, present2;
18112
18113 present1 = snd_hda_jack_detect(codec, 0x1b);
18114 present2 = snd_hda_jack_detect(codec, 0x15);
18115
18116 if (present1 || present2) {
18117 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18118 HDA_AMP_MUTE, HDA_AMP_MUTE);
18119 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18120 HDA_AMP_MUTE, HDA_AMP_MUTE);
18121 } else {
18122 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18123 HDA_AMP_MUTE, 0);
18124 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18125 HDA_AMP_MUTE, 0);
18126 }
18127 }
18128
18129 static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18130 {
18131 unsigned int present1, present2;
18132
18133 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18134 AC_VERB_GET_PIN_SENSE, 0)
18135 & AC_PINSENSE_PRESENCE;
18136 present2 = snd_hda_codec_read(codec, 0x21, 0,
18137 AC_VERB_GET_PIN_SENSE, 0)
18138 & AC_PINSENSE_PRESENCE;
18139
18140 if (present1 || present2) {
18141 snd_hda_codec_write_cache(codec, 0x14, 0,
18142 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18143 snd_hda_codec_write_cache(codec, 0x17, 0,
18144 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18145 } else {
18146 snd_hda_codec_write_cache(codec, 0x14, 0,
18147 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18148 snd_hda_codec_write_cache(codec, 0x17, 0,
18149 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18150 }
18151 }
18152
18153 static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18154 {
18155 unsigned int present1, present2;
18156
18157 present1 = snd_hda_codec_read(codec, 0x21, 0,
18158 AC_VERB_GET_PIN_SENSE, 0)
18159 & AC_PINSENSE_PRESENCE;
18160 present2 = snd_hda_codec_read(codec, 0x15, 0,
18161 AC_VERB_GET_PIN_SENSE, 0)
18162 & AC_PINSENSE_PRESENCE;
18163
18164 if (present1 || present2) {
18165 snd_hda_codec_write_cache(codec, 0x14, 0,
18166 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18167 snd_hda_codec_write_cache(codec, 0x17, 0,
18168 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18169 } else {
18170 snd_hda_codec_write_cache(codec, 0x14, 0,
18171 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18172 snd_hda_codec_write_cache(codec, 0x17, 0,
18173 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18174 }
18175 }
18176
18177 static void alc663_m51va_unsol_event(struct hda_codec *codec,
18178 unsigned int res)
18179 {
18180 switch (res >> 26) {
18181 case ALC880_HP_EVENT:
18182 alc663_m51va_speaker_automute(codec);
18183 break;
18184 case ALC880_MIC_EVENT:
18185 alc_mic_automute(codec);
18186 break;
18187 }
18188 }
18189
18190 static void alc663_m51va_setup(struct hda_codec *codec)
18191 {
18192 struct alc_spec *spec = codec->spec;
18193 spec->ext_mic.pin = 0x18;
18194 spec->ext_mic.mux_idx = 0;
18195 spec->int_mic.pin = 0x12;
18196 spec->int_mic.mux_idx = 9;
18197 spec->auto_mic = 1;
18198 }
18199
18200 static void alc663_m51va_inithook(struct hda_codec *codec)
18201 {
18202 alc663_m51va_speaker_automute(codec);
18203 alc_mic_automute(codec);
18204 }
18205
18206 /* ***************** Mode1 ******************************/
18207 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
18208
18209 static void alc663_mode1_setup(struct hda_codec *codec)
18210 {
18211 struct alc_spec *spec = codec->spec;
18212 spec->ext_mic.pin = 0x18;
18213 spec->ext_mic.mux_idx = 0;
18214 spec->int_mic.pin = 0x19;
18215 spec->int_mic.mux_idx = 1;
18216 spec->auto_mic = 1;
18217 }
18218
18219 #define alc663_mode1_inithook alc663_m51va_inithook
18220
18221 /* ***************** Mode2 ******************************/
18222 static void alc662_mode2_unsol_event(struct hda_codec *codec,
18223 unsigned int res)
18224 {
18225 switch (res >> 26) {
18226 case ALC880_HP_EVENT:
18227 alc662_f5z_speaker_automute(codec);
18228 break;
18229 case ALC880_MIC_EVENT:
18230 alc_mic_automute(codec);
18231 break;
18232 }
18233 }
18234
18235 #define alc662_mode2_setup alc663_mode1_setup
18236
18237 static void alc662_mode2_inithook(struct hda_codec *codec)
18238 {
18239 alc662_f5z_speaker_automute(codec);
18240 alc_mic_automute(codec);
18241 }
18242 /* ***************** Mode3 ******************************/
18243 static void alc663_mode3_unsol_event(struct hda_codec *codec,
18244 unsigned int res)
18245 {
18246 switch (res >> 26) {
18247 case ALC880_HP_EVENT:
18248 alc663_two_hp_m1_speaker_automute(codec);
18249 break;
18250 case ALC880_MIC_EVENT:
18251 alc_mic_automute(codec);
18252 break;
18253 }
18254 }
18255
18256 #define alc663_mode3_setup alc663_mode1_setup
18257
18258 static void alc663_mode3_inithook(struct hda_codec *codec)
18259 {
18260 alc663_two_hp_m1_speaker_automute(codec);
18261 alc_mic_automute(codec);
18262 }
18263 /* ***************** Mode4 ******************************/
18264 static void alc663_mode4_unsol_event(struct hda_codec *codec,
18265 unsigned int res)
18266 {
18267 switch (res >> 26) {
18268 case ALC880_HP_EVENT:
18269 alc663_21jd_two_speaker_automute(codec);
18270 break;
18271 case ALC880_MIC_EVENT:
18272 alc_mic_automute(codec);
18273 break;
18274 }
18275 }
18276
18277 #define alc663_mode4_setup alc663_mode1_setup
18278
18279 static void alc663_mode4_inithook(struct hda_codec *codec)
18280 {
18281 alc663_21jd_two_speaker_automute(codec);
18282 alc_mic_automute(codec);
18283 }
18284 /* ***************** Mode5 ******************************/
18285 static void alc663_mode5_unsol_event(struct hda_codec *codec,
18286 unsigned int res)
18287 {
18288 switch (res >> 26) {
18289 case ALC880_HP_EVENT:
18290 alc663_15jd_two_speaker_automute(codec);
18291 break;
18292 case ALC880_MIC_EVENT:
18293 alc_mic_automute(codec);
18294 break;
18295 }
18296 }
18297
18298 #define alc663_mode5_setup alc663_mode1_setup
18299
18300 static void alc663_mode5_inithook(struct hda_codec *codec)
18301 {
18302 alc663_15jd_two_speaker_automute(codec);
18303 alc_mic_automute(codec);
18304 }
18305 /* ***************** Mode6 ******************************/
18306 static void alc663_mode6_unsol_event(struct hda_codec *codec,
18307 unsigned int res)
18308 {
18309 switch (res >> 26) {
18310 case ALC880_HP_EVENT:
18311 alc663_two_hp_m2_speaker_automute(codec);
18312 break;
18313 case ALC880_MIC_EVENT:
18314 alc_mic_automute(codec);
18315 break;
18316 }
18317 }
18318
18319 #define alc663_mode6_setup alc663_mode1_setup
18320
18321 static void alc663_mode6_inithook(struct hda_codec *codec)
18322 {
18323 alc663_two_hp_m2_speaker_automute(codec);
18324 alc_mic_automute(codec);
18325 }
18326
18327 /* ***************** Mode7 ******************************/
18328 static void alc663_mode7_unsol_event(struct hda_codec *codec,
18329 unsigned int res)
18330 {
18331 switch (res >> 26) {
18332 case ALC880_HP_EVENT:
18333 alc663_two_hp_m7_speaker_automute(codec);
18334 break;
18335 case ALC880_MIC_EVENT:
18336 alc_mic_automute(codec);
18337 break;
18338 }
18339 }
18340
18341 #define alc663_mode7_setup alc663_mode1_setup
18342
18343 static void alc663_mode7_inithook(struct hda_codec *codec)
18344 {
18345 alc663_two_hp_m7_speaker_automute(codec);
18346 alc_mic_automute(codec);
18347 }
18348
18349 /* ***************** Mode8 ******************************/
18350 static void alc663_mode8_unsol_event(struct hda_codec *codec,
18351 unsigned int res)
18352 {
18353 switch (res >> 26) {
18354 case ALC880_HP_EVENT:
18355 alc663_two_hp_m8_speaker_automute(codec);
18356 break;
18357 case ALC880_MIC_EVENT:
18358 alc_mic_automute(codec);
18359 break;
18360 }
18361 }
18362
18363 #define alc663_mode8_setup alc663_m51va_setup
18364
18365 static void alc663_mode8_inithook(struct hda_codec *codec)
18366 {
18367 alc663_two_hp_m8_speaker_automute(codec);
18368 alc_mic_automute(codec);
18369 }
18370
18371 static void alc663_g71v_hp_automute(struct hda_codec *codec)
18372 {
18373 unsigned int present;
18374 unsigned char bits;
18375
18376 present = snd_hda_jack_detect(codec, 0x21);
18377 bits = present ? HDA_AMP_MUTE : 0;
18378 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18379 HDA_AMP_MUTE, bits);
18380 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18381 HDA_AMP_MUTE, bits);
18382 }
18383
18384 static void alc663_g71v_front_automute(struct hda_codec *codec)
18385 {
18386 unsigned int present;
18387 unsigned char bits;
18388
18389 present = snd_hda_jack_detect(codec, 0x15);
18390 bits = present ? HDA_AMP_MUTE : 0;
18391 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18392 HDA_AMP_MUTE, bits);
18393 }
18394
18395 static void alc663_g71v_unsol_event(struct hda_codec *codec,
18396 unsigned int res)
18397 {
18398 switch (res >> 26) {
18399 case ALC880_HP_EVENT:
18400 alc663_g71v_hp_automute(codec);
18401 break;
18402 case ALC880_FRONT_EVENT:
18403 alc663_g71v_front_automute(codec);
18404 break;
18405 case ALC880_MIC_EVENT:
18406 alc_mic_automute(codec);
18407 break;
18408 }
18409 }
18410
18411 #define alc663_g71v_setup alc663_m51va_setup
18412
18413 static void alc663_g71v_inithook(struct hda_codec *codec)
18414 {
18415 alc663_g71v_front_automute(codec);
18416 alc663_g71v_hp_automute(codec);
18417 alc_mic_automute(codec);
18418 }
18419
18420 static void alc663_g50v_unsol_event(struct hda_codec *codec,
18421 unsigned int res)
18422 {
18423 switch (res >> 26) {
18424 case ALC880_HP_EVENT:
18425 alc663_m51va_speaker_automute(codec);
18426 break;
18427 case ALC880_MIC_EVENT:
18428 alc_mic_automute(codec);
18429 break;
18430 }
18431 }
18432
18433 #define alc663_g50v_setup alc663_m51va_setup
18434
18435 static void alc663_g50v_inithook(struct hda_codec *codec)
18436 {
18437 alc663_m51va_speaker_automute(codec);
18438 alc_mic_automute(codec);
18439 }
18440
18441 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18442 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18443 ALC262_HIPPO_MASTER_SWITCH,
18444
18445 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18446 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18447 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18448
18449 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18450 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18451 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18452 { } /* end */
18453 };
18454
18455 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18456 /* Master Playback automatically created from Speaker and Headphone */
18457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18458 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18459 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18461
18462 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18463 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18464 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18465
18466 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18467 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18468 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18469 { } /* end */
18470 };
18471
18472 #ifdef CONFIG_SND_HDA_POWER_SAVE
18473 #define alc662_loopbacks alc880_loopbacks
18474 #endif
18475
18476
18477 /* pcm configuration: identical with ALC880 */
18478 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
18479 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
18480 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
18481 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
18482
18483 /*
18484 * configuration and preset
18485 */
18486 static const char *alc662_models[ALC662_MODEL_LAST] = {
18487 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18488 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18489 [ALC662_3ST_6ch] = "3stack-6ch",
18490 [ALC662_5ST_DIG] = "6stack-dig",
18491 [ALC662_LENOVO_101E] = "lenovo-101e",
18492 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18493 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18494 [ALC662_ECS] = "ecs",
18495 [ALC663_ASUS_M51VA] = "m51va",
18496 [ALC663_ASUS_G71V] = "g71v",
18497 [ALC663_ASUS_H13] = "h13",
18498 [ALC663_ASUS_G50V] = "g50v",
18499 [ALC663_ASUS_MODE1] = "asus-mode1",
18500 [ALC662_ASUS_MODE2] = "asus-mode2",
18501 [ALC663_ASUS_MODE3] = "asus-mode3",
18502 [ALC663_ASUS_MODE4] = "asus-mode4",
18503 [ALC663_ASUS_MODE5] = "asus-mode5",
18504 [ALC663_ASUS_MODE6] = "asus-mode6",
18505 [ALC663_ASUS_MODE7] = "asus-mode7",
18506 [ALC663_ASUS_MODE8] = "asus-mode8",
18507 [ALC272_DELL] = "dell",
18508 [ALC272_DELL_ZM1] = "dell-zm1",
18509 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18510 [ALC662_AUTO] = "auto",
18511 };
18512
18513 static struct snd_pci_quirk alc662_cfg_tbl[] = {
18514 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18515 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18516 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18517 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18518 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18519 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18520 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18521 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18522 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18523 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18524 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18525 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18526 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18527 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18528 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18529 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18530 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18531 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18532 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18533 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18534 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18535 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18536 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18537 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18538 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18539 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18540 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18541 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18542 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18543 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18544 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18545 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18546 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18547 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18548 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18549 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18550 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18551 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18552 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18553 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18554 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18555 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18556 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18557 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18558 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18559 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18560 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18561 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18562 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18563 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18564 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18565 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18566 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18567 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18568 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18569 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18570 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18571 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18572 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18573 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18574 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18575 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18576 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18577 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18578 ALC662_3ST_6ch_DIG),
18579 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18580 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18581 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18582 ALC662_3ST_6ch_DIG),
18583 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18584 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18585 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18586 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18587 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18588 ALC662_3ST_6ch_DIG),
18589 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18590 ALC663_ASUS_H13),
18591 {}
18592 };
18593
18594 static struct alc_config_preset alc662_presets[] = {
18595 [ALC662_3ST_2ch_DIG] = {
18596 .mixers = { alc662_3ST_2ch_mixer },
18597 .init_verbs = { alc662_init_verbs },
18598 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18599 .dac_nids = alc662_dac_nids,
18600 .dig_out_nid = ALC662_DIGOUT_NID,
18601 .dig_in_nid = ALC662_DIGIN_NID,
18602 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18603 .channel_mode = alc662_3ST_2ch_modes,
18604 .input_mux = &alc662_capture_source,
18605 },
18606 [ALC662_3ST_6ch_DIG] = {
18607 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18608 .init_verbs = { alc662_init_verbs },
18609 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18610 .dac_nids = alc662_dac_nids,
18611 .dig_out_nid = ALC662_DIGOUT_NID,
18612 .dig_in_nid = ALC662_DIGIN_NID,
18613 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18614 .channel_mode = alc662_3ST_6ch_modes,
18615 .need_dac_fix = 1,
18616 .input_mux = &alc662_capture_source,
18617 },
18618 [ALC662_3ST_6ch] = {
18619 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18620 .init_verbs = { alc662_init_verbs },
18621 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18622 .dac_nids = alc662_dac_nids,
18623 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18624 .channel_mode = alc662_3ST_6ch_modes,
18625 .need_dac_fix = 1,
18626 .input_mux = &alc662_capture_source,
18627 },
18628 [ALC662_5ST_DIG] = {
18629 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18630 .init_verbs = { alc662_init_verbs },
18631 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18632 .dac_nids = alc662_dac_nids,
18633 .dig_out_nid = ALC662_DIGOUT_NID,
18634 .dig_in_nid = ALC662_DIGIN_NID,
18635 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18636 .channel_mode = alc662_5stack_modes,
18637 .input_mux = &alc662_capture_source,
18638 },
18639 [ALC662_LENOVO_101E] = {
18640 .mixers = { alc662_lenovo_101e_mixer },
18641 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18642 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18643 .dac_nids = alc662_dac_nids,
18644 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18645 .channel_mode = alc662_3ST_2ch_modes,
18646 .input_mux = &alc662_lenovo_101e_capture_source,
18647 .unsol_event = alc662_lenovo_101e_unsol_event,
18648 .init_hook = alc662_lenovo_101e_all_automute,
18649 },
18650 [ALC662_ASUS_EEEPC_P701] = {
18651 .mixers = { alc662_eeepc_p701_mixer },
18652 .init_verbs = { alc662_init_verbs,
18653 alc662_eeepc_sue_init_verbs },
18654 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18655 .dac_nids = alc662_dac_nids,
18656 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18657 .channel_mode = alc662_3ST_2ch_modes,
18658 .unsol_event = alc662_eeepc_unsol_event,
18659 .setup = alc662_eeepc_setup,
18660 .init_hook = alc662_eeepc_inithook,
18661 },
18662 [ALC662_ASUS_EEEPC_EP20] = {
18663 .mixers = { alc662_eeepc_ep20_mixer,
18664 alc662_chmode_mixer },
18665 .init_verbs = { alc662_init_verbs,
18666 alc662_eeepc_ep20_sue_init_verbs },
18667 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18668 .dac_nids = alc662_dac_nids,
18669 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18670 .channel_mode = alc662_3ST_6ch_modes,
18671 .input_mux = &alc662_lenovo_101e_capture_source,
18672 .unsol_event = alc662_eeepc_unsol_event,
18673 .setup = alc662_eeepc_ep20_setup,
18674 .init_hook = alc662_eeepc_ep20_inithook,
18675 },
18676 [ALC662_ECS] = {
18677 .mixers = { alc662_ecs_mixer },
18678 .init_verbs = { alc662_init_verbs,
18679 alc662_ecs_init_verbs },
18680 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18681 .dac_nids = alc662_dac_nids,
18682 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18683 .channel_mode = alc662_3ST_2ch_modes,
18684 .unsol_event = alc662_eeepc_unsol_event,
18685 .setup = alc662_eeepc_setup,
18686 .init_hook = alc662_eeepc_inithook,
18687 },
18688 [ALC663_ASUS_M51VA] = {
18689 .mixers = { alc663_m51va_mixer },
18690 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18691 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18692 .dac_nids = alc662_dac_nids,
18693 .dig_out_nid = ALC662_DIGOUT_NID,
18694 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18695 .channel_mode = alc662_3ST_2ch_modes,
18696 .unsol_event = alc663_m51va_unsol_event,
18697 .setup = alc663_m51va_setup,
18698 .init_hook = alc663_m51va_inithook,
18699 },
18700 [ALC663_ASUS_G71V] = {
18701 .mixers = { alc663_g71v_mixer },
18702 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18703 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18704 .dac_nids = alc662_dac_nids,
18705 .dig_out_nid = ALC662_DIGOUT_NID,
18706 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18707 .channel_mode = alc662_3ST_2ch_modes,
18708 .unsol_event = alc663_g71v_unsol_event,
18709 .setup = alc663_g71v_setup,
18710 .init_hook = alc663_g71v_inithook,
18711 },
18712 [ALC663_ASUS_H13] = {
18713 .mixers = { alc663_m51va_mixer },
18714 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18715 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18716 .dac_nids = alc662_dac_nids,
18717 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18718 .channel_mode = alc662_3ST_2ch_modes,
18719 .unsol_event = alc663_m51va_unsol_event,
18720 .init_hook = alc663_m51va_inithook,
18721 },
18722 [ALC663_ASUS_G50V] = {
18723 .mixers = { alc663_g50v_mixer },
18724 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18725 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18726 .dac_nids = alc662_dac_nids,
18727 .dig_out_nid = ALC662_DIGOUT_NID,
18728 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18729 .channel_mode = alc662_3ST_6ch_modes,
18730 .input_mux = &alc663_capture_source,
18731 .unsol_event = alc663_g50v_unsol_event,
18732 .setup = alc663_g50v_setup,
18733 .init_hook = alc663_g50v_inithook,
18734 },
18735 [ALC663_ASUS_MODE1] = {
18736 .mixers = { alc663_m51va_mixer },
18737 .cap_mixer = alc662_auto_capture_mixer,
18738 .init_verbs = { alc662_init_verbs,
18739 alc663_21jd_amic_init_verbs },
18740 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18741 .hp_nid = 0x03,
18742 .dac_nids = alc662_dac_nids,
18743 .dig_out_nid = ALC662_DIGOUT_NID,
18744 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18745 .channel_mode = alc662_3ST_2ch_modes,
18746 .unsol_event = alc663_mode1_unsol_event,
18747 .setup = alc663_mode1_setup,
18748 .init_hook = alc663_mode1_inithook,
18749 },
18750 [ALC662_ASUS_MODE2] = {
18751 .mixers = { alc662_1bjd_mixer },
18752 .cap_mixer = alc662_auto_capture_mixer,
18753 .init_verbs = { alc662_init_verbs,
18754 alc662_1bjd_amic_init_verbs },
18755 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18756 .dac_nids = alc662_dac_nids,
18757 .dig_out_nid = ALC662_DIGOUT_NID,
18758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18759 .channel_mode = alc662_3ST_2ch_modes,
18760 .unsol_event = alc662_mode2_unsol_event,
18761 .setup = alc662_mode2_setup,
18762 .init_hook = alc662_mode2_inithook,
18763 },
18764 [ALC663_ASUS_MODE3] = {
18765 .mixers = { alc663_two_hp_m1_mixer },
18766 .cap_mixer = alc662_auto_capture_mixer,
18767 .init_verbs = { alc662_init_verbs,
18768 alc663_two_hp_amic_m1_init_verbs },
18769 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18770 .hp_nid = 0x03,
18771 .dac_nids = alc662_dac_nids,
18772 .dig_out_nid = ALC662_DIGOUT_NID,
18773 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18774 .channel_mode = alc662_3ST_2ch_modes,
18775 .unsol_event = alc663_mode3_unsol_event,
18776 .setup = alc663_mode3_setup,
18777 .init_hook = alc663_mode3_inithook,
18778 },
18779 [ALC663_ASUS_MODE4] = {
18780 .mixers = { alc663_asus_21jd_clfe_mixer },
18781 .cap_mixer = alc662_auto_capture_mixer,
18782 .init_verbs = { alc662_init_verbs,
18783 alc663_21jd_amic_init_verbs},
18784 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18785 .hp_nid = 0x03,
18786 .dac_nids = alc662_dac_nids,
18787 .dig_out_nid = ALC662_DIGOUT_NID,
18788 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18789 .channel_mode = alc662_3ST_2ch_modes,
18790 .unsol_event = alc663_mode4_unsol_event,
18791 .setup = alc663_mode4_setup,
18792 .init_hook = alc663_mode4_inithook,
18793 },
18794 [ALC663_ASUS_MODE5] = {
18795 .mixers = { alc663_asus_15jd_clfe_mixer },
18796 .cap_mixer = alc662_auto_capture_mixer,
18797 .init_verbs = { alc662_init_verbs,
18798 alc663_15jd_amic_init_verbs },
18799 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18800 .hp_nid = 0x03,
18801 .dac_nids = alc662_dac_nids,
18802 .dig_out_nid = ALC662_DIGOUT_NID,
18803 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18804 .channel_mode = alc662_3ST_2ch_modes,
18805 .unsol_event = alc663_mode5_unsol_event,
18806 .setup = alc663_mode5_setup,
18807 .init_hook = alc663_mode5_inithook,
18808 },
18809 [ALC663_ASUS_MODE6] = {
18810 .mixers = { alc663_two_hp_m2_mixer },
18811 .cap_mixer = alc662_auto_capture_mixer,
18812 .init_verbs = { alc662_init_verbs,
18813 alc663_two_hp_amic_m2_init_verbs },
18814 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18815 .hp_nid = 0x03,
18816 .dac_nids = alc662_dac_nids,
18817 .dig_out_nid = ALC662_DIGOUT_NID,
18818 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18819 .channel_mode = alc662_3ST_2ch_modes,
18820 .unsol_event = alc663_mode6_unsol_event,
18821 .setup = alc663_mode6_setup,
18822 .init_hook = alc663_mode6_inithook,
18823 },
18824 [ALC663_ASUS_MODE7] = {
18825 .mixers = { alc663_mode7_mixer },
18826 .cap_mixer = alc662_auto_capture_mixer,
18827 .init_verbs = { alc662_init_verbs,
18828 alc663_mode7_init_verbs },
18829 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18830 .hp_nid = 0x03,
18831 .dac_nids = alc662_dac_nids,
18832 .dig_out_nid = ALC662_DIGOUT_NID,
18833 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18834 .channel_mode = alc662_3ST_2ch_modes,
18835 .unsol_event = alc663_mode7_unsol_event,
18836 .setup = alc663_mode7_setup,
18837 .init_hook = alc663_mode7_inithook,
18838 },
18839 [ALC663_ASUS_MODE8] = {
18840 .mixers = { alc663_mode8_mixer },
18841 .cap_mixer = alc662_auto_capture_mixer,
18842 .init_verbs = { alc662_init_verbs,
18843 alc663_mode8_init_verbs },
18844 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18845 .hp_nid = 0x03,
18846 .dac_nids = alc662_dac_nids,
18847 .dig_out_nid = ALC662_DIGOUT_NID,
18848 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18849 .channel_mode = alc662_3ST_2ch_modes,
18850 .unsol_event = alc663_mode8_unsol_event,
18851 .setup = alc663_mode8_setup,
18852 .init_hook = alc663_mode8_inithook,
18853 },
18854 [ALC272_DELL] = {
18855 .mixers = { alc663_m51va_mixer },
18856 .cap_mixer = alc272_auto_capture_mixer,
18857 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18858 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18859 .dac_nids = alc662_dac_nids,
18860 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18861 .adc_nids = alc272_adc_nids,
18862 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18863 .capsrc_nids = alc272_capsrc_nids,
18864 .channel_mode = alc662_3ST_2ch_modes,
18865 .unsol_event = alc663_m51va_unsol_event,
18866 .setup = alc663_m51va_setup,
18867 .init_hook = alc663_m51va_inithook,
18868 },
18869 [ALC272_DELL_ZM1] = {
18870 .mixers = { alc663_m51va_mixer },
18871 .cap_mixer = alc662_auto_capture_mixer,
18872 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18873 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18874 .dac_nids = alc662_dac_nids,
18875 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18876 .adc_nids = alc662_adc_nids,
18877 .num_adc_nids = 1,
18878 .capsrc_nids = alc662_capsrc_nids,
18879 .channel_mode = alc662_3ST_2ch_modes,
18880 .unsol_event = alc663_m51va_unsol_event,
18881 .setup = alc663_m51va_setup,
18882 .init_hook = alc663_m51va_inithook,
18883 },
18884 [ALC272_SAMSUNG_NC10] = {
18885 .mixers = { alc272_nc10_mixer },
18886 .init_verbs = { alc662_init_verbs,
18887 alc663_21jd_amic_init_verbs },
18888 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18889 .dac_nids = alc272_dac_nids,
18890 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18891 .channel_mode = alc662_3ST_2ch_modes,
18892 /*.input_mux = &alc272_nc10_capture_source,*/
18893 .unsol_event = alc663_mode4_unsol_event,
18894 .setup = alc663_mode4_setup,
18895 .init_hook = alc663_mode4_inithook,
18896 },
18897 };
18898
18899
18900 /*
18901 * BIOS auto configuration
18902 */
18903
18904 /* convert from MIX nid to DAC */
18905 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18906 {
18907 if (nid == 0x0f)
18908 return 0x02;
18909 else if (nid >= 0x0c && nid <= 0x0e)
18910 return nid - 0x0c + 0x02;
18911 else
18912 return 0;
18913 }
18914
18915 /* get MIX nid connected to the given pin targeted to DAC */
18916 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18917 hda_nid_t dac)
18918 {
18919 hda_nid_t mix[4];
18920 int i, num;
18921
18922 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18923 for (i = 0; i < num; i++) {
18924 if (alc662_mix_to_dac(mix[i]) == dac)
18925 return mix[i];
18926 }
18927 return 0;
18928 }
18929
18930 /* look for an empty DAC slot */
18931 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18932 {
18933 struct alc_spec *spec = codec->spec;
18934 hda_nid_t srcs[5];
18935 int i, j, num;
18936
18937 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18938 if (num < 0)
18939 return 0;
18940 for (i = 0; i < num; i++) {
18941 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18942 if (!nid)
18943 continue;
18944 for (j = 0; j < spec->multiout.num_dacs; j++)
18945 if (spec->multiout.dac_nids[j] == nid)
18946 break;
18947 if (j >= spec->multiout.num_dacs)
18948 return nid;
18949 }
18950 return 0;
18951 }
18952
18953 /* fill in the dac_nids table from the parsed pin configuration */
18954 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18955 const struct auto_pin_cfg *cfg)
18956 {
18957 struct alc_spec *spec = codec->spec;
18958 int i;
18959 hda_nid_t dac;
18960
18961 spec->multiout.dac_nids = spec->private_dac_nids;
18962 for (i = 0; i < cfg->line_outs; i++) {
18963 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18964 if (!dac)
18965 continue;
18966 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18967 }
18968 return 0;
18969 }
18970
18971 static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18972 hda_nid_t nid, unsigned int chs)
18973 {
18974 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
18975 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18976 }
18977
18978 static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18979 hda_nid_t nid, unsigned int chs)
18980 {
18981 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18982 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18983 }
18984
18985 #define alc662_add_stereo_vol(spec, pfx, nid) \
18986 alc662_add_vol_ctl(spec, pfx, nid, 3)
18987 #define alc662_add_stereo_sw(spec, pfx, nid) \
18988 alc662_add_sw_ctl(spec, pfx, nid, 3)
18989
18990 /* add playback controls from the parsed DAC table */
18991 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
18992 const struct auto_pin_cfg *cfg)
18993 {
18994 struct alc_spec *spec = codec->spec;
18995 static const char *chname[4] = {
18996 "Front", "Surround", NULL /*CLFE*/, "Side"
18997 };
18998 hda_nid_t nid, mix;
18999 int i, err;
19000
19001 for (i = 0; i < cfg->line_outs; i++) {
19002 nid = spec->multiout.dac_nids[i];
19003 if (!nid)
19004 continue;
19005 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19006 if (!mix)
19007 continue;
19008 if (i == 2) {
19009 /* Center/LFE */
19010 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19011 if (err < 0)
19012 return err;
19013 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19014 if (err < 0)
19015 return err;
19016 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19017 if (err < 0)
19018 return err;
19019 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19020 if (err < 0)
19021 return err;
19022 } else {
19023 const char *pfx;
19024 if (cfg->line_outs == 1 &&
19025 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
19026 if (cfg->hp_outs)
19027 pfx = "Speaker";
19028 else
19029 pfx = "PCM";
19030 } else
19031 pfx = chname[i];
19032 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19033 if (err < 0)
19034 return err;
19035 if (cfg->line_outs == 1 &&
19036 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19037 pfx = "Speaker";
19038 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19039 if (err < 0)
19040 return err;
19041 }
19042 }
19043 return 0;
19044 }
19045
19046 /* add playback controls for speaker and HP outputs */
19047 /* return DAC nid if any new DAC is assigned */
19048 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19049 const char *pfx)
19050 {
19051 struct alc_spec *spec = codec->spec;
19052 hda_nid_t nid, mix;
19053 int err;
19054
19055 if (!pin)
19056 return 0;
19057 nid = alc662_look_for_dac(codec, pin);
19058 if (!nid) {
19059 /* the corresponding DAC is already occupied */
19060 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19061 return 0; /* no way */
19062 /* create a switch only */
19063 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19064 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19065 }
19066
19067 mix = alc662_dac_to_mix(codec, pin, nid);
19068 if (!mix)
19069 return 0;
19070 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19071 if (err < 0)
19072 return err;
19073 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19074 if (err < 0)
19075 return err;
19076 return nid;
19077 }
19078
19079 /* create playback/capture controls for input pins */
19080 #define alc662_auto_create_input_ctls \
19081 alc882_auto_create_input_ctls
19082
19083 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19084 hda_nid_t nid, int pin_type,
19085 hda_nid_t dac)
19086 {
19087 int i, num;
19088 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19089
19090 alc_set_pin_output(codec, nid, pin_type);
19091 /* need the manual connection? */
19092 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19093 if (num <= 1)
19094 return;
19095 for (i = 0; i < num; i++) {
19096 if (alc662_mix_to_dac(srcs[i]) != dac)
19097 continue;
19098 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19099 return;
19100 }
19101 }
19102
19103 static void alc662_auto_init_multi_out(struct hda_codec *codec)
19104 {
19105 struct alc_spec *spec = codec->spec;
19106 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19107 int i;
19108
19109 for (i = 0; i <= HDA_SIDE; i++) {
19110 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19111 if (nid)
19112 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19113 spec->multiout.dac_nids[i]);
19114 }
19115 }
19116
19117 static void alc662_auto_init_hp_out(struct hda_codec *codec)
19118 {
19119 struct alc_spec *spec = codec->spec;
19120 hda_nid_t pin;
19121
19122 pin = spec->autocfg.hp_pins[0];
19123 if (pin)
19124 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19125 spec->multiout.hp_nid);
19126 pin = spec->autocfg.speaker_pins[0];
19127 if (pin)
19128 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19129 spec->multiout.extra_out_nid[0]);
19130 }
19131
19132 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19133
19134 static void alc662_auto_init_analog_input(struct hda_codec *codec)
19135 {
19136 struct alc_spec *spec = codec->spec;
19137 struct auto_pin_cfg *cfg = &spec->autocfg;
19138 int i;
19139
19140 for (i = 0; i < cfg->num_inputs; i++) {
19141 hda_nid_t nid = cfg->inputs[i].pin;
19142 if (alc_is_input_pin(codec, nid)) {
19143 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19144 if (nid != ALC662_PIN_CD_NID &&
19145 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19146 snd_hda_codec_write(codec, nid, 0,
19147 AC_VERB_SET_AMP_GAIN_MUTE,
19148 AMP_OUT_MUTE);
19149 }
19150 }
19151 }
19152
19153 #define alc662_auto_init_input_src alc882_auto_init_input_src
19154
19155 static int alc662_parse_auto_config(struct hda_codec *codec)
19156 {
19157 struct alc_spec *spec = codec->spec;
19158 int err;
19159 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19160
19161 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19162 alc662_ignore);
19163 if (err < 0)
19164 return err;
19165 if (!spec->autocfg.line_outs)
19166 return 0; /* can't find valid BIOS pin config */
19167
19168 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19169 if (err < 0)
19170 return err;
19171 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19172 if (err < 0)
19173 return err;
19174 err = alc662_auto_create_extra_out(codec,
19175 spec->autocfg.speaker_pins[0],
19176 "Speaker");
19177 if (err < 0)
19178 return err;
19179 if (err)
19180 spec->multiout.extra_out_nid[0] = err;
19181 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19182 "Headphone");
19183 if (err < 0)
19184 return err;
19185 if (err)
19186 spec->multiout.hp_nid = err;
19187 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19188 if (err < 0)
19189 return err;
19190
19191 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19192
19193 alc_auto_parse_digital(codec);
19194
19195 if (spec->kctls.list)
19196 add_mixer(spec, spec->kctls.list);
19197
19198 spec->num_mux_defs = 1;
19199 spec->input_mux = &spec->private_imux[0];
19200
19201 add_verb(spec, alc662_init_verbs);
19202 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19203 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19204 add_verb(spec, alc663_init_verbs);
19205
19206 if (codec->vendor_id == 0x10ec0272)
19207 add_verb(spec, alc272_init_verbs);
19208
19209 err = alc_auto_add_mic_boost(codec);
19210 if (err < 0)
19211 return err;
19212
19213 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19214 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19215 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19216 else
19217 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19218
19219 return 1;
19220 }
19221
19222 /* additional initialization for auto-configuration model */
19223 static void alc662_auto_init(struct hda_codec *codec)
19224 {
19225 struct alc_spec *spec = codec->spec;
19226 alc662_auto_init_multi_out(codec);
19227 alc662_auto_init_hp_out(codec);
19228 alc662_auto_init_analog_input(codec);
19229 alc662_auto_init_input_src(codec);
19230 alc_auto_init_digital(codec);
19231 if (spec->unsol_event)
19232 alc_inithook(codec);
19233 }
19234
19235 enum {
19236 ALC662_FIXUP_IDEAPAD,
19237 };
19238
19239 static const struct alc_fixup alc662_fixups[] = {
19240 [ALC662_FIXUP_IDEAPAD] = {
19241 .pins = (const struct alc_pincfg[]) {
19242 { 0x17, 0x99130112 }, /* subwoofer */
19243 { }
19244 }
19245 },
19246 };
19247
19248 static struct snd_pci_quirk alc662_fixup_tbl[] = {
19249 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19250 {}
19251 };
19252
19253
19254
19255 static int patch_alc662(struct hda_codec *codec)
19256 {
19257 struct alc_spec *spec;
19258 int err, board_config;
19259
19260 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19261 if (!spec)
19262 return -ENOMEM;
19263
19264 codec->spec = spec;
19265
19266 alc_auto_parse_customize_define(codec);
19267
19268 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19269
19270 if (alc_read_coef_idx(codec, 0) == 0x8020)
19271 alc_codec_rename(codec, "ALC661");
19272 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
19273 codec->bus->pci->subsystem_vendor == 0x1025 &&
19274 spec->cdefine.platform_type == 1)
19275 alc_codec_rename(codec, "ALC272X");
19276
19277 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19278 alc662_models,
19279 alc662_cfg_tbl);
19280 if (board_config < 0) {
19281 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19282 codec->chip_name);
19283 board_config = ALC662_AUTO;
19284 }
19285
19286 if (board_config == ALC662_AUTO) {
19287 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1);
19288 /* automatic parse from the BIOS config */
19289 err = alc662_parse_auto_config(codec);
19290 if (err < 0) {
19291 alc_free(codec);
19292 return err;
19293 } else if (!err) {
19294 printk(KERN_INFO
19295 "hda_codec: Cannot set up configuration "
19296 "from BIOS. Using base mode...\n");
19297 board_config = ALC662_3ST_2ch_DIG;
19298 }
19299 }
19300
19301 if (has_cdefine_beep(codec)) {
19302 err = snd_hda_attach_beep_device(codec, 0x1);
19303 if (err < 0) {
19304 alc_free(codec);
19305 return err;
19306 }
19307 }
19308
19309 if (board_config != ALC662_AUTO)
19310 setup_preset(codec, &alc662_presets[board_config]);
19311
19312 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19313 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19314
19315 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19316 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19317
19318 if (!spec->adc_nids) {
19319 spec->adc_nids = alc662_adc_nids;
19320 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19321 }
19322 if (!spec->capsrc_nids)
19323 spec->capsrc_nids = alc662_capsrc_nids;
19324
19325 if (!spec->cap_mixer)
19326 set_capture_mixer(codec);
19327
19328 if (has_cdefine_beep(codec)) {
19329 switch (codec->vendor_id) {
19330 case 0x10ec0662:
19331 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19332 break;
19333 case 0x10ec0272:
19334 case 0x10ec0663:
19335 case 0x10ec0665:
19336 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19337 break;
19338 case 0x10ec0273:
19339 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19340 break;
19341 }
19342 }
19343 spec->vmaster_nid = 0x02;
19344
19345 codec->patch_ops = alc_patch_ops;
19346 if (board_config == ALC662_AUTO) {
19347 spec->init_hook = alc662_auto_init;
19348 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0);
19349 }
19350
19351 #ifdef CONFIG_SND_HDA_POWER_SAVE
19352 if (!spec->loopback.amplist)
19353 spec->loopback.amplist = alc662_loopbacks;
19354 #endif
19355
19356 return 0;
19357 }
19358
19359 static int patch_alc888(struct hda_codec *codec)
19360 {
19361 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19362 kfree(codec->chip_name);
19363 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19364 if (!codec->chip_name) {
19365 alc_free(codec);
19366 return -ENOMEM;
19367 }
19368 return patch_alc662(codec);
19369 }
19370 return patch_alc882(codec);
19371 }
19372
19373 /*
19374 * ALC680 support
19375 */
19376 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19377 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19378 #define alc680_modes alc260_modes
19379
19380 static hda_nid_t alc680_dac_nids[3] = {
19381 /* Lout1, Lout2, hp */
19382 0x02, 0x03, 0x04
19383 };
19384
19385 static hda_nid_t alc680_adc_nids[3] = {
19386 /* ADC0-2 */
19387 /* DMIC, MIC, Line-in*/
19388 0x07, 0x08, 0x09
19389 };
19390
19391 /*
19392 * Analog capture ADC cgange
19393 */
19394 static void alc680_rec_autoswitch(struct hda_codec *codec)
19395 {
19396 struct alc_spec *spec = codec->spec;
19397 struct auto_pin_cfg *cfg = &spec->autocfg;
19398 int pin_found = 0;
19399 int type_found = AUTO_PIN_LAST;
19400 hda_nid_t nid;
19401 int i;
19402
19403 for (i = 0; i < cfg->num_inputs; i++) {
19404 nid = cfg->inputs[i].pin;
19405 if (!(snd_hda_query_pin_caps(codec, nid) &
19406 AC_PINCAP_PRES_DETECT))
19407 continue;
19408 if (snd_hda_jack_detect(codec, nid)) {
19409 if (cfg->inputs[i].type < type_found) {
19410 type_found = cfg->inputs[i].type;
19411 pin_found = nid;
19412 }
19413 }
19414 }
19415
19416 nid = 0x07;
19417 if (pin_found)
19418 snd_hda_get_connections(codec, pin_found, &nid, 1);
19419
19420 if (nid != spec->cur_adc)
19421 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19422 spec->cur_adc = nid;
19423 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19424 spec->cur_adc_format);
19425 }
19426
19427 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19428 struct hda_codec *codec,
19429 unsigned int stream_tag,
19430 unsigned int format,
19431 struct snd_pcm_substream *substream)
19432 {
19433 struct alc_spec *spec = codec->spec;
19434
19435 spec->cur_adc = 0x07;
19436 spec->cur_adc_stream_tag = stream_tag;
19437 spec->cur_adc_format = format;
19438
19439 alc680_rec_autoswitch(codec);
19440 return 0;
19441 }
19442
19443 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19444 struct hda_codec *codec,
19445 struct snd_pcm_substream *substream)
19446 {
19447 snd_hda_codec_cleanup_stream(codec, 0x07);
19448 snd_hda_codec_cleanup_stream(codec, 0x08);
19449 snd_hda_codec_cleanup_stream(codec, 0x09);
19450 return 0;
19451 }
19452
19453 static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19454 .substreams = 1, /* can be overridden */
19455 .channels_min = 2,
19456 .channels_max = 2,
19457 /* NID is set in alc_build_pcms */
19458 .ops = {
19459 .prepare = alc680_capture_pcm_prepare,
19460 .cleanup = alc680_capture_pcm_cleanup
19461 },
19462 };
19463
19464 static struct snd_kcontrol_new alc680_base_mixer[] = {
19465 /* output mixer control */
19466 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19467 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19468 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19469 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19470 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
19471 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
19472 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
19473 { }
19474 };
19475
19476 static struct hda_bind_ctls alc680_bind_cap_vol = {
19477 .ops = &snd_hda_bind_vol,
19478 .values = {
19479 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19480 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19481 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19482 0
19483 },
19484 };
19485
19486 static struct hda_bind_ctls alc680_bind_cap_switch = {
19487 .ops = &snd_hda_bind_sw,
19488 .values = {
19489 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19490 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19491 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19492 0
19493 },
19494 };
19495
19496 static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19497 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19498 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19499 { } /* end */
19500 };
19501
19502 /*
19503 * generic initialization of ADC, input mixers and output mixers
19504 */
19505 static struct hda_verb alc680_init_verbs[] = {
19506 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19507 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19508 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19509
19510 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19511 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19513 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19514 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19515 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19516
19517 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19520 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19521 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19522
19523 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19524 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19525 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19526
19527 { }
19528 };
19529
19530 /* toggle speaker-output according to the hp-jack state */
19531 static void alc680_base_setup(struct hda_codec *codec)
19532 {
19533 struct alc_spec *spec = codec->spec;
19534
19535 spec->autocfg.hp_pins[0] = 0x16;
19536 spec->autocfg.speaker_pins[0] = 0x14;
19537 spec->autocfg.speaker_pins[1] = 0x15;
19538 spec->autocfg.num_inputs = 2;
19539 spec->autocfg.inputs[0].pin = 0x18;
19540 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19541 spec->autocfg.inputs[1].pin = 0x19;
19542 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19543 }
19544
19545 static void alc680_unsol_event(struct hda_codec *codec,
19546 unsigned int res)
19547 {
19548 if ((res >> 26) == ALC880_HP_EVENT)
19549 alc_automute_amp(codec);
19550 if ((res >> 26) == ALC880_MIC_EVENT)
19551 alc680_rec_autoswitch(codec);
19552 }
19553
19554 static void alc680_inithook(struct hda_codec *codec)
19555 {
19556 alc_automute_amp(codec);
19557 alc680_rec_autoswitch(codec);
19558 }
19559
19560 /* create input playback/capture controls for the given pin */
19561 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19562 const char *ctlname, int idx)
19563 {
19564 hda_nid_t dac;
19565 int err;
19566
19567 switch (nid) {
19568 case 0x14:
19569 dac = 0x02;
19570 break;
19571 case 0x15:
19572 dac = 0x03;
19573 break;
19574 case 0x16:
19575 dac = 0x04;
19576 break;
19577 default:
19578 return 0;
19579 }
19580 if (spec->multiout.dac_nids[0] != dac &&
19581 spec->multiout.dac_nids[1] != dac) {
19582 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19583 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19584 HDA_OUTPUT));
19585 if (err < 0)
19586 return err;
19587
19588 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19589 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19590
19591 if (err < 0)
19592 return err;
19593 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19594 }
19595
19596 return 0;
19597 }
19598
19599 /* add playback controls from the parsed DAC table */
19600 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19601 const struct auto_pin_cfg *cfg)
19602 {
19603 hda_nid_t nid;
19604 int err;
19605
19606 spec->multiout.dac_nids = spec->private_dac_nids;
19607
19608 nid = cfg->line_out_pins[0];
19609 if (nid) {
19610 const char *name;
19611 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19612 name = "Speaker";
19613 else
19614 name = "Front";
19615 err = alc680_new_analog_output(spec, nid, name, 0);
19616 if (err < 0)
19617 return err;
19618 }
19619
19620 nid = cfg->speaker_pins[0];
19621 if (nid) {
19622 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19623 if (err < 0)
19624 return err;
19625 }
19626 nid = cfg->hp_pins[0];
19627 if (nid) {
19628 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19629 if (err < 0)
19630 return err;
19631 }
19632
19633 return 0;
19634 }
19635
19636 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19637 hda_nid_t nid, int pin_type)
19638 {
19639 alc_set_pin_output(codec, nid, pin_type);
19640 }
19641
19642 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19643 {
19644 struct alc_spec *spec = codec->spec;
19645 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19646 if (nid) {
19647 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19648 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19649 }
19650 }
19651
19652 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19653 {
19654 struct alc_spec *spec = codec->spec;
19655 hda_nid_t pin;
19656
19657 pin = spec->autocfg.hp_pins[0];
19658 if (pin)
19659 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19660 pin = spec->autocfg.speaker_pins[0];
19661 if (pin)
19662 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19663 }
19664
19665 /* pcm configuration: identical with ALC880 */
19666 #define alc680_pcm_analog_playback alc880_pcm_analog_playback
19667 #define alc680_pcm_analog_capture alc880_pcm_analog_capture
19668 #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19669 #define alc680_pcm_digital_playback alc880_pcm_digital_playback
19670 #define alc680_pcm_digital_capture alc880_pcm_digital_capture
19671
19672 /*
19673 * BIOS auto configuration
19674 */
19675 static int alc680_parse_auto_config(struct hda_codec *codec)
19676 {
19677 struct alc_spec *spec = codec->spec;
19678 int err;
19679 static hda_nid_t alc680_ignore[] = { 0 };
19680
19681 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19682 alc680_ignore);
19683 if (err < 0)
19684 return err;
19685
19686 if (!spec->autocfg.line_outs) {
19687 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19688 spec->multiout.max_channels = 2;
19689 spec->no_analog = 1;
19690 goto dig_only;
19691 }
19692 return 0; /* can't find valid BIOS pin config */
19693 }
19694 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19695 if (err < 0)
19696 return err;
19697
19698 spec->multiout.max_channels = 2;
19699
19700 dig_only:
19701 /* digital only support output */
19702 alc_auto_parse_digital(codec);
19703 if (spec->kctls.list)
19704 add_mixer(spec, spec->kctls.list);
19705
19706 add_verb(spec, alc680_init_verbs);
19707
19708 err = alc_auto_add_mic_boost(codec);
19709 if (err < 0)
19710 return err;
19711
19712 return 1;
19713 }
19714
19715 #define alc680_auto_init_analog_input alc882_auto_init_analog_input
19716
19717 /* init callback for auto-configuration model -- overriding the default init */
19718 static void alc680_auto_init(struct hda_codec *codec)
19719 {
19720 struct alc_spec *spec = codec->spec;
19721 alc680_auto_init_multi_out(codec);
19722 alc680_auto_init_hp_out(codec);
19723 alc680_auto_init_analog_input(codec);
19724 alc_auto_init_digital(codec);
19725 if (spec->unsol_event)
19726 alc_inithook(codec);
19727 }
19728
19729 /*
19730 * configuration and preset
19731 */
19732 static const char *alc680_models[ALC680_MODEL_LAST] = {
19733 [ALC680_BASE] = "base",
19734 [ALC680_AUTO] = "auto",
19735 };
19736
19737 static struct snd_pci_quirk alc680_cfg_tbl[] = {
19738 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19739 {}
19740 };
19741
19742 static struct alc_config_preset alc680_presets[] = {
19743 [ALC680_BASE] = {
19744 .mixers = { alc680_base_mixer },
19745 .cap_mixer = alc680_master_capture_mixer,
19746 .init_verbs = { alc680_init_verbs },
19747 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19748 .dac_nids = alc680_dac_nids,
19749 .dig_out_nid = ALC680_DIGOUT_NID,
19750 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19751 .channel_mode = alc680_modes,
19752 .unsol_event = alc680_unsol_event,
19753 .setup = alc680_base_setup,
19754 .init_hook = alc680_inithook,
19755
19756 },
19757 };
19758
19759 static int patch_alc680(struct hda_codec *codec)
19760 {
19761 struct alc_spec *spec;
19762 int board_config;
19763 int err;
19764
19765 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19766 if (spec == NULL)
19767 return -ENOMEM;
19768
19769 codec->spec = spec;
19770
19771 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19772 alc680_models,
19773 alc680_cfg_tbl);
19774
19775 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19776 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19777 codec->chip_name);
19778 board_config = ALC680_AUTO;
19779 }
19780
19781 if (board_config == ALC680_AUTO) {
19782 /* automatic parse from the BIOS config */
19783 err = alc680_parse_auto_config(codec);
19784 if (err < 0) {
19785 alc_free(codec);
19786 return err;
19787 } else if (!err) {
19788 printk(KERN_INFO
19789 "hda_codec: Cannot set up configuration "
19790 "from BIOS. Using base mode...\n");
19791 board_config = ALC680_BASE;
19792 }
19793 }
19794
19795 if (board_config != ALC680_AUTO)
19796 setup_preset(codec, &alc680_presets[board_config]);
19797
19798 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19799 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
19800 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19801 spec->stream_digital_capture = &alc680_pcm_digital_capture;
19802
19803 if (!spec->adc_nids) {
19804 spec->adc_nids = alc680_adc_nids;
19805 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19806 }
19807
19808 if (!spec->cap_mixer)
19809 set_capture_mixer(codec);
19810
19811 spec->vmaster_nid = 0x02;
19812
19813 codec->patch_ops = alc_patch_ops;
19814 if (board_config == ALC680_AUTO)
19815 spec->init_hook = alc680_auto_init;
19816
19817 return 0;
19818 }
19819
19820 /*
19821 * patch entries
19822 */
19823 static struct hda_codec_preset snd_hda_preset_realtek[] = {
19824 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
19825 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
19826 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
19827 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
19828 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
19829 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
19830 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
19831 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
19832 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
19833 .patch = patch_alc861 },
19834 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19835 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19836 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
19837 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
19838 .patch = patch_alc882 },
19839 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19840 .patch = patch_alc662 },
19841 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
19842 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
19843 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
19844 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
19845 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
19846 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
19847 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
19848 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
19849 .patch = patch_alc882 },
19850 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
19851 .patch = patch_alc882 },
19852 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
19853 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
19854 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
19855 .patch = patch_alc882 },
19856 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
19857 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
19858 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
19859 {} /* terminator */
19860 };
19861
19862 MODULE_ALIAS("snd-hda-codec-id:10ec*");
19863
19864 MODULE_LICENSE("GPL");
19865 MODULE_DESCRIPTION("Realtek HD-audio codec");
19866
19867 static struct hda_codec_preset_list realtek_list = {
19868 .preset = snd_hda_preset_realtek,
19869 .owner = THIS_MODULE,
19870 };
19871
19872 static int __init patch_realtek_init(void)
19873 {
19874 return snd_hda_add_codec_preset(&realtek_list);
19875 }
19876
19877 static void __exit patch_realtek_exit(void)
19878 {
19879 snd_hda_delete_codec_preset(&realtek_list);
19880 }
19881
19882 module_init(patch_realtek_init)
19883 module_exit(patch_realtek_exit)