2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
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>
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.
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.
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
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"
36 #define ALC880_FRONT_EVENT 0x01
37 #define ALC880_DCVOL_EVENT 0x02
38 #define ALC880_HP_EVENT 0x04
39 #define ALC880_MIC_EVENT 0x08
41 /* ALC880 board config type */
65 #ifdef CONFIG_SND_DEBUG
69 ALC880_MODEL_LAST /* last tag */
83 #ifdef CONFIG_SND_DEBUG
87 ALC260_MODEL_LAST /* last tag */
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
111 ALC262_MODEL_LAST /* last tag */
121 ALC268_ACER_ASPIRE_ONE,
124 #ifdef CONFIG_SND_DEBUG
128 ALC268_MODEL_LAST /* last tag */
143 ALC269_MODEL_LAST /* last tag */
160 /* ALC861-VD models */
182 ALC662_ASUS_EEEPC_P701,
183 ALC662_ASUS_EEEPC_EP20,
225 ALC883_TARGA_2ch_DIG,
226 ALC883_TARGA_8ch_DIG,
229 ALC888_ACER_ASPIRE_4930G,
230 ALC888_ACER_ASPIRE_6530G,
231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G,
234 ALC883_MEDION_WIM2160,
236 ALC883_LENOVO_101E_2ch,
237 ALC883_LENOVO_NB0763,
238 ALC888_LENOVO_MS7195_DIG,
246 ALC883_FUJITSU_PI2515,
247 ALC888_FUJITSU_XA3530,
248 ALC883_3ST_6ch_INTEL,
268 #define GPIO_MASK 0x03
270 /* extra amp-initialization sequence types */
279 struct alc_mic_route {
281 unsigned char mux_idx;
282 unsigned char amix_idx;
288 struct snd_jack *jack;
291 #define MUX_IDX_UNDEF ((unsigned char)-1)
293 struct alc_customize_define {
294 unsigned int sku_cfg;
295 unsigned char port_connectivity;
296 unsigned char check_sum;
297 unsigned char customization;
298 unsigned char external_amp;
299 unsigned int enable_pcbeep:1;
300 unsigned int platform_type:1;
302 unsigned int override:1;
303 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
309 /* codec parameterization */
310 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
311 unsigned int num_mixers;
312 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
313 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
315 const struct hda_verb *init_verbs[10]; /* initialization verbs
319 unsigned int num_init_verbs;
321 char stream_name_analog[32]; /* analog PCM stream */
322 struct hda_pcm_stream *stream_analog_playback;
323 struct hda_pcm_stream *stream_analog_capture;
324 struct hda_pcm_stream *stream_analog_alt_playback;
325 struct hda_pcm_stream *stream_analog_alt_capture;
327 char stream_name_digital[32]; /* digital PCM stream */
328 struct hda_pcm_stream *stream_digital_playback;
329 struct hda_pcm_stream *stream_digital_capture;
332 struct hda_multi_out multiout; /* playback set-up
333 * max_channels, dacs must be set
334 * dig_out_nid and hp_nid are optional
336 hda_nid_t alt_dac_nid;
337 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
341 unsigned int num_adc_nids;
343 hda_nid_t *capsrc_nids;
344 hda_nid_t dig_in_nid; /* digital-in NID; optional */
346 /* capture setup for dynamic dual-adc switch */
347 unsigned int cur_adc_idx;
349 unsigned int cur_adc_stream_tag;
350 unsigned int cur_adc_format;
353 unsigned int num_mux_defs;
354 const struct hda_input_mux *input_mux;
355 unsigned int cur_mux[3];
356 struct alc_mic_route ext_mic;
357 struct alc_mic_route int_mic;
360 const struct hda_channel_mode *channel_mode;
361 int num_channel_mode;
363 int const_channel_count;
364 int ext_channel_count;
366 /* PCM information */
367 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
370 struct snd_array jacks;
372 /* dynamic controls, init_verbs and input_mux */
373 struct auto_pin_cfg autocfg;
374 struct alc_customize_define cdefine;
375 struct snd_array kctls;
376 struct hda_input_mux private_imux[3];
377 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
378 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
379 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
382 void (*init_hook)(struct hda_codec *codec);
383 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
384 #ifdef CONFIG_SND_HDA_POWER_SAVE
385 void (*power_hook)(struct hda_codec *codec);
388 /* for pin sensing */
389 unsigned int sense_updated: 1;
390 unsigned int jack_present: 1;
391 unsigned int master_sw: 1;
392 unsigned int auto_mic:1;
395 unsigned int no_analog :1; /* digital I/O only */
396 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
398 int codec_variant; /* flag for other variants */
400 /* for virtual master */
401 hda_nid_t vmaster_nid;
402 #ifdef CONFIG_SND_HDA_POWER_SAVE
403 struct hda_loopback_check loopback;
408 unsigned int pll_coef_idx, pll_coef_bit;
412 const struct alc_fixup *fixup_list;
413 const char *fixup_name;
417 * configuration template - to be copied to the spec instance
419 struct alc_config_preset {
420 struct snd_kcontrol_new *mixers[5]; /* should be identical size
423 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
424 const struct hda_verb *init_verbs[5];
425 unsigned int num_dacs;
427 hda_nid_t dig_out_nid; /* optional */
428 hda_nid_t hp_nid; /* optional */
429 hda_nid_t *slave_dig_outs;
430 unsigned int num_adc_nids;
432 hda_nid_t *capsrc_nids;
433 hda_nid_t dig_in_nid;
434 unsigned int num_channel_mode;
435 const struct hda_channel_mode *channel_mode;
437 int const_channel_count;
438 unsigned int num_mux_defs;
439 const struct hda_input_mux *input_mux;
440 void (*unsol_event)(struct hda_codec *, unsigned int);
441 void (*setup)(struct hda_codec *);
442 void (*init_hook)(struct hda_codec *);
443 #ifdef CONFIG_SND_HDA_POWER_SAVE
444 struct hda_amp_list *loopbacks;
445 void (*power_hook)(struct hda_codec *codec);
453 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_info *uinfo)
456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
457 struct alc_spec *spec = codec->spec;
458 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
459 if (mux_idx >= spec->num_mux_defs)
461 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
463 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
466 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
467 struct snd_ctl_elem_value *ucontrol)
469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
470 struct alc_spec *spec = codec->spec;
471 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
473 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
477 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
478 struct snd_ctl_elem_value *ucontrol)
480 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
481 struct alc_spec *spec = codec->spec;
482 const struct hda_input_mux *imux;
483 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
484 unsigned int mux_idx;
485 hda_nid_t nid = spec->capsrc_nids ?
486 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
489 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
490 imux = &spec->input_mux[mux_idx];
491 if (!imux->num_items && mux_idx > 0)
492 imux = &spec->input_mux[0];
494 type = get_wcaps_type(get_wcaps(codec, nid));
495 if (type == AC_WID_AUD_MIX) {
496 /* Matrix-mixer style (e.g. ALC882) */
497 unsigned int *cur_val = &spec->cur_mux[adc_idx];
500 idx = ucontrol->value.enumerated.item[0];
501 if (idx >= imux->num_items)
502 idx = imux->num_items - 1;
505 for (i = 0; i < imux->num_items; i++) {
506 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
507 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
508 imux->items[i].index,
514 /* MUX style (e.g. ALC880) */
515 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
516 &spec->cur_mux[adc_idx]);
521 * channel mode setting
523 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_info *uinfo)
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
528 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
529 spec->num_channel_mode);
532 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
533 struct snd_ctl_elem_value *ucontrol)
535 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
536 struct alc_spec *spec = codec->spec;
537 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
538 spec->num_channel_mode,
539 spec->ext_channel_count);
542 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_value *ucontrol)
545 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546 struct alc_spec *spec = codec->spec;
547 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
548 spec->num_channel_mode,
549 &spec->ext_channel_count);
550 if (err >= 0 && !spec->const_channel_count) {
551 spec->multiout.max_channels = spec->ext_channel_count;
552 if (spec->need_dac_fix)
553 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
559 * Control the mode of pin widget settings via the mixer. "pc" is used
560 * instead of "%" to avoid consequences of accidently treating the % as
561 * being part of a format specifier. Maximum allowed length of a value is
562 * 63 characters plus NULL terminator.
564 * Note: some retasking pin complexes seem to ignore requests for input
565 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
566 * are requested. Therefore order this list so that this behaviour will not
567 * cause problems when mixer clients move through the enum sequentially.
568 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
571 static char *alc_pin_mode_names[] = {
572 "Mic 50pc bias", "Mic 80pc bias",
573 "Line in", "Line out", "Headphone out",
575 static unsigned char alc_pin_mode_values[] = {
576 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
578 /* The control can present all 5 options, or it can limit the options based
579 * in the pin being assumed to be exclusively an input or an output pin. In
580 * addition, "input" pins may or may not process the mic bias option
581 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
582 * accept requests for bias as of chip versions up to March 2006) and/or
583 * wiring in the computer.
585 #define ALC_PIN_DIR_IN 0x00
586 #define ALC_PIN_DIR_OUT 0x01
587 #define ALC_PIN_DIR_INOUT 0x02
588 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
589 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
591 /* Info about the pin modes supported by the different pin direction modes.
592 * For each direction the minimum and maximum values are given.
594 static signed char alc_pin_mode_dir_info[5][2] = {
595 { 0, 2 }, /* ALC_PIN_DIR_IN */
596 { 3, 4 }, /* ALC_PIN_DIR_OUT */
597 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
598 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
599 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
601 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
602 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
603 #define alc_pin_mode_n_items(_dir) \
604 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
606 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
607 struct snd_ctl_elem_info *uinfo)
609 unsigned int item_num = uinfo->value.enumerated.item;
610 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
612 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
614 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
616 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
617 item_num = alc_pin_mode_min(dir);
618 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
622 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
623 struct snd_ctl_elem_value *ucontrol)
626 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
627 hda_nid_t nid = kcontrol->private_value & 0xffff;
628 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
629 long *valp = ucontrol->value.integer.value;
630 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
631 AC_VERB_GET_PIN_WIDGET_CONTROL,
634 /* Find enumerated value for current pinctl setting */
635 i = alc_pin_mode_min(dir);
636 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
638 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
642 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 hda_nid_t nid = kcontrol->private_value & 0xffff;
648 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
649 long val = *ucontrol->value.integer.value;
650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
651 AC_VERB_GET_PIN_WIDGET_CONTROL,
654 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
655 val = alc_pin_mode_min(dir);
657 change = pinctl != alc_pin_mode_values[val];
659 /* Set pin mode to that requested */
660 snd_hda_codec_write_cache(codec, nid, 0,
661 AC_VERB_SET_PIN_WIDGET_CONTROL,
662 alc_pin_mode_values[val]);
664 /* Also enable the retasking pin's input/output as required
665 * for the requested pin mode. Enum values of 2 or less are
668 * Dynamically switching the input/output buffers probably
669 * reduces noise slightly (particularly on input) so we'll
670 * do it. However, having both input and output buffers
671 * enabled simultaneously doesn't seem to be problematic if
672 * this turns out to be necessary in the future.
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
676 HDA_AMP_MUTE, HDA_AMP_MUTE);
677 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
680 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
681 HDA_AMP_MUTE, HDA_AMP_MUTE);
682 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
689 #define ALC_PIN_MODE(xname, nid, dir) \
690 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
691 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
692 .info = alc_pin_mode_info, \
693 .get = alc_pin_mode_get, \
694 .put = alc_pin_mode_put, \
695 .private_value = nid | (dir<<16) }
697 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
698 * together using a mask with more than one bit set. This control is
699 * currently used only by the ALC260 test model. At this stage they are not
700 * needed for any "production" models.
702 #ifdef CONFIG_SND_DEBUG
703 #define alc_gpio_data_info snd_ctl_boolean_mono_info
705 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
706 struct snd_ctl_elem_value *ucontrol)
708 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
709 hda_nid_t nid = kcontrol->private_value & 0xffff;
710 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
711 long *valp = ucontrol->value.integer.value;
712 unsigned int val = snd_hda_codec_read(codec, nid, 0,
713 AC_VERB_GET_GPIO_DATA, 0x00);
715 *valp = (val & mask) != 0;
718 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
719 struct snd_ctl_elem_value *ucontrol)
722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723 hda_nid_t nid = kcontrol->private_value & 0xffff;
724 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
725 long val = *ucontrol->value.integer.value;
726 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
727 AC_VERB_GET_GPIO_DATA,
730 /* Set/unset the masked GPIO bit(s) as needed */
731 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
736 snd_hda_codec_write_cache(codec, nid, 0,
737 AC_VERB_SET_GPIO_DATA, gpio_data);
741 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
742 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
744 .info = alc_gpio_data_info, \
745 .get = alc_gpio_data_get, \
746 .put = alc_gpio_data_put, \
747 .private_value = nid | (mask<<16) }
748 #endif /* CONFIG_SND_DEBUG */
750 /* A switch control to allow the enabling of the digital IO pins on the
751 * ALC260. This is incredibly simplistic; the intention of this control is
752 * to provide something in the test model allowing digital outputs to be
753 * identified if present. If models are found which can utilise these
754 * outputs a more complete mixer control can be devised for those models if
757 #ifdef CONFIG_SND_DEBUG
758 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
760 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
761 struct snd_ctl_elem_value *ucontrol)
763 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
764 hda_nid_t nid = kcontrol->private_value & 0xffff;
765 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
766 long *valp = ucontrol->value.integer.value;
767 unsigned int val = snd_hda_codec_read(codec, nid, 0,
768 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
770 *valp = (val & mask) != 0;
773 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
774 struct snd_ctl_elem_value *ucontrol)
777 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
778 hda_nid_t nid = kcontrol->private_value & 0xffff;
779 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
780 long val = *ucontrol->value.integer.value;
781 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
782 AC_VERB_GET_DIGI_CONVERT_1,
785 /* Set/unset the masked control bit(s) as needed */
786 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
791 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
796 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
797 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
798 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
799 .info = alc_spdif_ctrl_info, \
800 .get = alc_spdif_ctrl_get, \
801 .put = alc_spdif_ctrl_put, \
802 .private_value = nid | (mask<<16) }
803 #endif /* CONFIG_SND_DEBUG */
805 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
806 * Again, this is only used in the ALC26x test models to help identify when
807 * the EAPD line must be asserted for features to work.
809 #ifdef CONFIG_SND_DEBUG
810 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
812 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
813 struct snd_ctl_elem_value *ucontrol)
815 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
816 hda_nid_t nid = kcontrol->private_value & 0xffff;
817 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
818 long *valp = ucontrol->value.integer.value;
819 unsigned int val = snd_hda_codec_read(codec, nid, 0,
820 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
822 *valp = (val & mask) != 0;
826 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol)
830 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
831 hda_nid_t nid = kcontrol->private_value & 0xffff;
832 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
833 long val = *ucontrol->value.integer.value;
834 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
835 AC_VERB_GET_EAPD_BTLENABLE,
838 /* Set/unset the masked control bit(s) as needed */
839 change = (!val ? 0 : mask) != (ctrl_data & mask);
844 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
850 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
851 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
852 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
853 .info = alc_eapd_ctrl_info, \
854 .get = alc_eapd_ctrl_get, \
855 .put = alc_eapd_ctrl_put, \
856 .private_value = nid | (mask<<16) }
857 #endif /* CONFIG_SND_DEBUG */
860 * set up the input pin config (depending on the given auto-pin type)
862 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
865 unsigned int val = PIN_IN;
867 if (auto_pin_type == AUTO_PIN_MIC) {
870 oldval = snd_hda_codec_read(codec, nid, 0,
871 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
872 pincap = snd_hda_query_pin_caps(codec, nid);
873 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
874 /* if the default pin setup is vref50, we give it priority */
875 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
877 else if (pincap & AC_PINCAP_VREF_50)
879 else if (pincap & AC_PINCAP_VREF_100)
881 else if (pincap & AC_PINCAP_VREF_GRD)
884 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
887 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
889 struct alc_spec *spec = codec->spec;
890 struct auto_pin_cfg *cfg = &spec->autocfg;
892 if (!cfg->line_outs) {
893 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
894 cfg->line_out_pins[cfg->line_outs])
897 if (!cfg->speaker_outs) {
898 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
899 cfg->speaker_pins[cfg->speaker_outs])
903 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
904 cfg->hp_pins[cfg->hp_outs])
911 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
913 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
915 spec->mixers[spec->num_mixers++] = mix;
918 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
920 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
922 spec->init_verbs[spec->num_init_verbs++] = verb;
926 * set up from the preset table
928 static void setup_preset(struct hda_codec *codec,
929 const struct alc_config_preset *preset)
931 struct alc_spec *spec = codec->spec;
934 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
935 add_mixer(spec, preset->mixers[i]);
936 spec->cap_mixer = preset->cap_mixer;
937 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
939 add_verb(spec, preset->init_verbs[i]);
941 spec->channel_mode = preset->channel_mode;
942 spec->num_channel_mode = preset->num_channel_mode;
943 spec->need_dac_fix = preset->need_dac_fix;
944 spec->const_channel_count = preset->const_channel_count;
946 if (preset->const_channel_count)
947 spec->multiout.max_channels = preset->const_channel_count;
949 spec->multiout.max_channels = spec->channel_mode[0].channels;
950 spec->ext_channel_count = spec->channel_mode[0].channels;
952 spec->multiout.num_dacs = preset->num_dacs;
953 spec->multiout.dac_nids = preset->dac_nids;
954 spec->multiout.dig_out_nid = preset->dig_out_nid;
955 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
956 spec->multiout.hp_nid = preset->hp_nid;
958 spec->num_mux_defs = preset->num_mux_defs;
959 if (!spec->num_mux_defs)
960 spec->num_mux_defs = 1;
961 spec->input_mux = preset->input_mux;
963 spec->num_adc_nids = preset->num_adc_nids;
964 spec->adc_nids = preset->adc_nids;
965 spec->capsrc_nids = preset->capsrc_nids;
966 spec->dig_in_nid = preset->dig_in_nid;
968 spec->unsol_event = preset->unsol_event;
969 spec->init_hook = preset->init_hook;
970 #ifdef CONFIG_SND_HDA_POWER_SAVE
971 spec->power_hook = preset->power_hook;
972 spec->loopback.amplist = preset->loopbacks;
976 preset->setup(codec);
978 alc_fixup_autocfg_pin_nums(codec);
981 /* Enable GPIO mask and set output */
982 static struct hda_verb alc_gpio1_init_verbs[] = {
983 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
985 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
989 static struct hda_verb alc_gpio2_init_verbs[] = {
990 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
992 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
996 static struct hda_verb alc_gpio3_init_verbs[] = {
997 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
998 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
999 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1004 * Fix hardware PLL issue
1005 * On some codecs, the analog PLL gating control must be off while
1006 * the default value is 1.
1008 static void alc_fix_pll(struct hda_codec *codec)
1010 struct alc_spec *spec = codec->spec;
1015 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1016 spec->pll_coef_idx);
1017 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1018 AC_VERB_GET_PROC_COEF, 0);
1019 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1020 spec->pll_coef_idx);
1021 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1022 val & ~(1 << spec->pll_coef_bit));
1025 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1026 unsigned int coef_idx, unsigned int coef_bit)
1028 struct alc_spec *spec = codec->spec;
1029 spec->pll_nid = nid;
1030 spec->pll_coef_idx = coef_idx;
1031 spec->pll_coef_bit = coef_bit;
1035 #ifdef CONFIG_SND_HDA_INPUT_JACK
1036 static void alc_free_jack_priv(struct snd_jack *jack)
1038 struct alc_jack *jacks = jack->private_data;
1043 static int alc_add_jack(struct hda_codec *codec,
1044 hda_nid_t nid, int type)
1046 struct alc_spec *spec;
1047 struct alc_jack *jack;
1052 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1053 jack = snd_array_new(&spec->jacks);
1059 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1061 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1064 jack->jack->private_data = jack;
1065 jack->jack->private_free = alc_free_jack_priv;
1069 static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1071 struct alc_spec *spec = codec->spec;
1072 struct alc_jack *jacks = spec->jacks.list;
1076 for (i = 0; i < spec->jacks.used; i++) {
1077 if (jacks->nid == nid) {
1078 unsigned int present;
1079 present = snd_hda_jack_detect(codec, nid);
1081 present = (present) ? jacks->type : 0;
1083 snd_jack_report(jacks->jack, present);
1090 static int alc_init_jacks(struct hda_codec *codec)
1092 struct alc_spec *spec = codec->spec;
1094 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1095 unsigned int mic_nid = spec->ext_mic.pin;
1098 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1101 alc_report_jack(codec, hp_nid);
1105 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1108 alc_report_jack(codec, mic_nid);
1114 static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1118 static inline int alc_init_jacks(struct hda_codec *codec)
1124 static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1126 struct alc_spec *spec = codec->spec;
1131 spec->jack_present = 0;
1132 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1133 nid = spec->autocfg.hp_pins[i];
1136 if (snd_hda_jack_detect(codec, nid)) {
1137 spec->jack_present = 1;
1140 alc_report_jack(codec, spec->autocfg.hp_pins[i]);
1143 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1144 /* Toggle internal speakers muting */
1145 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1146 nid = spec->autocfg.speaker_pins[i];
1150 snd_hda_codec_write(codec, nid, 0,
1151 AC_VERB_SET_PIN_WIDGET_CONTROL,
1152 spec->jack_present ? 0 : PIN_OUT);
1154 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1155 HDA_AMP_MUTE, mute);
1160 static void alc_automute_pin(struct hda_codec *codec)
1162 alc_automute_speaker(codec, 1);
1165 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1168 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1171 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1172 for (i = 0; i < nums; i++)
1178 /* switch the current ADC according to the jack state */
1179 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1181 struct alc_spec *spec = codec->spec;
1182 unsigned int present;
1185 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1187 spec->cur_adc_idx = 1;
1189 spec->cur_adc_idx = 0;
1190 new_adc = spec->adc_nids[spec->cur_adc_idx];
1191 if (spec->cur_adc && spec->cur_adc != new_adc) {
1192 /* stream is running, let's swap the current ADC */
1193 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1194 spec->cur_adc = new_adc;
1195 snd_hda_codec_setup_stream(codec, new_adc,
1196 spec->cur_adc_stream_tag, 0,
1197 spec->cur_adc_format);
1201 static void alc_mic_automute(struct hda_codec *codec)
1203 struct alc_spec *spec = codec->spec;
1204 struct alc_mic_route *dead, *alive;
1205 unsigned int present, type;
1208 if (!spec->auto_mic)
1210 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1212 if (snd_BUG_ON(!spec->adc_nids))
1215 if (spec->dual_adc_switch) {
1216 alc_dual_mic_adc_auto_switch(codec);
1220 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1222 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1224 alive = &spec->ext_mic;
1225 dead = &spec->int_mic;
1227 alive = &spec->int_mic;
1228 dead = &spec->ext_mic;
1231 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1232 if (type == AC_WID_AUD_MIX) {
1233 /* Matrix-mixer style (e.g. ALC882) */
1234 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1237 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1239 HDA_AMP_MUTE, HDA_AMP_MUTE);
1241 /* MUX style (e.g. ALC880) */
1242 snd_hda_codec_write_cache(codec, cap_nid, 0,
1243 AC_VERB_SET_CONNECT_SEL,
1246 alc_report_jack(codec, spec->ext_mic.pin);
1248 /* FIXME: analog mixer */
1251 /* unsolicited event for HP jack sensing */
1252 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1254 if (codec->vendor_id == 0x10ec0880)
1259 case ALC880_HP_EVENT:
1260 alc_automute_pin(codec);
1262 case ALC880_MIC_EVENT:
1263 alc_mic_automute(codec);
1268 static void alc_inithook(struct hda_codec *codec)
1270 alc_automute_pin(codec);
1271 alc_mic_automute(codec);
1274 /* additional initialization for ALC888 variants */
1275 static void alc888_coef_init(struct hda_codec *codec)
1279 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1280 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1281 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1282 if ((tmp & 0xf0) == 0x20)
1284 snd_hda_codec_read(codec, 0x20, 0,
1285 AC_VERB_SET_PROC_COEF, 0x830);
1288 snd_hda_codec_read(codec, 0x20, 0,
1289 AC_VERB_SET_PROC_COEF, 0x3030);
1292 static void alc889_coef_init(struct hda_codec *codec)
1296 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1297 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1298 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1299 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1302 /* turn on/off EAPD control (only if available) */
1303 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1305 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1307 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1308 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1312 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1317 case ALC_INIT_GPIO1:
1318 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1320 case ALC_INIT_GPIO2:
1321 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1323 case ALC_INIT_GPIO3:
1324 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1326 case ALC_INIT_DEFAULT:
1327 switch (codec->vendor_id) {
1329 set_eapd(codec, 0x0f, 1);
1330 set_eapd(codec, 0x10, 1);
1343 set_eapd(codec, 0x14, 1);
1344 set_eapd(codec, 0x15, 1);
1347 switch (codec->vendor_id) {
1349 snd_hda_codec_write(codec, 0x1a, 0,
1350 AC_VERB_SET_COEF_INDEX, 7);
1351 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1352 AC_VERB_GET_PROC_COEF, 0);
1353 snd_hda_codec_write(codec, 0x1a, 0,
1354 AC_VERB_SET_COEF_INDEX, 7);
1355 snd_hda_codec_write(codec, 0x1a, 0,
1356 AC_VERB_SET_PROC_COEF,
1366 alc889_coef_init(codec);
1369 alc888_coef_init(codec);
1371 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1374 snd_hda_codec_write(codec, 0x20, 0,
1375 AC_VERB_SET_COEF_INDEX, 7);
1376 tmp = snd_hda_codec_read(codec, 0x20, 0,
1377 AC_VERB_GET_PROC_COEF, 0);
1378 snd_hda_codec_write(codec, 0x20, 0,
1379 AC_VERB_SET_COEF_INDEX, 7);
1380 snd_hda_codec_write(codec, 0x20, 0,
1381 AC_VERB_SET_PROC_COEF,
1390 static void alc_init_auto_hp(struct hda_codec *codec)
1392 struct alc_spec *spec = codec->spec;
1393 struct auto_pin_cfg *cfg = &spec->autocfg;
1396 if (!cfg->hp_pins[0]) {
1397 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1401 if (!cfg->speaker_pins[0]) {
1402 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1404 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1405 sizeof(cfg->speaker_pins));
1406 cfg->speaker_outs = cfg->line_outs;
1409 if (!cfg->hp_pins[0]) {
1410 memcpy(cfg->hp_pins, cfg->line_out_pins,
1411 sizeof(cfg->hp_pins));
1412 cfg->hp_outs = cfg->line_outs;
1415 for (i = 0; i < cfg->hp_outs; i++) {
1416 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1418 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
1419 AC_VERB_SET_UNSOLICITED_ENABLE,
1420 AC_USRSP_EN | ALC880_HP_EVENT);
1422 spec->unsol_event = alc_sku_unsol_event;
1425 static void alc_init_auto_mic(struct hda_codec *codec)
1427 struct alc_spec *spec = codec->spec;
1428 struct auto_pin_cfg *cfg = &spec->autocfg;
1429 hda_nid_t fixed, ext;
1432 /* there must be only two mic inputs exclusively */
1433 for (i = 0; i < cfg->num_inputs; i++)
1434 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
1438 for (i = 0; i < cfg->num_inputs; i++) {
1439 hda_nid_t nid = cfg->inputs[i].pin;
1440 unsigned int defcfg;
1441 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1442 switch (snd_hda_get_input_pin_attr(defcfg)) {
1443 case INPUT_PIN_ATTR_INT:
1445 return; /* already occupied */
1448 case INPUT_PIN_ATTR_UNUSED:
1449 return; /* invalid entry */
1452 return; /* already occupied */
1459 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1460 return; /* no unsol support */
1461 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1463 spec->ext_mic.pin = ext;
1464 spec->int_mic.pin = fixed;
1465 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1466 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1468 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1469 AC_VERB_SET_UNSOLICITED_ENABLE,
1470 AC_USRSP_EN | ALC880_MIC_EVENT);
1471 spec->unsol_event = alc_sku_unsol_event;
1474 /* Could be any non-zero and even value. When used as fixup, tells
1475 * the driver to ignore any present sku defines.
1477 #define ALC_FIXUP_SKU_IGNORE (2)
1479 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1481 unsigned int ass, tmp, i;
1483 struct alc_spec *spec = codec->spec;
1485 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1487 if (spec->cdefine.fixup) {
1488 ass = spec->cdefine.sku_cfg;
1489 if (ass == ALC_FIXUP_SKU_IGNORE)
1494 ass = codec->subsystem_id & 0xffff;
1495 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1499 if (codec->vendor_id == 0x10ec0260)
1501 ass = snd_hda_codec_get_pincfg(codec, nid);
1504 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1505 codec->chip_name, ass);
1511 for (i = 1; i < 16; i++) {
1515 if (((ass >> 16) & 0xf) != tmp)
1518 spec->cdefine.port_connectivity = ass >> 30;
1519 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1520 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1521 spec->cdefine.customization = ass >> 8;
1523 spec->cdefine.sku_cfg = ass;
1524 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1525 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1526 spec->cdefine.swap = (ass & 0x2) >> 1;
1527 spec->cdefine.override = ass & 0x1;
1529 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1530 nid, spec->cdefine.sku_cfg);
1531 snd_printd("SKU: port_connectivity=0x%x\n",
1532 spec->cdefine.port_connectivity);
1533 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1534 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1535 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1536 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1537 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1538 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1539 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1544 /* check subsystem ID and set up device-specific initialization;
1545 * return 1 if initialized, 0 if invalid SSID
1547 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1548 * 31 ~ 16 : Manufacture ID
1550 * 7 ~ 0 : Assembly ID
1551 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1553 static int alc_subsystem_id(struct hda_codec *codec,
1554 hda_nid_t porta, hda_nid_t porte,
1555 hda_nid_t portd, hda_nid_t porti)
1557 unsigned int ass, tmp, i;
1559 struct alc_spec *spec = codec->spec;
1561 if (spec->cdefine.fixup) {
1562 ass = spec->cdefine.sku_cfg;
1563 if (ass == ALC_FIXUP_SKU_IGNORE)
1568 ass = codec->subsystem_id & 0xffff;
1569 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1572 /* invalid SSID, check the special NID pin defcfg instead */
1574 * 31~30 : port connectivity
1577 * 19~16 : Check sum (15:1)
1582 if (codec->vendor_id == 0x10ec0260)
1584 ass = snd_hda_codec_get_pincfg(codec, nid);
1585 snd_printd("realtek: No valid SSID, "
1586 "checking pincfg 0x%08x for NID 0x%x\n",
1590 if ((ass >> 30) != 1) /* no physical connection */
1595 for (i = 1; i < 16; i++) {
1599 if (((ass >> 16) & 0xf) != tmp)
1602 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1603 ass & 0xffff, codec->vendor_id);
1607 * 2 : 0 --> Desktop, 1 --> Laptop
1608 * 3~5 : External Amplifier control
1611 tmp = (ass & 0x38) >> 3; /* external Amp control */
1614 spec->init_amp = ALC_INIT_GPIO1;
1617 spec->init_amp = ALC_INIT_GPIO2;
1620 spec->init_amp = ALC_INIT_GPIO3;
1624 spec->init_amp = ALC_INIT_DEFAULT;
1628 /* is laptop or Desktop and enable the function "Mute internal speaker
1629 * when the external headphone out jack is plugged"
1631 if (!(ass & 0x8000))
1634 * 10~8 : Jack location
1635 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1637 * 15 : 1 --> enable the function "Mute internal speaker
1638 * when the external headphone out jack is plugged"
1640 if (!spec->autocfg.hp_pins[0]) {
1642 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1653 for (i = 0; i < spec->autocfg.line_outs; i++)
1654 if (spec->autocfg.line_out_pins[i] == nid)
1656 spec->autocfg.hp_pins[0] = nid;
1659 alc_init_auto_hp(codec);
1660 alc_init_auto_mic(codec);
1664 static void alc_ssid_check(struct hda_codec *codec,
1665 hda_nid_t porta, hda_nid_t porte,
1666 hda_nid_t portd, hda_nid_t porti)
1668 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1669 struct alc_spec *spec = codec->spec;
1670 snd_printd("realtek: "
1671 "Enable default setup for auto mode as fallback\n");
1672 spec->init_amp = ALC_INIT_DEFAULT;
1673 alc_init_auto_hp(codec);
1674 alc_init_auto_mic(codec);
1679 * Fix-up pin default configurations and add default verbs
1687 struct alc_model_fixup {
1696 const struct alc_pincfg *pins;
1697 const struct hda_verb *verbs;
1698 void (*func)(struct hda_codec *codec,
1699 const struct alc_fixup *fix,
1715 ALC_FIXUP_ACT_PRE_PROBE,
1716 ALC_FIXUP_ACT_PROBE,
1719 static void alc_apply_fixup(struct hda_codec *codec, int action)
1721 struct alc_spec *spec = codec->spec;
1722 int id = spec->fixup_id;
1723 const char *modelname = spec->fixup_name;
1726 if (!spec->fixup_list)
1730 const struct alc_fixup *fix = spec->fixup_list + id;
1731 const struct alc_pincfg *cfg;
1733 switch (fix->type) {
1735 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1737 snd_printdd(KERN_INFO "hda_codec: %s: "
1738 "Apply sku override for %s\n",
1739 codec->chip_name, modelname);
1740 spec->cdefine.sku_cfg = fix->v.sku;
1741 spec->cdefine.fixup = 1;
1743 case ALC_FIXUP_PINS:
1745 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1747 snd_printdd(KERN_INFO "hda_codec: %s: "
1748 "Apply pincfg for %s\n",
1749 codec->chip_name, modelname);
1750 for (; cfg->nid; cfg++)
1751 snd_hda_codec_set_pincfg(codec, cfg->nid,
1754 case ALC_FIXUP_VERBS:
1755 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1757 snd_printdd(KERN_INFO "hda_codec: %s: "
1758 "Apply fix-verbs for %s\n",
1759 codec->chip_name, modelname);
1760 add_verb(codec->spec, fix->v.verbs);
1762 case ALC_FIXUP_FUNC:
1765 snd_printdd(KERN_INFO "hda_codec: %s: "
1766 "Apply fix-func for %s\n",
1767 codec->chip_name, modelname);
1768 fix->v.func(codec, fix, action);
1771 snd_printk(KERN_ERR "hda_codec: %s: "
1772 "Invalid fixup type %d\n",
1773 codec->chip_name, fix->type);
1776 if (!fix[id].chained)
1780 id = fix[id].chain_id;
1784 static void alc_pick_fixup(struct hda_codec *codec,
1785 const struct alc_model_fixup *models,
1786 const struct snd_pci_quirk *quirk,
1787 const struct alc_fixup *fixlist)
1789 struct alc_spec *spec = codec->spec;
1791 const char *name = NULL;
1793 if (codec->modelname && models) {
1794 while (models->name) {
1795 if (!strcmp(codec->modelname, models->name)) {
1797 name = models->name;
1804 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1807 #ifdef CONFIG_SND_DEBUG_VERBOSE
1813 spec->fixup_id = id;
1815 spec->fixup_list = fixlist;
1816 spec->fixup_name = name;
1820 static int alc_read_coef_idx(struct hda_codec *codec,
1821 unsigned int coef_idx)
1824 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1826 val = snd_hda_codec_read(codec, 0x20, 0,
1827 AC_VERB_GET_PROC_COEF, 0);
1831 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1832 unsigned int coef_val)
1834 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1836 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1840 /* set right pin controls for digital I/O */
1841 static void alc_auto_init_digital(struct hda_codec *codec)
1843 struct alc_spec *spec = codec->spec;
1847 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1848 pin = spec->autocfg.dig_out_pins[i];
1850 snd_hda_codec_write(codec, pin, 0,
1851 AC_VERB_SET_PIN_WIDGET_CONTROL,
1855 pin = spec->autocfg.dig_in_pin;
1857 snd_hda_codec_write(codec, pin, 0,
1858 AC_VERB_SET_PIN_WIDGET_CONTROL,
1862 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1863 static void alc_auto_parse_digital(struct hda_codec *codec)
1865 struct alc_spec *spec = codec->spec;
1869 /* support multiple SPDIFs; the secondary is set up as a slave */
1870 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1871 err = snd_hda_get_connections(codec,
1872 spec->autocfg.dig_out_pins[i],
1877 spec->multiout.dig_out_nid = dig_nid;
1878 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1880 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1881 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1883 spec->slave_dig_outs[i - 1] = dig_nid;
1887 if (spec->autocfg.dig_in_pin) {
1888 dig_nid = codec->start_nid;
1889 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1890 unsigned int wcaps = get_wcaps(codec, dig_nid);
1891 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1893 if (!(wcaps & AC_WCAP_DIGITAL))
1895 if (!(wcaps & AC_WCAP_CONN_LIST))
1897 err = get_connection_index(codec, dig_nid,
1898 spec->autocfg.dig_in_pin);
1900 spec->dig_in_nid = dig_nid;
1914 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1915 /* Mic-in jack as mic in */
1916 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1917 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1918 /* Line-in jack as Line in */
1919 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1920 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1921 /* Line-Out as Front */
1922 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1929 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1930 /* Mic-in jack as mic in */
1931 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1932 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1933 /* Line-in jack as Surround */
1934 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1935 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1936 /* Line-Out as Front */
1937 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1944 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1945 /* Mic-in jack as CLFE */
1946 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1947 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1948 /* Line-in jack as Surround */
1949 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1950 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1951 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1952 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1959 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1960 /* Mic-in jack as CLFE */
1961 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1962 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1963 /* Line-in jack as Surround */
1964 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1965 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1966 /* Line-Out as Side */
1967 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1971 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1972 { 2, alc888_4ST_ch2_intel_init },
1973 { 4, alc888_4ST_ch4_intel_init },
1974 { 6, alc888_4ST_ch6_intel_init },
1975 { 8, alc888_4ST_ch8_intel_init },
1979 * ALC888 Fujitsu Siemens Amillo xa3530
1982 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1983 /* Front Mic: set to PIN_IN (empty by default) */
1984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1985 /* Connect Internal HP to Front */
1986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1987 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1988 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1989 /* Connect Bass HP to Front */
1990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1991 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1992 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1993 /* Connect Line-Out side jack (SPDIF) to Side */
1994 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1995 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1996 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1997 /* Connect Mic jack to CLFE */
1998 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1999 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2000 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2001 /* Connect Line-in jack to Surround */
2002 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2003 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2004 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2005 /* Connect HP out jack to Front */
2006 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2007 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2009 /* Enable unsolicited event for HP jack and Line-out jack */
2010 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2011 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2015 static void alc_automute_amp(struct hda_codec *codec)
2017 alc_automute_speaker(codec, 0);
2020 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
2023 if (codec->vendor_id == 0x10ec0880)
2027 if (res == ALC880_HP_EVENT)
2028 alc_automute_amp(codec);
2031 static void alc889_automute_setup(struct hda_codec *codec)
2033 struct alc_spec *spec = codec->spec;
2035 spec->autocfg.hp_pins[0] = 0x15;
2036 spec->autocfg.speaker_pins[0] = 0x14;
2037 spec->autocfg.speaker_pins[1] = 0x16;
2038 spec->autocfg.speaker_pins[2] = 0x17;
2039 spec->autocfg.speaker_pins[3] = 0x19;
2040 spec->autocfg.speaker_pins[4] = 0x1a;
2043 static void alc889_intel_init_hook(struct hda_codec *codec)
2045 alc889_coef_init(codec);
2046 alc_automute_amp(codec);
2049 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2051 struct alc_spec *spec = codec->spec;
2053 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2054 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2055 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2056 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2060 * ALC888 Acer Aspire 4930G model
2063 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2064 /* Front Mic: set to PIN_IN (empty by default) */
2065 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2066 /* Unselect Front Mic by default in input mixer 3 */
2067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2068 /* Enable unsolicited event for HP jack */
2069 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2070 /* Connect Internal HP to front */
2071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2072 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2073 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2074 /* Connect HP out to front */
2075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2076 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2077 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2078 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2083 * ALC888 Acer Aspire 6530G model
2086 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2087 /* Route to built-in subwoofer as well as speakers */
2088 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2089 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2090 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2091 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2092 /* Bias voltage on for external mic port */
2093 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2094 /* Front Mic: set to PIN_IN (empty by default) */
2095 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2096 /* Unselect Front Mic by default in input mixer 3 */
2097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2098 /* Enable unsolicited event for HP jack */
2099 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2100 /* Enable speaker output */
2101 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2102 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2103 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2104 /* Enable headphone output */
2105 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2106 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2107 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2108 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2113 *ALC888 Acer Aspire 7730G model
2116 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2117 /* Bias voltage on for external mic port */
2118 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2119 /* Front Mic: set to PIN_IN (empty by default) */
2120 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2121 /* Unselect Front Mic by default in input mixer 3 */
2122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2123 /* Enable unsolicited event for HP jack */
2124 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2125 /* Enable speaker output */
2126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2127 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2128 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2129 /* Enable headphone output */
2130 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2131 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2132 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2133 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2134 /*Enable internal subwoofer */
2135 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2136 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2137 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2138 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2143 * ALC889 Acer Aspire 8930G model
2146 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2147 /* Front Mic: set to PIN_IN (empty by default) */
2148 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2149 /* Unselect Front Mic by default in input mixer 3 */
2150 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2151 /* Enable unsolicited event for HP jack */
2152 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2153 /* Connect Internal Front to Front */
2154 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2157 /* Connect Internal Rear to Rear */
2158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2159 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2160 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2161 /* Connect Internal CLFE to CLFE */
2162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2163 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2164 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2165 /* Connect HP out to Front */
2166 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2167 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2168 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2169 /* Enable all DACs */
2170 /* DAC DISABLE/MUTE 1? */
2171 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2172 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2173 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2174 /* DAC DISABLE/MUTE 2? */
2175 /* some bit here disables the other DACs. Init=0x4900 */
2176 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2177 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2179 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2180 * which makes the stereo useless. However, either the mic or the ALC889
2181 * makes the signal become a difference/sum signal instead of standard
2182 * stereo, which is annoying. So instead we flip this bit which makes the
2183 * codec replicate the sum signal to both channels, turning it into a
2186 /* DMIC_CONTROL? Init value = 0x0001 */
2187 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2188 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2192 static struct hda_input_mux alc888_2_capture_sources[2] = {
2193 /* Front mic only available on one ADC */
2200 { "Front Mic", 0xb },
2213 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2214 /* Interal mic only available on one ADC */
2221 { "Input Mix", 0xa },
2222 { "Internal Mic", 0xb },
2231 { "Input Mix", 0xa },
2236 static struct hda_input_mux alc889_capture_sources[3] = {
2237 /* Digital mic only available on first "ADC" */
2244 { "Front Mic", 0xb },
2245 { "Input Mix", 0xa },
2254 { "Input Mix", 0xa },
2263 { "Input Mix", 0xa },
2268 static struct snd_kcontrol_new alc888_base_mixer[] = {
2269 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2270 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2271 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2272 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2273 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2275 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2276 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2277 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2278 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2279 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2280 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2281 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2285 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2286 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2290 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2293 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2294 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2295 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2297 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2298 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2299 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2301 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2303 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2304 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2309 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2311 struct alc_spec *spec = codec->spec;
2313 spec->autocfg.hp_pins[0] = 0x15;
2314 spec->autocfg.speaker_pins[0] = 0x14;
2315 spec->autocfg.speaker_pins[1] = 0x16;
2316 spec->autocfg.speaker_pins[2] = 0x17;
2319 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2321 struct alc_spec *spec = codec->spec;
2323 spec->autocfg.hp_pins[0] = 0x15;
2324 spec->autocfg.speaker_pins[0] = 0x14;
2325 spec->autocfg.speaker_pins[1] = 0x16;
2326 spec->autocfg.speaker_pins[2] = 0x17;
2329 static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2331 struct alc_spec *spec = codec->spec;
2333 spec->autocfg.hp_pins[0] = 0x15;
2334 spec->autocfg.speaker_pins[0] = 0x14;
2335 spec->autocfg.speaker_pins[1] = 0x16;
2336 spec->autocfg.speaker_pins[2] = 0x17;
2339 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2341 struct alc_spec *spec = codec->spec;
2343 spec->autocfg.hp_pins[0] = 0x15;
2344 spec->autocfg.speaker_pins[0] = 0x14;
2345 spec->autocfg.speaker_pins[1] = 0x16;
2346 spec->autocfg.speaker_pins[2] = 0x1b;
2350 * ALC880 3-stack model
2352 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2353 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2354 * F-Mic = 0x1b, HP = 0x19
2357 static hda_nid_t alc880_dac_nids[4] = {
2358 /* front, rear, clfe, rear_surr */
2359 0x02, 0x05, 0x04, 0x03
2362 static hda_nid_t alc880_adc_nids[3] = {
2367 /* The datasheet says the node 0x07 is connected from inputs,
2368 * but it shows zero connection in the real implementation on some devices.
2369 * Note: this is a 915GAV bug, fixed on 915GLV
2371 static hda_nid_t alc880_adc_nids_alt[2] = {
2376 #define ALC880_DIGOUT_NID 0x06
2377 #define ALC880_DIGIN_NID 0x0a
2379 static struct hda_input_mux alc880_capture_source = {
2383 { "Front Mic", 0x3 },
2389 /* channel source setting (2/6 channel selection for 3-stack) */
2391 static struct hda_verb alc880_threestack_ch2_init[] = {
2392 /* set line-in to input, mute it */
2393 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2394 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2395 /* set mic-in to input vref 80%, mute it */
2396 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2397 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2402 static struct hda_verb alc880_threestack_ch6_init[] = {
2403 /* set line-in to output, unmute it */
2404 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2405 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2406 /* set mic-in to output, unmute it */
2407 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2408 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2412 static struct hda_channel_mode alc880_threestack_modes[2] = {
2413 { 2, alc880_threestack_ch2_init },
2414 { 6, alc880_threestack_ch6_init },
2417 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2418 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2419 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2420 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2421 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2422 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2423 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2424 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2425 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2426 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2427 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2434 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2437 .name = "Channel Mode",
2438 .info = alc_ch_mode_info,
2439 .get = alc_ch_mode_get,
2440 .put = alc_ch_mode_put,
2445 /* capture mixer elements */
2446 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2447 struct snd_ctl_elem_info *uinfo)
2449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2450 struct alc_spec *spec = codec->spec;
2453 mutex_lock(&codec->control_mutex);
2454 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2456 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2457 mutex_unlock(&codec->control_mutex);
2461 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2462 unsigned int size, unsigned int __user *tlv)
2464 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2465 struct alc_spec *spec = codec->spec;
2468 mutex_lock(&codec->control_mutex);
2469 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2471 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2472 mutex_unlock(&codec->control_mutex);
2476 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2477 struct snd_ctl_elem_value *ucontrol);
2479 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2480 struct snd_ctl_elem_value *ucontrol,
2483 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2484 struct alc_spec *spec = codec->spec;
2485 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2488 mutex_lock(&codec->control_mutex);
2489 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2491 err = func(kcontrol, ucontrol);
2492 mutex_unlock(&codec->control_mutex);
2496 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2497 struct snd_ctl_elem_value *ucontrol)
2499 return alc_cap_getput_caller(kcontrol, ucontrol,
2500 snd_hda_mixer_amp_volume_get);
2503 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2504 struct snd_ctl_elem_value *ucontrol)
2506 return alc_cap_getput_caller(kcontrol, ucontrol,
2507 snd_hda_mixer_amp_volume_put);
2510 /* capture mixer elements */
2511 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2513 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2514 struct snd_ctl_elem_value *ucontrol)
2516 return alc_cap_getput_caller(kcontrol, ucontrol,
2517 snd_hda_mixer_amp_switch_get);
2520 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2521 struct snd_ctl_elem_value *ucontrol)
2523 return alc_cap_getput_caller(kcontrol, ucontrol,
2524 snd_hda_mixer_amp_switch_put);
2527 #define _DEFINE_CAPMIX(num) \
2529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2530 .name = "Capture Switch", \
2531 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2533 .info = alc_cap_sw_info, \
2534 .get = alc_cap_sw_get, \
2535 .put = alc_cap_sw_put, \
2538 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2539 .name = "Capture Volume", \
2540 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2541 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2542 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2544 .info = alc_cap_vol_info, \
2545 .get = alc_cap_vol_get, \
2546 .put = alc_cap_vol_put, \
2547 .tlv = { .c = alc_cap_vol_tlv }, \
2550 #define _DEFINE_CAPSRC(num) \
2552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2553 /* .name = "Capture Source", */ \
2554 .name = "Input Source", \
2556 .info = alc_mux_enum_info, \
2557 .get = alc_mux_enum_get, \
2558 .put = alc_mux_enum_put, \
2561 #define DEFINE_CAPMIX(num) \
2562 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2563 _DEFINE_CAPMIX(num), \
2564 _DEFINE_CAPSRC(num), \
2568 #define DEFINE_CAPMIX_NOSRC(num) \
2569 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2570 _DEFINE_CAPMIX(num), \
2574 /* up to three ADCs */
2578 DEFINE_CAPMIX_NOSRC(1);
2579 DEFINE_CAPMIX_NOSRC(2);
2580 DEFINE_CAPMIX_NOSRC(3);
2583 * ALC880 5-stack model
2585 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2587 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2588 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2591 /* additional mixers to alc880_three_stack_mixer */
2592 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2593 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2594 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2598 /* channel source setting (6/8 channel selection for 5-stack) */
2600 static struct hda_verb alc880_fivestack_ch6_init[] = {
2601 /* set line-in to input, mute it */
2602 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2603 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2608 static struct hda_verb alc880_fivestack_ch8_init[] = {
2609 /* set line-in to output, unmute it */
2610 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2611 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2615 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2616 { 6, alc880_fivestack_ch6_init },
2617 { 8, alc880_fivestack_ch8_init },
2622 * ALC880 6-stack model
2624 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2625 * Side = 0x05 (0x0f)
2626 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2627 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2630 static hda_nid_t alc880_6st_dac_nids[4] = {
2631 /* front, rear, clfe, rear_surr */
2632 0x02, 0x03, 0x04, 0x05
2635 static struct hda_input_mux alc880_6stack_capture_source = {
2639 { "Front Mic", 0x1 },
2645 /* fixed 8-channels */
2646 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2650 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2651 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2652 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2653 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2654 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2655 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2656 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2657 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2658 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2659 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2660 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2661 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2662 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2663 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2664 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2665 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2666 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2667 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2668 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2670 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2671 .name = "Channel Mode",
2672 .info = alc_ch_mode_info,
2673 .get = alc_ch_mode_get,
2674 .put = alc_ch_mode_put,
2683 * W810 has rear IO for:
2686 * Center/LFE (DAC 04)
2689 * The system also has a pair of internal speakers, and a headphone jack.
2690 * These are both connected to Line2 on the codec, hence to DAC 02.
2692 * There is a variable resistor to control the speaker or headphone
2693 * volume. This is a hardware-only device without a software API.
2695 * Plugging headphones in will disable the internal speakers. This is
2696 * implemented in hardware, not via the driver using jack sense. In
2697 * a similar fashion, plugging into the rear socket marked "front" will
2698 * disable both the speakers and headphones.
2700 * For input, there's a microphone jack, and an "audio in" jack.
2701 * These may not do anything useful with this driver yet, because I
2702 * haven't setup any initialization verbs for these yet...
2705 static hda_nid_t alc880_w810_dac_nids[3] = {
2706 /* front, rear/surround, clfe */
2710 /* fixed 6 channels */
2711 static struct hda_channel_mode alc880_w810_modes[1] = {
2715 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2716 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2717 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2718 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2719 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2720 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2721 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2722 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2723 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2724 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2725 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2733 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2734 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2738 static hda_nid_t alc880_z71v_dac_nids[1] = {
2741 #define ALC880_Z71V_HP_DAC 0x03
2743 /* fixed 2 channels */
2744 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2748 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2749 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2750 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2751 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2752 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2753 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2754 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2755 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2756 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2762 * ALC880 F1734 model
2764 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2765 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2768 static hda_nid_t alc880_f1734_dac_nids[1] = {
2771 #define ALC880_F1734_HP_DAC 0x02
2773 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2774 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2775 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2776 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2777 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2778 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2779 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2785 static struct hda_input_mux alc880_f1734_capture_source = {
2797 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2798 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2799 * Mic = 0x18, Line = 0x1a
2802 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2803 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2805 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2806 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2807 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2808 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2809 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2810 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2811 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2812 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2813 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2814 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2815 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2816 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2817 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2818 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2821 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2822 .name = "Channel Mode",
2823 .info = alc_ch_mode_info,
2824 .get = alc_ch_mode_get,
2825 .put = alc_ch_mode_put,
2831 * ALC880 ASUS W1V model
2833 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2834 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2835 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2838 /* additional mixers to alc880_asus_mixer */
2839 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2840 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2841 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2846 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2847 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2848 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2849 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2850 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2851 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2854 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2855 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2860 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2861 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2862 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2863 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2864 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2865 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2866 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2867 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2868 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2869 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2870 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2871 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2872 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2873 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2874 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2875 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2876 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2878 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2879 .name = "Channel Mode",
2880 .info = alc_ch_mode_info,
2881 .get = alc_ch_mode_get,
2882 .put = alc_ch_mode_put,
2887 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2888 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2889 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2890 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2891 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2894 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2895 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2896 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2897 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2901 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2902 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2903 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2904 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2905 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2906 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2912 * virtual master controls
2916 * slave controls for virtual master
2918 static const char *alc_slave_vols[] = {
2919 "Front Playback Volume",
2920 "Surround Playback Volume",
2921 "Center Playback Volume",
2922 "LFE Playback Volume",
2923 "Side Playback Volume",
2924 "Headphone Playback Volume",
2925 "Speaker Playback Volume",
2926 "Mono Playback Volume",
2927 "Line-Out Playback Volume",
2928 "PCM Playback Volume",
2932 static const char *alc_slave_sws[] = {
2933 "Front Playback Switch",
2934 "Surround Playback Switch",
2935 "Center Playback Switch",
2936 "LFE Playback Switch",
2937 "Side Playback Switch",
2938 "Headphone Playback Switch",
2939 "Speaker Playback Switch",
2940 "Mono Playback Switch",
2941 "IEC958 Playback Switch",
2942 "Line-Out Playback Switch",
2943 "PCM Playback Switch",
2948 * build control elements
2951 #define NID_MAPPING (-1)
2953 #define SUBDEV_SPEAKER_ (0 << 6)
2954 #define SUBDEV_HP_ (1 << 6)
2955 #define SUBDEV_LINE_ (2 << 6)
2956 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2957 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2958 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2960 static void alc_free_kctls(struct hda_codec *codec);
2962 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2963 /* additional beep mixers; the actual parameters are overwritten at build */
2964 static struct snd_kcontrol_new alc_beep_mixer[] = {
2965 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2966 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2971 static int alc_build_controls(struct hda_codec *codec)
2973 struct alc_spec *spec = codec->spec;
2974 struct snd_kcontrol *kctl = NULL;
2975 struct snd_kcontrol_new *knew;
2980 for (i = 0; i < spec->num_mixers; i++) {
2981 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2985 if (spec->cap_mixer) {
2986 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2990 if (spec->multiout.dig_out_nid) {
2991 err = snd_hda_create_spdif_out_ctls(codec,
2992 spec->multiout.dig_out_nid);
2995 if (!spec->no_analog) {
2996 err = snd_hda_create_spdif_share_sw(codec,
3000 spec->multiout.share_spdif = 1;
3003 if (spec->dig_in_nid) {
3004 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3009 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3010 /* create beep controls if needed */
3011 if (spec->beep_amp) {
3012 struct snd_kcontrol_new *knew;
3013 for (knew = alc_beep_mixer; knew->name; knew++) {
3014 struct snd_kcontrol *kctl;
3015 kctl = snd_ctl_new1(knew, codec);
3018 kctl->private_value = spec->beep_amp;
3019 err = snd_hda_ctl_add(codec, 0, kctl);
3026 /* if we have no master control, let's create it */
3027 if (!spec->no_analog &&
3028 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3029 unsigned int vmaster_tlv[4];
3030 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3031 HDA_OUTPUT, vmaster_tlv);
3032 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3033 vmaster_tlv, alc_slave_vols);
3037 if (!spec->no_analog &&
3038 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3039 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3040 NULL, alc_slave_sws);
3045 /* assign Capture Source enums to NID */
3046 if (spec->capsrc_nids || spec->adc_nids) {
3047 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3049 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3050 for (i = 0; kctl && i < kctl->count; i++) {
3051 hda_nid_t *nids = spec->capsrc_nids;
3053 nids = spec->adc_nids;
3054 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3059 if (spec->cap_mixer) {
3060 const char *kname = kctl ? kctl->id.name : NULL;
3061 for (knew = spec->cap_mixer; knew->name; knew++) {
3062 if (kname && strcmp(knew->name, kname) == 0)
3064 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3065 for (i = 0; kctl && i < kctl->count; i++) {
3066 err = snd_hda_add_nid(codec, kctl, i,
3074 /* other nid->control mapping */
3075 for (i = 0; i < spec->num_mixers; i++) {
3076 for (knew = spec->mixers[i]; knew->name; knew++) {
3077 if (knew->iface != NID_MAPPING)
3079 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3082 u = knew->subdevice;
3083 for (j = 0; j < 4; j++, u >>= 8) {
3088 case SUBDEV_SPEAKER_:
3089 nid = spec->autocfg.speaker_pins[nid];
3092 nid = spec->autocfg.line_out_pins[nid];
3095 nid = spec->autocfg.hp_pins[nid];
3100 err = snd_hda_add_nid(codec, kctl, 0, nid);
3104 u = knew->private_value;
3105 for (j = 0; j < 4; j++, u >>= 8) {
3109 err = snd_hda_add_nid(codec, kctl, 0, nid);
3116 alc_free_kctls(codec); /* no longer needed */
3123 * initialize the codec volumes, etc
3127 * generic initialization of ADC, input mixers and output mixers
3129 static struct hda_verb alc880_volume_init_verbs[] = {
3131 * Unmute ADC0-2 and set the default input to mic-in
3133 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3134 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3135 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3136 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3137 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3138 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3140 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3142 * Note: PASD motherboards uses the Line In 2 as the input for front
3145 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3146 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3155 * Set up output mixers (0x0c - 0x0f)
3157 /* set vol=0 to output mixers */
3158 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3159 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3160 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3161 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3162 /* set up input amps for analog loopback */
3163 /* Amp Indices: DAC = 0, mixer = 1 */
3164 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3165 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3166 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3167 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3168 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3169 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3170 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3171 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3177 * 3-stack pin configuration:
3178 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3180 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3182 * preset connection lists of input pins
3183 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3185 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3186 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3187 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3190 * Set pin mode and muting
3192 /* set front pin widgets 0x14 for output */
3193 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3194 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3195 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3196 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3197 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3198 /* Mic2 (as headphone out) for HP output */
3199 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3200 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3201 /* Line In pin widget for input */
3202 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3203 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3204 /* Line2 (as front mic) pin widget for input and vref at 80% */
3205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3206 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3207 /* CD pin widget for input */
3208 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3214 * 5-stack pin configuration:
3215 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3216 * line-in/side = 0x1a, f-mic = 0x1b
3218 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3220 * preset connection lists of input pins
3221 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3223 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3224 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3227 * Set pin mode and muting
3229 /* set pin widgets 0x14-0x17 for output */
3230 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3231 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3232 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3233 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3234 /* unmute pins for output (no gain on this amp) */
3235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3236 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3237 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3238 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3240 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3241 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3242 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3243 /* Mic2 (as headphone out) for HP output */
3244 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3245 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3246 /* Line In pin widget for input */
3247 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3248 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3249 /* Line2 (as front mic) pin widget for input and vref at 80% */
3250 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3251 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3252 /* CD pin widget for input */
3253 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3259 * W810 pin configuration:
3260 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3262 static struct hda_verb alc880_pin_w810_init_verbs[] = {
3263 /* hphone/speaker input selector: front DAC */
3264 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3266 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3267 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3270 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3271 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3274 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3280 * Z71V pin configuration:
3281 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3283 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
3284 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3285 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3287 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3289 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3290 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3291 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3292 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3298 * 6-stack pin configuration:
3299 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3300 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3302 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3303 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3305 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3306 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3307 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3309 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3310 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3311 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3312 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3314 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3315 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3316 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3318 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3320 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3321 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3322 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3328 * Uniwill pin configuration:
3329 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3332 static struct hda_verb alc880_uniwill_init_verbs[] = {
3333 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3338 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3339 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3340 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3341 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3342 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3343 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3345 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3350 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3351 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3352 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3353 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3354 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3355 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3356 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3357 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3358 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3360 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3361 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3368 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3370 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3371 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3375 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3376 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3377 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3378 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3379 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3380 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3381 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3382 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3383 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3384 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3386 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3388 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3389 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3390 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3391 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3393 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3394 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3399 static struct hda_verb alc880_beep_init_verbs[] = {
3400 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3404 /* auto-toggle front mic */
3405 static void alc88x_simple_mic_automute(struct hda_codec *codec)
3407 unsigned int present;
3410 present = snd_hda_jack_detect(codec, 0x18);
3411 bits = present ? HDA_AMP_MUTE : 0;
3412 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3415 static void alc880_uniwill_setup(struct hda_codec *codec)
3417 struct alc_spec *spec = codec->spec;
3419 spec->autocfg.hp_pins[0] = 0x14;
3420 spec->autocfg.speaker_pins[0] = 0x15;
3421 spec->autocfg.speaker_pins[0] = 0x16;
3424 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3426 alc_automute_amp(codec);
3427 alc88x_simple_mic_automute(codec);
3430 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3433 /* Looks like the unsol event is incompatible with the standard
3434 * definition. 4bit tag is placed at 28 bit!
3436 switch (res >> 28) {
3437 case ALC880_MIC_EVENT:
3438 alc88x_simple_mic_automute(codec);
3441 alc_automute_amp_unsol_event(codec, res);
3446 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3448 struct alc_spec *spec = codec->spec;
3450 spec->autocfg.hp_pins[0] = 0x14;
3451 spec->autocfg.speaker_pins[0] = 0x15;
3454 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3456 unsigned int present;
3458 present = snd_hda_codec_read(codec, 0x21, 0,
3459 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3460 present &= HDA_AMP_VOLMASK;
3461 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3462 HDA_AMP_VOLMASK, present);
3463 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3464 HDA_AMP_VOLMASK, present);
3467 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3470 /* Looks like the unsol event is incompatible with the standard
3471 * definition. 4bit tag is placed at 28 bit!
3473 if ((res >> 28) == ALC880_DCVOL_EVENT)
3474 alc880_uniwill_p53_dcvol_automute(codec);
3476 alc_automute_amp_unsol_event(codec, res);
3480 * F1734 pin configuration:
3481 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3483 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3484 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3485 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3486 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3487 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3488 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3490 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3491 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3495 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3496 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3497 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3498 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3499 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3500 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3502 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3503 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3505 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3506 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3512 * ASUS pin configuration:
3513 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3515 static struct hda_verb alc880_pin_asus_init_verbs[] = {
3516 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3517 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3518 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3519 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3523 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3524 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3525 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3527 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3528 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3532 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3534 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3536 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3538 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3543 /* Enable GPIO mask and set output */
3544 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3545 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3546 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3548 /* Clevo m520g init */
3549 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3550 /* headphone output */
3551 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3556 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3559 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3560 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3561 /* Mic1 (rear panel) */
3562 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3563 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3564 /* Mic2 (front panel) */
3565 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3566 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3568 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3570 /* change to EAPD mode */
3571 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3572 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3577 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3578 /* change to EAPD mode */
3579 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3580 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3582 /* Headphone output */
3583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3586 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3588 /* Line In pin widget for input */
3589 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3590 /* CD pin widget for input */
3591 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3592 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3593 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3595 /* change to EAPD mode */
3596 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3597 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3603 * LG m1 express dual
3606 * Rear Line-In/Out (blue): 0x14
3607 * Build-in Mic-In: 0x15
3609 * HP-Out (green): 0x1b
3610 * Mic-In/Out (red): 0x19
3614 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3615 static hda_nid_t alc880_lg_dac_nids[3] = {
3619 /* seems analog CD is not working */
3620 static struct hda_input_mux alc880_lg_capture_source = {
3625 { "Internal Mic", 0x6 },
3629 /* 2,4,6 channel modes */
3630 static struct hda_verb alc880_lg_ch2_init[] = {
3631 /* set line-in and mic-in to input */
3632 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3633 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3637 static struct hda_verb alc880_lg_ch4_init[] = {
3638 /* set line-in to out and mic-in to input */
3639 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3640 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3644 static struct hda_verb alc880_lg_ch6_init[] = {
3645 /* set line-in and mic-in to output */
3646 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3647 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3651 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3652 { 2, alc880_lg_ch2_init },
3653 { 4, alc880_lg_ch4_init },
3654 { 6, alc880_lg_ch6_init },
3657 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3658 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3659 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3660 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3661 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3662 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3663 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3664 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3665 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3670 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3671 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3674 .name = "Channel Mode",
3675 .info = alc_ch_mode_info,
3676 .get = alc_ch_mode_get,
3677 .put = alc_ch_mode_put,
3682 static struct hda_verb alc880_lg_init_verbs[] = {
3683 /* set capture source to mic-in */
3684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3685 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3686 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3687 /* mute all amp mixer inputs */
3688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3691 /* line-in to input */
3692 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3693 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3695 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3698 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3699 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3700 /* mic-in to input */
3701 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3702 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3703 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3705 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3709 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3713 /* toggle speaker-output according to the hp-jack state */
3714 static void alc880_lg_setup(struct hda_codec *codec)
3716 struct alc_spec *spec = codec->spec;
3718 spec->autocfg.hp_pins[0] = 0x1b;
3719 spec->autocfg.speaker_pins[0] = 0x17;
3728 * Built-in Mic-In: 0x19
3734 static struct hda_input_mux alc880_lg_lw_capture_source = {
3738 { "Internal Mic", 0x1 },
3743 #define alc880_lg_lw_modes alc880_threestack_modes
3745 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3746 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3747 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3748 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3749 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3750 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3751 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3752 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3753 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3754 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3755 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3757 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3758 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3759 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3762 .name = "Channel Mode",
3763 .info = alc_ch_mode_info,
3764 .get = alc_ch_mode_get,
3765 .put = alc_ch_mode_put,
3770 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3771 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3772 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3773 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3775 /* set capture source to mic-in */
3776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3777 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3778 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3779 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3781 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3782 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3784 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3785 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3786 /* mic-in to input */
3787 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3788 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3791 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3793 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3797 /* toggle speaker-output according to the hp-jack state */
3798 static void alc880_lg_lw_setup(struct hda_codec *codec)
3800 struct alc_spec *spec = codec->spec;
3802 spec->autocfg.hp_pins[0] = 0x1b;
3803 spec->autocfg.speaker_pins[0] = 0x14;
3806 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3807 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3808 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3811 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3812 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3816 static struct hda_input_mux alc880_medion_rim_capture_source = {
3820 { "Internal Mic", 0x1 },
3824 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3825 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3828 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3830 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3831 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3832 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3833 /* Mic2 (as headphone out) for HP output */
3834 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3836 /* Internal Speaker */
3837 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3838 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3840 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3841 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3843 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3847 /* toggle speaker-output according to the hp-jack state */
3848 static void alc880_medion_rim_automute(struct hda_codec *codec)
3850 struct alc_spec *spec = codec->spec;
3851 alc_automute_amp(codec);
3853 if (spec->jack_present)
3854 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3856 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3859 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3862 /* Looks like the unsol event is incompatible with the standard
3863 * definition. 4bit tag is placed at 28 bit!
3865 if ((res >> 28) == ALC880_HP_EVENT)
3866 alc880_medion_rim_automute(codec);
3869 static void alc880_medion_rim_setup(struct hda_codec *codec)
3871 struct alc_spec *spec = codec->spec;
3873 spec->autocfg.hp_pins[0] = 0x14;
3874 spec->autocfg.speaker_pins[0] = 0x1b;
3877 #ifdef CONFIG_SND_HDA_POWER_SAVE
3878 static struct hda_amp_list alc880_loopbacks[] = {
3879 { 0x0b, HDA_INPUT, 0 },
3880 { 0x0b, HDA_INPUT, 1 },
3881 { 0x0b, HDA_INPUT, 2 },
3882 { 0x0b, HDA_INPUT, 3 },
3883 { 0x0b, HDA_INPUT, 4 },
3887 static struct hda_amp_list alc880_lg_loopbacks[] = {
3888 { 0x0b, HDA_INPUT, 1 },
3889 { 0x0b, HDA_INPUT, 6 },
3890 { 0x0b, HDA_INPUT, 7 },
3899 static int alc_init(struct hda_codec *codec)
3901 struct alc_spec *spec = codec->spec;
3905 alc_auto_init_amp(codec, spec->init_amp);
3907 for (i = 0; i < spec->num_init_verbs; i++)
3908 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3910 if (spec->init_hook)
3911 spec->init_hook(codec);
3913 hda_call_check_power_status(codec, 0x01);
3917 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3919 struct alc_spec *spec = codec->spec;
3921 if (spec->unsol_event)
3922 spec->unsol_event(codec, res);
3925 #ifdef CONFIG_SND_HDA_POWER_SAVE
3926 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3928 struct alc_spec *spec = codec->spec;
3929 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3934 * Analog playback callbacks
3936 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3937 struct hda_codec *codec,
3938 struct snd_pcm_substream *substream)
3940 struct alc_spec *spec = codec->spec;
3941 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3945 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3946 struct hda_codec *codec,
3947 unsigned int stream_tag,
3948 unsigned int format,
3949 struct snd_pcm_substream *substream)
3951 struct alc_spec *spec = codec->spec;
3952 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3953 stream_tag, format, substream);
3956 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3957 struct hda_codec *codec,
3958 struct snd_pcm_substream *substream)
3960 struct alc_spec *spec = codec->spec;
3961 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3967 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3968 struct hda_codec *codec,
3969 struct snd_pcm_substream *substream)
3971 struct alc_spec *spec = codec->spec;
3972 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3975 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3976 struct hda_codec *codec,
3977 unsigned int stream_tag,
3978 unsigned int format,
3979 struct snd_pcm_substream *substream)
3981 struct alc_spec *spec = codec->spec;
3982 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3983 stream_tag, format, substream);
3986 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3987 struct hda_codec *codec,
3988 struct snd_pcm_substream *substream)
3990 struct alc_spec *spec = codec->spec;
3991 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3994 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3995 struct hda_codec *codec,
3996 struct snd_pcm_substream *substream)
3998 struct alc_spec *spec = codec->spec;
3999 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4005 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4006 struct hda_codec *codec,
4007 unsigned int stream_tag,
4008 unsigned int format,
4009 struct snd_pcm_substream *substream)
4011 struct alc_spec *spec = codec->spec;
4013 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4014 stream_tag, 0, format);
4018 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4019 struct hda_codec *codec,
4020 struct snd_pcm_substream *substream)
4022 struct alc_spec *spec = codec->spec;
4024 snd_hda_codec_cleanup_stream(codec,
4025 spec->adc_nids[substream->number + 1]);
4029 /* analog capture with dynamic dual-adc changes */
4030 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4031 struct hda_codec *codec,
4032 unsigned int stream_tag,
4033 unsigned int format,
4034 struct snd_pcm_substream *substream)
4036 struct alc_spec *spec = codec->spec;
4037 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4038 spec->cur_adc_stream_tag = stream_tag;
4039 spec->cur_adc_format = format;
4040 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4044 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4045 struct hda_codec *codec,
4046 struct snd_pcm_substream *substream)
4048 struct alc_spec *spec = codec->spec;
4049 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4054 static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4058 .nid = 0, /* fill later */
4060 .prepare = dualmic_capture_pcm_prepare,
4061 .cleanup = dualmic_capture_pcm_cleanup
4067 static struct hda_pcm_stream alc880_pcm_analog_playback = {
4071 /* NID is set in alc_build_pcms */
4073 .open = alc880_playback_pcm_open,
4074 .prepare = alc880_playback_pcm_prepare,
4075 .cleanup = alc880_playback_pcm_cleanup
4079 static struct hda_pcm_stream alc880_pcm_analog_capture = {
4083 /* NID is set in alc_build_pcms */
4086 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4090 /* NID is set in alc_build_pcms */
4093 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4094 .substreams = 2, /* can be overridden */
4097 /* NID is set in alc_build_pcms */
4099 .prepare = alc880_alt_capture_pcm_prepare,
4100 .cleanup = alc880_alt_capture_pcm_cleanup
4104 static struct hda_pcm_stream alc880_pcm_digital_playback = {
4108 /* NID is set in alc_build_pcms */
4110 .open = alc880_dig_playback_pcm_open,
4111 .close = alc880_dig_playback_pcm_close,
4112 .prepare = alc880_dig_playback_pcm_prepare,
4113 .cleanup = alc880_dig_playback_pcm_cleanup
4117 static struct hda_pcm_stream alc880_pcm_digital_capture = {
4121 /* NID is set in alc_build_pcms */
4124 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
4125 static struct hda_pcm_stream alc_pcm_null_stream = {
4131 static int alc_build_pcms(struct hda_codec *codec)
4133 struct alc_spec *spec = codec->spec;
4134 struct hda_pcm *info = spec->pcm_rec;
4137 codec->num_pcms = 1;
4138 codec->pcm_info = info;
4140 if (spec->no_analog)
4143 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4144 "%s Analog", codec->chip_name);
4145 info->name = spec->stream_name_analog;
4147 if (spec->stream_analog_playback) {
4148 if (snd_BUG_ON(!spec->multiout.dac_nids))
4150 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4151 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4153 if (spec->stream_analog_capture) {
4154 if (snd_BUG_ON(!spec->adc_nids))
4156 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4157 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4160 if (spec->channel_mode) {
4161 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4162 for (i = 0; i < spec->num_channel_mode; i++) {
4163 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4164 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4170 /* SPDIF for stream index #1 */
4171 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4172 snprintf(spec->stream_name_digital,
4173 sizeof(spec->stream_name_digital),
4174 "%s Digital", codec->chip_name);
4175 codec->num_pcms = 2;
4176 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4177 info = spec->pcm_rec + 1;
4178 info->name = spec->stream_name_digital;
4179 if (spec->dig_out_type)
4180 info->pcm_type = spec->dig_out_type;
4182 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4183 if (spec->multiout.dig_out_nid &&
4184 spec->stream_digital_playback) {
4185 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4186 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4188 if (spec->dig_in_nid &&
4189 spec->stream_digital_capture) {
4190 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4191 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4193 /* FIXME: do we need this for all Realtek codec models? */
4194 codec->spdif_status_reset = 1;
4197 if (spec->no_analog)
4200 /* If the use of more than one ADC is requested for the current
4201 * model, configure a second analog capture-only PCM.
4203 /* Additional Analaog capture for index #2 */
4204 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4205 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4206 codec->num_pcms = 3;
4207 info = spec->pcm_rec + 2;
4208 info->name = spec->stream_name_analog;
4209 if (spec->alt_dac_nid) {
4210 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4211 *spec->stream_analog_alt_playback;
4212 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4215 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4216 alc_pcm_null_stream;
4217 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4219 if (spec->num_adc_nids > 1) {
4220 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4221 *spec->stream_analog_alt_capture;
4222 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4224 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4225 spec->num_adc_nids - 1;
4227 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4228 alc_pcm_null_stream;
4229 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4236 static inline void alc_shutup(struct hda_codec *codec)
4238 snd_hda_shutup_pins(codec);
4241 static void alc_free_kctls(struct hda_codec *codec)
4243 struct alc_spec *spec = codec->spec;
4245 if (spec->kctls.list) {
4246 struct snd_kcontrol_new *kctl = spec->kctls.list;
4248 for (i = 0; i < spec->kctls.used; i++)
4249 kfree(kctl[i].name);
4251 snd_array_free(&spec->kctls);
4254 static void alc_free(struct hda_codec *codec)
4256 struct alc_spec *spec = codec->spec;
4262 alc_free_kctls(codec);
4264 snd_hda_detach_beep_device(codec);
4267 #ifdef CONFIG_SND_HDA_POWER_SAVE
4268 static void alc_power_eapd(struct hda_codec *codec)
4270 /* We currently only handle front, HP */
4271 switch (codec->vendor_id) {
4273 set_eapd(codec, 0x0f, 0);
4274 set_eapd(codec, 0x10, 0);
4287 set_eapd(codec, 0x14, 0);
4288 set_eapd(codec, 0x15, 0);
4293 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4295 struct alc_spec *spec = codec->spec;
4297 if (spec && spec->power_hook)
4298 spec->power_hook(codec);
4303 #ifdef SND_HDA_NEEDS_RESUME
4304 static int alc_resume(struct hda_codec *codec)
4306 codec->patch_ops.init(codec);
4307 snd_hda_codec_resume_amp(codec);
4308 snd_hda_codec_resume_cache(codec);
4309 hda_call_check_power_status(codec, 0x01);
4316 static struct hda_codec_ops alc_patch_ops = {
4317 .build_controls = alc_build_controls,
4318 .build_pcms = alc_build_pcms,
4321 .unsol_event = alc_unsol_event,
4322 #ifdef SND_HDA_NEEDS_RESUME
4323 .resume = alc_resume,
4325 #ifdef CONFIG_SND_HDA_POWER_SAVE
4326 .suspend = alc_suspend,
4327 .check_power_status = alc_check_power_status,
4329 .reboot_notify = alc_shutup,
4332 /* replace the codec chip_name with the given string */
4333 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4335 kfree(codec->chip_name);
4336 codec->chip_name = kstrdup(name, GFP_KERNEL);
4337 if (!codec->chip_name) {
4345 * Test configuration for debugging
4347 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4350 #ifdef CONFIG_SND_DEBUG
4351 static hda_nid_t alc880_test_dac_nids[4] = {
4352 0x02, 0x03, 0x04, 0x05
4355 static struct hda_input_mux alc880_test_capture_source = {
4364 { "Surround", 0x6 },
4368 static struct hda_channel_mode alc880_test_modes[4] = {
4375 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4376 struct snd_ctl_elem_info *uinfo)
4378 static char *texts[] = {
4379 "N/A", "Line Out", "HP Out",
4380 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4382 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4384 uinfo->value.enumerated.items = 8;
4385 if (uinfo->value.enumerated.item >= 8)
4386 uinfo->value.enumerated.item = 7;
4387 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4391 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4392 struct snd_ctl_elem_value *ucontrol)
4394 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4395 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4396 unsigned int pin_ctl, item = 0;
4398 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4399 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4400 if (pin_ctl & AC_PINCTL_OUT_EN) {
4401 if (pin_ctl & AC_PINCTL_HP_EN)
4405 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4406 switch (pin_ctl & AC_PINCTL_VREFEN) {
4407 case AC_PINCTL_VREF_HIZ: item = 3; break;
4408 case AC_PINCTL_VREF_50: item = 4; break;
4409 case AC_PINCTL_VREF_GRD: item = 5; break;
4410 case AC_PINCTL_VREF_80: item = 6; break;
4411 case AC_PINCTL_VREF_100: item = 7; break;
4414 ucontrol->value.enumerated.item[0] = item;
4418 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4419 struct snd_ctl_elem_value *ucontrol)
4421 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4422 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4423 static unsigned int ctls[] = {
4424 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4425 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4426 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4427 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4428 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4429 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4431 unsigned int old_ctl, new_ctl;
4433 old_ctl = snd_hda_codec_read(codec, nid, 0,
4434 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4435 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4436 if (old_ctl != new_ctl) {
4438 snd_hda_codec_write_cache(codec, nid, 0,
4439 AC_VERB_SET_PIN_WIDGET_CONTROL,
4441 val = ucontrol->value.enumerated.item[0] >= 3 ?
4443 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4450 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4451 struct snd_ctl_elem_info *uinfo)
4453 static char *texts[] = {
4454 "Front", "Surround", "CLFE", "Side"
4456 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4458 uinfo->value.enumerated.items = 4;
4459 if (uinfo->value.enumerated.item >= 4)
4460 uinfo->value.enumerated.item = 3;
4461 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4465 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4466 struct snd_ctl_elem_value *ucontrol)
4468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4469 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4472 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4473 ucontrol->value.enumerated.item[0] = sel & 3;
4477 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4478 struct snd_ctl_elem_value *ucontrol)
4480 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4481 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4484 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4485 if (ucontrol->value.enumerated.item[0] != sel) {
4486 sel = ucontrol->value.enumerated.item[0] & 3;
4487 snd_hda_codec_write_cache(codec, nid, 0,
4488 AC_VERB_SET_CONNECT_SEL, sel);
4494 #define PIN_CTL_TEST(xname,nid) { \
4495 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4497 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4498 .info = alc_test_pin_ctl_info, \
4499 .get = alc_test_pin_ctl_get, \
4500 .put = alc_test_pin_ctl_put, \
4501 .private_value = nid \
4504 #define PIN_SRC_TEST(xname,nid) { \
4505 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4507 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4508 .info = alc_test_pin_src_info, \
4509 .get = alc_test_pin_src_get, \
4510 .put = alc_test_pin_src_put, \
4511 .private_value = nid \
4514 static struct snd_kcontrol_new alc880_test_mixer[] = {
4515 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4516 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4517 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4518 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4519 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4520 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4521 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4522 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4523 PIN_CTL_TEST("Front Pin Mode", 0x14),
4524 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4525 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4526 PIN_CTL_TEST("Side Pin Mode", 0x17),
4527 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4528 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4529 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4530 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4531 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4532 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4533 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4534 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4535 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4536 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4537 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4538 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4539 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4540 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4541 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4542 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4543 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4544 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4546 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4547 .name = "Channel Mode",
4548 .info = alc_ch_mode_info,
4549 .get = alc_ch_mode_get,
4550 .put = alc_ch_mode_put,
4555 static struct hda_verb alc880_test_init_verbs[] = {
4556 /* Unmute inputs of 0x0c - 0x0f */
4557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4558 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4560 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4562 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4563 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4564 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4565 /* Vol output for 0x0c-0x0f */
4566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4568 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4569 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4570 /* Set output pins 0x14-0x17 */
4571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4572 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4573 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4574 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4575 /* Unmute output pins 0x14-0x17 */
4576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4578 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4579 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4580 /* Set input pins 0x18-0x1c */
4581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4582 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4584 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4585 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4586 /* Mute input pins 0x18-0x1b */
4587 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4590 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4593 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4594 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4595 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4596 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4597 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4598 /* Analog input/passthru */
4599 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4611 static const char *alc880_models[ALC880_MODEL_LAST] = {
4612 [ALC880_3ST] = "3stack",
4613 [ALC880_TCL_S700] = "tcl",
4614 [ALC880_3ST_DIG] = "3stack-digout",
4615 [ALC880_CLEVO] = "clevo",
4616 [ALC880_5ST] = "5stack",
4617 [ALC880_5ST_DIG] = "5stack-digout",
4618 [ALC880_W810] = "w810",
4619 [ALC880_Z71V] = "z71v",
4620 [ALC880_6ST] = "6stack",
4621 [ALC880_6ST_DIG] = "6stack-digout",
4622 [ALC880_ASUS] = "asus",
4623 [ALC880_ASUS_W1V] = "asus-w1v",
4624 [ALC880_ASUS_DIG] = "asus-dig",
4625 [ALC880_ASUS_DIG2] = "asus-dig2",
4626 [ALC880_UNIWILL_DIG] = "uniwill",
4627 [ALC880_UNIWILL_P53] = "uniwill-p53",
4628 [ALC880_FUJITSU] = "fujitsu",
4629 [ALC880_F1734] = "F1734",
4631 [ALC880_LG_LW] = "lg-lw",
4632 [ALC880_MEDION_RIM] = "medion",
4633 #ifdef CONFIG_SND_DEBUG
4634 [ALC880_TEST] = "test",
4636 [ALC880_AUTO] = "auto",
4639 static struct snd_pci_quirk alc880_cfg_tbl[] = {
4640 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4641 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4642 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4643 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4644 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4645 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4646 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4647 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4648 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4649 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4650 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4651 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4652 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4653 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4654 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4655 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4656 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4657 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4658 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4659 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4660 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4661 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4662 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4663 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4664 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4665 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4666 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4667 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4668 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4669 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4670 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4671 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4672 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4673 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4674 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4675 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4676 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4677 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4678 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4679 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4680 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4681 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4682 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4683 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4684 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4685 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4686 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4687 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4688 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4689 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4690 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4691 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4692 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4693 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4694 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4695 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4696 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4697 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4698 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4699 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4700 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4701 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4702 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4703 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4704 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4705 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4706 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4707 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4708 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4710 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4711 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4712 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4717 * ALC880 codec presets
4719 static struct alc_config_preset alc880_presets[] = {
4721 .mixers = { alc880_three_stack_mixer },
4722 .init_verbs = { alc880_volume_init_verbs,
4723 alc880_pin_3stack_init_verbs },
4724 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4725 .dac_nids = alc880_dac_nids,
4726 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4727 .channel_mode = alc880_threestack_modes,
4729 .input_mux = &alc880_capture_source,
4731 [ALC880_3ST_DIG] = {
4732 .mixers = { alc880_three_stack_mixer },
4733 .init_verbs = { alc880_volume_init_verbs,
4734 alc880_pin_3stack_init_verbs },
4735 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4736 .dac_nids = alc880_dac_nids,
4737 .dig_out_nid = ALC880_DIGOUT_NID,
4738 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4739 .channel_mode = alc880_threestack_modes,
4741 .input_mux = &alc880_capture_source,
4743 [ALC880_TCL_S700] = {
4744 .mixers = { alc880_tcl_s700_mixer },
4745 .init_verbs = { alc880_volume_init_verbs,
4746 alc880_pin_tcl_S700_init_verbs,
4747 alc880_gpio2_init_verbs },
4748 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4749 .dac_nids = alc880_dac_nids,
4750 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4751 .num_adc_nids = 1, /* single ADC */
4753 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4754 .channel_mode = alc880_2_jack_modes,
4755 .input_mux = &alc880_capture_source,
4758 .mixers = { alc880_three_stack_mixer,
4759 alc880_five_stack_mixer},
4760 .init_verbs = { alc880_volume_init_verbs,
4761 alc880_pin_5stack_init_verbs },
4762 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4763 .dac_nids = alc880_dac_nids,
4764 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4765 .channel_mode = alc880_fivestack_modes,
4766 .input_mux = &alc880_capture_source,
4768 [ALC880_5ST_DIG] = {
4769 .mixers = { alc880_three_stack_mixer,
4770 alc880_five_stack_mixer },
4771 .init_verbs = { alc880_volume_init_verbs,
4772 alc880_pin_5stack_init_verbs },
4773 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4774 .dac_nids = alc880_dac_nids,
4775 .dig_out_nid = ALC880_DIGOUT_NID,
4776 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4777 .channel_mode = alc880_fivestack_modes,
4778 .input_mux = &alc880_capture_source,
4781 .mixers = { alc880_six_stack_mixer },
4782 .init_verbs = { alc880_volume_init_verbs,
4783 alc880_pin_6stack_init_verbs },
4784 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4785 .dac_nids = alc880_6st_dac_nids,
4786 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4787 .channel_mode = alc880_sixstack_modes,
4788 .input_mux = &alc880_6stack_capture_source,
4790 [ALC880_6ST_DIG] = {
4791 .mixers = { alc880_six_stack_mixer },
4792 .init_verbs = { alc880_volume_init_verbs,
4793 alc880_pin_6stack_init_verbs },
4794 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4795 .dac_nids = alc880_6st_dac_nids,
4796 .dig_out_nid = ALC880_DIGOUT_NID,
4797 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4798 .channel_mode = alc880_sixstack_modes,
4799 .input_mux = &alc880_6stack_capture_source,
4802 .mixers = { alc880_w810_base_mixer },
4803 .init_verbs = { alc880_volume_init_verbs,
4804 alc880_pin_w810_init_verbs,
4805 alc880_gpio2_init_verbs },
4806 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4807 .dac_nids = alc880_w810_dac_nids,
4808 .dig_out_nid = ALC880_DIGOUT_NID,
4809 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4810 .channel_mode = alc880_w810_modes,
4811 .input_mux = &alc880_capture_source,
4814 .mixers = { alc880_z71v_mixer },
4815 .init_verbs = { alc880_volume_init_verbs,
4816 alc880_pin_z71v_init_verbs },
4817 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4818 .dac_nids = alc880_z71v_dac_nids,
4819 .dig_out_nid = ALC880_DIGOUT_NID,
4821 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4822 .channel_mode = alc880_2_jack_modes,
4823 .input_mux = &alc880_capture_source,
4826 .mixers = { alc880_f1734_mixer },
4827 .init_verbs = { alc880_volume_init_verbs,
4828 alc880_pin_f1734_init_verbs },
4829 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4830 .dac_nids = alc880_f1734_dac_nids,
4832 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4833 .channel_mode = alc880_2_jack_modes,
4834 .input_mux = &alc880_f1734_capture_source,
4835 .unsol_event = alc880_uniwill_p53_unsol_event,
4836 .setup = alc880_uniwill_p53_setup,
4837 .init_hook = alc_automute_amp,
4840 .mixers = { alc880_asus_mixer },
4841 .init_verbs = { alc880_volume_init_verbs,
4842 alc880_pin_asus_init_verbs,
4843 alc880_gpio1_init_verbs },
4844 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4845 .dac_nids = alc880_asus_dac_nids,
4846 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4847 .channel_mode = alc880_asus_modes,
4849 .input_mux = &alc880_capture_source,
4851 [ALC880_ASUS_DIG] = {
4852 .mixers = { alc880_asus_mixer },
4853 .init_verbs = { alc880_volume_init_verbs,
4854 alc880_pin_asus_init_verbs,
4855 alc880_gpio1_init_verbs },
4856 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4857 .dac_nids = alc880_asus_dac_nids,
4858 .dig_out_nid = ALC880_DIGOUT_NID,
4859 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4860 .channel_mode = alc880_asus_modes,
4862 .input_mux = &alc880_capture_source,
4864 [ALC880_ASUS_DIG2] = {
4865 .mixers = { alc880_asus_mixer },
4866 .init_verbs = { alc880_volume_init_verbs,
4867 alc880_pin_asus_init_verbs,
4868 alc880_gpio2_init_verbs }, /* use GPIO2 */
4869 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4870 .dac_nids = alc880_asus_dac_nids,
4871 .dig_out_nid = ALC880_DIGOUT_NID,
4872 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4873 .channel_mode = alc880_asus_modes,
4875 .input_mux = &alc880_capture_source,
4877 [ALC880_ASUS_W1V] = {
4878 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4879 .init_verbs = { alc880_volume_init_verbs,
4880 alc880_pin_asus_init_verbs,
4881 alc880_gpio1_init_verbs },
4882 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4883 .dac_nids = alc880_asus_dac_nids,
4884 .dig_out_nid = ALC880_DIGOUT_NID,
4885 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4886 .channel_mode = alc880_asus_modes,
4888 .input_mux = &alc880_capture_source,
4890 [ALC880_UNIWILL_DIG] = {
4891 .mixers = { alc880_asus_mixer },
4892 .init_verbs = { alc880_volume_init_verbs,
4893 alc880_pin_asus_init_verbs },
4894 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4895 .dac_nids = alc880_asus_dac_nids,
4896 .dig_out_nid = ALC880_DIGOUT_NID,
4897 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4898 .channel_mode = alc880_asus_modes,
4900 .input_mux = &alc880_capture_source,
4902 [ALC880_UNIWILL] = {
4903 .mixers = { alc880_uniwill_mixer },
4904 .init_verbs = { alc880_volume_init_verbs,
4905 alc880_uniwill_init_verbs },
4906 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4907 .dac_nids = alc880_asus_dac_nids,
4908 .dig_out_nid = ALC880_DIGOUT_NID,
4909 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4910 .channel_mode = alc880_threestack_modes,
4912 .input_mux = &alc880_capture_source,
4913 .unsol_event = alc880_uniwill_unsol_event,
4914 .setup = alc880_uniwill_setup,
4915 .init_hook = alc880_uniwill_init_hook,
4917 [ALC880_UNIWILL_P53] = {
4918 .mixers = { alc880_uniwill_p53_mixer },
4919 .init_verbs = { alc880_volume_init_verbs,
4920 alc880_uniwill_p53_init_verbs },
4921 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4922 .dac_nids = alc880_asus_dac_nids,
4923 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4924 .channel_mode = alc880_threestack_modes,
4925 .input_mux = &alc880_capture_source,
4926 .unsol_event = alc880_uniwill_p53_unsol_event,
4927 .setup = alc880_uniwill_p53_setup,
4928 .init_hook = alc_automute_amp,
4930 [ALC880_FUJITSU] = {
4931 .mixers = { alc880_fujitsu_mixer },
4932 .init_verbs = { alc880_volume_init_verbs,
4933 alc880_uniwill_p53_init_verbs,
4934 alc880_beep_init_verbs },
4935 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4936 .dac_nids = alc880_dac_nids,
4937 .dig_out_nid = ALC880_DIGOUT_NID,
4938 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4939 .channel_mode = alc880_2_jack_modes,
4940 .input_mux = &alc880_capture_source,
4941 .unsol_event = alc880_uniwill_p53_unsol_event,
4942 .setup = alc880_uniwill_p53_setup,
4943 .init_hook = alc_automute_amp,
4946 .mixers = { alc880_three_stack_mixer },
4947 .init_verbs = { alc880_volume_init_verbs,
4948 alc880_pin_clevo_init_verbs },
4949 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4950 .dac_nids = alc880_dac_nids,
4952 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4953 .channel_mode = alc880_threestack_modes,
4955 .input_mux = &alc880_capture_source,
4958 .mixers = { alc880_lg_mixer },
4959 .init_verbs = { alc880_volume_init_verbs,
4960 alc880_lg_init_verbs },
4961 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4962 .dac_nids = alc880_lg_dac_nids,
4963 .dig_out_nid = ALC880_DIGOUT_NID,
4964 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4965 .channel_mode = alc880_lg_ch_modes,
4967 .input_mux = &alc880_lg_capture_source,
4968 .unsol_event = alc_automute_amp_unsol_event,
4969 .setup = alc880_lg_setup,
4970 .init_hook = alc_automute_amp,
4971 #ifdef CONFIG_SND_HDA_POWER_SAVE
4972 .loopbacks = alc880_lg_loopbacks,
4976 .mixers = { alc880_lg_lw_mixer },
4977 .init_verbs = { alc880_volume_init_verbs,
4978 alc880_lg_lw_init_verbs },
4979 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4980 .dac_nids = alc880_dac_nids,
4981 .dig_out_nid = ALC880_DIGOUT_NID,
4982 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4983 .channel_mode = alc880_lg_lw_modes,
4984 .input_mux = &alc880_lg_lw_capture_source,
4985 .unsol_event = alc_automute_amp_unsol_event,
4986 .setup = alc880_lg_lw_setup,
4987 .init_hook = alc_automute_amp,
4989 [ALC880_MEDION_RIM] = {
4990 .mixers = { alc880_medion_rim_mixer },
4991 .init_verbs = { alc880_volume_init_verbs,
4992 alc880_medion_rim_init_verbs,
4993 alc_gpio2_init_verbs },
4994 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4995 .dac_nids = alc880_dac_nids,
4996 .dig_out_nid = ALC880_DIGOUT_NID,
4997 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4998 .channel_mode = alc880_2_jack_modes,
4999 .input_mux = &alc880_medion_rim_capture_source,
5000 .unsol_event = alc880_medion_rim_unsol_event,
5001 .setup = alc880_medion_rim_setup,
5002 .init_hook = alc880_medion_rim_automute,
5004 #ifdef CONFIG_SND_DEBUG
5006 .mixers = { alc880_test_mixer },
5007 .init_verbs = { alc880_test_init_verbs },
5008 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5009 .dac_nids = alc880_test_dac_nids,
5010 .dig_out_nid = ALC880_DIGOUT_NID,
5011 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5012 .channel_mode = alc880_test_modes,
5013 .input_mux = &alc880_test_capture_source,
5019 * Automatic parse of I/O pins from the BIOS configuration
5024 ALC_CTL_WIDGET_MUTE,
5027 static struct snd_kcontrol_new alc880_control_templates[] = {
5028 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5029 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5030 HDA_BIND_MUTE(NULL, 0, 0, 0),
5033 /* add dynamic controls */
5034 static int add_control(struct alc_spec *spec, int type, const char *name,
5035 int cidx, unsigned long val)
5037 struct snd_kcontrol_new *knew;
5039 snd_array_init(&spec->kctls, sizeof(*knew), 32);
5040 knew = snd_array_new(&spec->kctls);
5043 *knew = alc880_control_templates[type];
5044 knew->name = kstrdup(name, GFP_KERNEL);
5048 if (get_amp_nid_(val))
5049 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5050 knew->private_value = val;
5054 static int add_control_with_pfx(struct alc_spec *spec, int type,
5055 const char *pfx, const char *dir,
5056 const char *sfx, int cidx, unsigned long val)
5059 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5060 return add_control(spec, type, name, cidx, val);
5063 #define add_pb_vol_ctrl(spec, type, pfx, val) \
5064 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5065 #define add_pb_sw_ctrl(spec, type, pfx, val) \
5066 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5067 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5068 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5069 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5070 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5072 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5073 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5074 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5075 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5076 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
5077 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
5078 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5079 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
5080 #define ALC880_PIN_CD_NID 0x1c
5082 /* fill in the dac_nids table from the parsed pin configuration */
5083 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5084 const struct auto_pin_cfg *cfg)
5090 memset(assigned, 0, sizeof(assigned));
5091 spec->multiout.dac_nids = spec->private_dac_nids;
5093 /* check the pins hardwired to audio widget */
5094 for (i = 0; i < cfg->line_outs; i++) {
5095 nid = cfg->line_out_pins[i];
5096 if (alc880_is_fixed_pin(nid)) {
5097 int idx = alc880_fixed_pin_idx(nid);
5098 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
5102 /* left pins can be connect to any audio widget */
5103 for (i = 0; i < cfg->line_outs; i++) {
5104 nid = cfg->line_out_pins[i];
5105 if (alc880_is_fixed_pin(nid))
5107 /* search for an empty channel */
5108 for (j = 0; j < cfg->line_outs; j++) {
5110 spec->multiout.dac_nids[i] =
5111 alc880_idx_to_dac(j);
5117 spec->multiout.num_dacs = cfg->line_outs;
5121 static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5124 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5127 switch (cfg->line_out_type) {
5128 case AUTO_PIN_SPEAKER_OUT:
5130 case AUTO_PIN_HP_OUT:
5133 if (cfg->line_outs == 1)
5140 /* add playback controls from the parsed DAC table */
5141 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5142 const struct auto_pin_cfg *cfg)
5144 static const char *chname[4] = {
5145 "Front", "Surround", NULL /*CLFE*/, "Side"
5147 const char *pfx = alc_get_line_out_pfx(cfg, false);
5151 for (i = 0; i < cfg->line_outs; i++) {
5152 if (!spec->multiout.dac_nids[i])
5154 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5155 if (!pfx && i == 2) {
5157 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5159 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5163 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5165 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5169 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5171 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5175 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5177 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5182 const char *name = pfx;
5185 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5187 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5191 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5193 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5202 /* add playback controls for speaker and HP outputs */
5203 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5212 if (alc880_is_fixed_pin(pin)) {
5213 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5214 /* specify the DAC as the extra output */
5215 if (!spec->multiout.hp_nid)
5216 spec->multiout.hp_nid = nid;
5218 spec->multiout.extra_out_nid[0] = nid;
5219 /* control HP volume/switch on the output mixer amp */
5220 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5221 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5222 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5225 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5226 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5229 } else if (alc880_is_multi_pin(pin)) {
5230 /* set manual connection */
5231 /* we have only a switch on HP-out PIN */
5232 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5233 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5240 /* create input playback/capture controls for the given pin */
5241 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5242 const char *ctlname, int ctlidx,
5243 int idx, hda_nid_t mix_nid)
5247 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5248 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5251 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5252 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5258 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5260 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5261 return (pincap & AC_PINCAP_IN) != 0;
5264 /* create playback/capture controls for input pins */
5265 static int alc_auto_create_input_ctls(struct hda_codec *codec,
5266 const struct auto_pin_cfg *cfg,
5268 hda_nid_t cap1, hda_nid_t cap2)
5270 struct alc_spec *spec = codec->spec;
5271 struct hda_input_mux *imux = &spec->private_imux[0];
5272 int i, err, idx, type_idx = 0;
5273 const char *prev_label = NULL;
5275 for (i = 0; i < cfg->num_inputs; i++) {
5279 pin = cfg->inputs[i].pin;
5280 if (!alc_is_input_pin(codec, pin))
5283 label = hda_get_autocfg_input_label(codec, cfg, i);
5284 if (prev_label && !strcmp(label, prev_label))
5291 idx = get_connection_index(codec, mixer, pin);
5293 err = new_analog_input(spec, pin,
5303 idx = get_connection_index(codec, cap1, pin);
5304 if (idx < 0 && cap2)
5305 idx = get_connection_index(codec, cap2, pin);
5307 snd_hda_add_imux_item(imux, label, idx, NULL);
5312 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5313 const struct auto_pin_cfg *cfg)
5315 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5318 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5319 unsigned int pin_type)
5321 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5324 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5328 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5329 hda_nid_t nid, int pin_type,
5332 alc_set_pin_output(codec, nid, pin_type);
5333 /* need the manual connection? */
5334 if (alc880_is_multi_pin(nid)) {
5335 struct alc_spec *spec = codec->spec;
5336 int idx = alc880_multi_pin_idx(nid);
5337 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5338 AC_VERB_SET_CONNECT_SEL,
5339 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5343 static int get_pin_type(int line_out_type)
5345 if (line_out_type == AUTO_PIN_HP_OUT)
5351 static void alc880_auto_init_multi_out(struct hda_codec *codec)
5353 struct alc_spec *spec = codec->spec;
5356 for (i = 0; i < spec->autocfg.line_outs; i++) {
5357 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5358 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5359 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5363 static void alc880_auto_init_extra_out(struct hda_codec *codec)
5365 struct alc_spec *spec = codec->spec;
5368 pin = spec->autocfg.speaker_pins[0];
5369 if (pin) /* connect to front */
5370 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5371 pin = spec->autocfg.hp_pins[0];
5372 if (pin) /* connect to front */
5373 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5376 static void alc880_auto_init_analog_input(struct hda_codec *codec)
5378 struct alc_spec *spec = codec->spec;
5379 struct auto_pin_cfg *cfg = &spec->autocfg;
5382 for (i = 0; i < cfg->num_inputs; i++) {
5383 hda_nid_t nid = cfg->inputs[i].pin;
5384 if (alc_is_input_pin(codec, nid)) {
5385 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5386 if (nid != ALC880_PIN_CD_NID &&
5387 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5388 snd_hda_codec_write(codec, nid, 0,
5389 AC_VERB_SET_AMP_GAIN_MUTE,
5395 static void alc880_auto_init_input_src(struct hda_codec *codec)
5397 struct alc_spec *spec = codec->spec;
5400 for (c = 0; c < spec->num_adc_nids; c++) {
5401 unsigned int mux_idx;
5402 const struct hda_input_mux *imux;
5403 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5404 imux = &spec->input_mux[mux_idx];
5405 if (!imux->num_items && mux_idx > 0)
5406 imux = &spec->input_mux[0];
5408 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5409 AC_VERB_SET_CONNECT_SEL,
5410 imux->items[0].index);
5414 /* parse the BIOS configuration and set up the alc_spec */
5415 /* return 1 if successful, 0 if the proper config is not found,
5416 * or a negative error code
5418 static int alc880_parse_auto_config(struct hda_codec *codec)
5420 struct alc_spec *spec = codec->spec;
5422 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5424 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5428 if (!spec->autocfg.line_outs)
5429 return 0; /* can't find valid BIOS pin config */
5431 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5434 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5437 err = alc880_auto_create_extra_out(spec,
5438 spec->autocfg.speaker_pins[0],
5442 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5446 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5450 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5452 alc_auto_parse_digital(codec);
5454 if (spec->kctls.list)
5455 add_mixer(spec, spec->kctls.list);
5457 add_verb(spec, alc880_volume_init_verbs);
5459 spec->num_mux_defs = 1;
5460 spec->input_mux = &spec->private_imux[0];
5462 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5467 /* additional initialization for auto-configuration model */
5468 static void alc880_auto_init(struct hda_codec *codec)
5470 struct alc_spec *spec = codec->spec;
5471 alc880_auto_init_multi_out(codec);
5472 alc880_auto_init_extra_out(codec);
5473 alc880_auto_init_analog_input(codec);
5474 alc880_auto_init_input_src(codec);
5475 alc_auto_init_digital(codec);
5476 if (spec->unsol_event)
5477 alc_inithook(codec);
5480 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5481 * one of two digital mic pins, e.g. on ALC272
5483 static void fixup_automic_adc(struct hda_codec *codec)
5485 struct alc_spec *spec = codec->spec;
5488 for (i = 0; i < spec->num_adc_nids; i++) {
5489 hda_nid_t cap = spec->capsrc_nids ?
5490 spec->capsrc_nids[i] : spec->adc_nids[i];
5493 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5496 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5499 spec->int_mic.mux_idx = iidx;
5500 spec->ext_mic.mux_idx = eidx;
5501 if (spec->capsrc_nids)
5502 spec->capsrc_nids += i;
5503 spec->adc_nids += i;
5504 spec->num_adc_nids = 1;
5507 snd_printd(KERN_INFO "hda_codec: %s: "
5508 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5509 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5510 spec->auto_mic = 0; /* disable auto-mic to be sure */
5513 /* select or unmute the given capsrc route */
5514 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5517 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5518 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5521 snd_hda_codec_write_cache(codec, cap, 0,
5522 AC_VERB_SET_CONNECT_SEL, idx);
5526 /* set the default connection to that pin */
5527 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5529 struct alc_spec *spec = codec->spec;
5532 for (i = 0; i < spec->num_adc_nids; i++) {
5533 hda_nid_t cap = spec->capsrc_nids ?
5534 spec->capsrc_nids[i] : spec->adc_nids[i];
5537 idx = get_connection_index(codec, cap, pin);
5540 select_or_unmute_capsrc(codec, cap, idx);
5541 return i; /* return the found index */
5543 return -1; /* not found */
5546 /* choose the ADC/MUX containing the input pin and initialize the setup */
5547 static void fixup_single_adc(struct hda_codec *codec)
5549 struct alc_spec *spec = codec->spec;
5550 struct auto_pin_cfg *cfg = &spec->autocfg;
5553 /* search for the input pin; there must be only one */
5554 if (cfg->num_inputs != 1)
5556 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5558 /* use only this ADC */
5559 if (spec->capsrc_nids)
5560 spec->capsrc_nids += i;
5561 spec->adc_nids += i;
5562 spec->num_adc_nids = 1;
5566 /* initialize dual adcs */
5567 static void fixup_dual_adc_switch(struct hda_codec *codec)
5569 struct alc_spec *spec = codec->spec;
5570 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5571 init_capsrc_for_pin(codec, spec->int_mic.pin);
5574 static void set_capture_mixer(struct hda_codec *codec)
5576 struct alc_spec *spec = codec->spec;
5577 static struct snd_kcontrol_new *caps[2][3] = {
5578 { alc_capture_mixer_nosrc1,
5579 alc_capture_mixer_nosrc2,
5580 alc_capture_mixer_nosrc3 },
5581 { alc_capture_mixer1,
5583 alc_capture_mixer3 },
5585 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5587 int num_adcs = spec->num_adc_nids;
5588 if (spec->dual_adc_switch)
5589 fixup_dual_adc_switch(codec);
5590 else if (spec->auto_mic)
5591 fixup_automic_adc(codec);
5592 else if (spec->input_mux) {
5593 if (spec->input_mux->num_items > 1)
5595 else if (spec->input_mux->num_items == 1)
5596 fixup_single_adc(codec);
5598 if (spec->dual_adc_switch)
5600 spec->cap_mixer = caps[mux][num_adcs - 1];
5604 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5605 static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5608 struct alc_spec *spec = codec->spec;
5609 struct auto_pin_cfg *cfg = &spec->autocfg;
5611 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5613 for (n = 0; n < num_nids; n++) {
5615 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5619 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5622 nconns = snd_hda_get_connections(codec, cap, conn,
5626 nconns = snd_hda_get_connections(codec, cap, conn,
5631 if (!fallback_adc) {
5635 for (i = 0; i < cfg->num_inputs; i++) {
5636 hda_nid_t nid = cfg->inputs[i].pin;
5637 for (j = 0; j < nconns; j++) {
5644 if (i >= cfg->num_inputs) {
5645 int num_adcs = spec->num_adc_nids;
5646 spec->private_adc_nids[num_adcs] = adc;
5647 spec->private_capsrc_nids[num_adcs] = cap;
5648 spec->num_adc_nids++;
5649 spec->adc_nids = spec->private_adc_nids;
5651 spec->capsrc_nids = spec->private_capsrc_nids;
5654 if (!spec->num_adc_nids) {
5655 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5656 " using fallback 0x%x\n",
5657 codec->chip_name, fallback_adc);
5658 spec->private_adc_nids[0] = fallback_adc;
5659 spec->adc_nids = spec->private_adc_nids;
5660 if (fallback_adc != fallback_cap) {
5661 spec->private_capsrc_nids[0] = fallback_cap;
5662 spec->capsrc_nids = spec->private_adc_nids;
5667 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5668 #define set_beep_amp(spec, nid, idx, dir) \
5669 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5671 static struct snd_pci_quirk beep_white_list[] = {
5672 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5673 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5674 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5678 static inline int has_cdefine_beep(struct hda_codec *codec)
5680 struct alc_spec *spec = codec->spec;
5681 const struct snd_pci_quirk *q;
5682 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5685 return spec->cdefine.enable_pcbeep;
5688 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5689 #define has_cdefine_beep(codec) 0
5693 * OK, here we have finally the patch for ALC880
5696 static int patch_alc880(struct hda_codec *codec)
5698 struct alc_spec *spec;
5702 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5708 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5711 if (board_config < 0) {
5712 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5714 board_config = ALC880_AUTO;
5717 if (board_config == ALC880_AUTO) {
5718 /* automatic parse from the BIOS config */
5719 err = alc880_parse_auto_config(codec);
5725 "hda_codec: Cannot set up configuration "
5726 "from BIOS. Using 3-stack mode...\n");
5727 board_config = ALC880_3ST;
5731 err = snd_hda_attach_beep_device(codec, 0x1);
5737 if (board_config != ALC880_AUTO)
5738 setup_preset(codec, &alc880_presets[board_config]);
5740 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5741 spec->stream_analog_capture = &alc880_pcm_analog_capture;
5742 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
5744 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5745 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5747 if (!spec->adc_nids && spec->input_mux) {
5748 /* check whether NID 0x07 is valid */
5749 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
5751 wcap = get_wcaps_type(wcap);
5752 if (wcap != AC_WID_AUD_IN) {
5753 spec->adc_nids = alc880_adc_nids_alt;
5754 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
5756 spec->adc_nids = alc880_adc_nids;
5757 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
5760 set_capture_mixer(codec);
5761 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5763 spec->vmaster_nid = 0x0c;
5765 codec->patch_ops = alc_patch_ops;
5766 if (board_config == ALC880_AUTO)
5767 spec->init_hook = alc880_auto_init;
5768 #ifdef CONFIG_SND_HDA_POWER_SAVE
5769 if (!spec->loopback.amplist)
5770 spec->loopback.amplist = alc880_loopbacks;
5781 static hda_nid_t alc260_dac_nids[1] = {
5786 static hda_nid_t alc260_adc_nids[1] = {
5791 static hda_nid_t alc260_adc_nids_alt[1] = {
5796 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5797 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5799 static hda_nid_t alc260_dual_adc_nids[2] = {
5804 #define ALC260_DIGOUT_NID 0x03
5805 #define ALC260_DIGIN_NID 0x06
5807 static struct hda_input_mux alc260_capture_source = {
5811 { "Front Mic", 0x1 },
5817 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5818 * headphone jack and the internal CD lines since these are the only pins at
5819 * which audio can appear. For flexibility, also allow the option of
5820 * recording the mixer output on the second ADC (ADC0 doesn't have a
5821 * connection to the mixer output).
5823 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5827 { "Mic/Line", 0x0 },
5829 { "Headphone", 0x2 },
5835 { "Mic/Line", 0x0 },
5837 { "Headphone", 0x2 },
5844 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5845 * the Fujitsu S702x, but jacks are marked differently.
5847 static struct hda_input_mux alc260_acer_capture_sources[2] = {
5854 { "Headphone", 0x5 },
5863 { "Headphone", 0x6 },
5869 /* Maxdata Favorit 100XS */
5870 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5874 { "Line/Mic", 0x0 },
5881 { "Line/Mic", 0x0 },
5889 * This is just place-holder, so there's something for alc_build_pcms to look
5890 * at when it calculates the maximum number of channels. ALC260 has no mixer
5891 * element which allows changing the channel mode, so the verb list is
5894 static struct hda_channel_mode alc260_modes[1] = {
5899 /* Mixer combinations
5901 * basic: base_output + input + pc_beep + capture
5902 * HP: base_output + input + capture_alt
5903 * HP_3013: hp_3013 + input + capture
5904 * fujitsu: fujitsu + capture
5905 * acer: acer + capture
5908 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5909 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5910 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5911 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5912 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5913 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5914 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5918 static struct snd_kcontrol_new alc260_input_mixer[] = {
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("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5922 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5923 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5924 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5925 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5926 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5930 /* update HP, line and mono out pins according to the master switch */
5931 static void alc260_hp_master_update(struct hda_codec *codec,
5932 hda_nid_t hp, hda_nid_t line,
5935 struct alc_spec *spec = codec->spec;
5936 unsigned int val = spec->master_sw ? PIN_HP : 0;
5937 /* change HP and line-out pins */
5938 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5940 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5942 /* mono (speaker) depending on the HP jack sense */
5943 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5944 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5948 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5949 struct snd_ctl_elem_value *ucontrol)
5951 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5952 struct alc_spec *spec = codec->spec;
5953 *ucontrol->value.integer.value = spec->master_sw;
5957 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5958 struct snd_ctl_elem_value *ucontrol)
5960 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5961 struct alc_spec *spec = codec->spec;
5962 int val = !!*ucontrol->value.integer.value;
5963 hda_nid_t hp, line, mono;
5965 if (val == spec->master_sw)
5967 spec->master_sw = val;
5968 hp = (kcontrol->private_value >> 16) & 0xff;
5969 line = (kcontrol->private_value >> 8) & 0xff;
5970 mono = kcontrol->private_value & 0xff;
5971 alc260_hp_master_update(codec, hp, line, mono);
5975 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5977 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5978 .name = "Master Playback Switch",
5979 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5980 .info = snd_ctl_boolean_mono_info,
5981 .get = alc260_hp_master_sw_get,
5982 .put = alc260_hp_master_sw_put,
5983 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5985 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5986 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5987 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5988 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5989 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5991 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5995 static struct hda_verb alc260_hp_unsol_verbs[] = {
5996 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6000 static void alc260_hp_automute(struct hda_codec *codec)
6002 struct alc_spec *spec = codec->spec;
6004 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
6005 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
6008 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
6010 if ((res >> 26) == ALC880_HP_EVENT)
6011 alc260_hp_automute(codec);
6014 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6016 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6017 .name = "Master Playback Switch",
6018 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6019 .info = snd_ctl_boolean_mono_info,
6020 .get = alc260_hp_master_sw_get,
6021 .put = alc260_hp_master_sw_put,
6022 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
6024 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6025 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6026 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6027 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6028 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6030 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6031 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6035 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6036 .ops = &snd_hda_bind_vol,
6038 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6039 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6040 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6045 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6046 .ops = &snd_hda_bind_sw,
6048 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6049 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6054 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6055 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6056 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6057 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6058 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6062 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6063 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6067 static void alc260_hp_3013_automute(struct hda_codec *codec)
6069 struct alc_spec *spec = codec->spec;
6071 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
6072 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
6075 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6078 if ((res >> 26) == ALC880_HP_EVENT)
6079 alc260_hp_3013_automute(codec);
6082 static void alc260_hp_3012_automute(struct hda_codec *codec)
6084 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
6086 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6088 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6090 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6094 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6097 if ((res >> 26) == ALC880_HP_EVENT)
6098 alc260_hp_3012_automute(codec);
6101 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6102 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6104 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6105 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6106 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6107 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6108 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6109 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6110 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6111 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6112 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6113 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6114 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6118 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6119 * versions of the ALC260 don't act on requests to enable mic bias from NID
6120 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6121 * datasheet doesn't mention this restriction. At this stage it's not clear
6122 * whether this behaviour is intentional or is a hardware bug in chip
6123 * revisions available in early 2006. Therefore for now allow the
6124 * "Headphone Jack Mode" control to span all choices, but if it turns out
6125 * that the lack of mic bias for this NID is intentional we could change the
6126 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6128 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6129 * don't appear to make the mic bias available from the "line" jack, even
6130 * though the NID used for this jack (0x14) can supply it. The theory is
6131 * that perhaps Acer have included blocking capacitors between the ALC260
6132 * and the output jack. If this turns out to be the case for all such
6133 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6134 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6136 * The C20x Tablet series have a mono internal speaker which is controlled
6137 * via the chip's Mono sum widget and pin complex, so include the necessary
6138 * controls for such models. On models without a "mono speaker" the control
6139 * won't do anything.
6141 static struct snd_kcontrol_new alc260_acer_mixer[] = {
6142 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6143 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6144 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6145 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6147 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6149 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6150 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6151 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6152 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6153 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6154 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6155 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6156 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6160 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
6162 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6163 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6164 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6165 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6166 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6167 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6168 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6172 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6173 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6175 static struct snd_kcontrol_new alc260_will_mixer[] = {
6176 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6177 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6179 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6180 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6181 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6182 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6183 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6184 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6185 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6189 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6190 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6192 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6193 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6194 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6196 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6197 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6198 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6199 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6200 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6201 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6202 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6207 * initialization verbs
6209 static struct hda_verb alc260_init_verbs[] = {
6210 /* Line In pin widget for input */
6211 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6212 /* CD pin widget for input */
6213 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6214 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6215 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6216 /* Mic2 (front panel) pin widget for input and vref at 80% */
6217 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6218 /* LINE-2 is used for line-out in rear */
6219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6220 /* select line-out */
6221 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6223 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6225 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6227 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6228 /* mute capture amp left and right */
6229 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6230 /* set connection select to line in (default select for this ADC) */
6231 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6232 /* mute capture amp left and right */
6233 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6234 /* set connection select to line in (default select for this ADC) */
6235 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6236 /* set vol=0 Line-Out mixer amp left and right */
6237 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6238 /* unmute pin widget amp left and right (no gain on this amp) */
6239 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6240 /* set vol=0 HP mixer amp left and right */
6241 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6242 /* unmute pin widget amp left and right (no gain on this amp) */
6243 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6244 /* set vol=0 Mono mixer amp left and right */
6245 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6246 /* unmute pin widget amp left and right (no gain on this amp) */
6247 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6248 /* unmute LINE-2 out pin */
6249 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6250 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6253 /* mute analog inputs */
6254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6256 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6259 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6260 /* mute Front out path */
6261 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6263 /* mute Headphone out path */
6264 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6265 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6266 /* mute Mono out path */
6267 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6268 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6272 #if 0 /* should be identical with alc260_init_verbs? */
6273 static struct hda_verb alc260_hp_init_verbs[] = {
6274 /* Headphone and output */
6275 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6277 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6278 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6279 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6280 /* Mic2 (front panel) pin widget for input and vref at 80% */
6281 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6282 /* Line In pin widget for input */
6283 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6284 /* Line-2 pin widget for output */
6285 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6286 /* CD pin widget for input */
6287 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6288 /* unmute amp left and right */
6289 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6290 /* set connection select to line in (default select for this ADC) */
6291 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6292 /* unmute Line-Out mixer amp left and right (volume = 0) */
6293 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6294 /* mute pin widget amp left and right (no gain on this amp) */
6295 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6296 /* unmute HP mixer amp left and right (volume = 0) */
6297 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6298 /* mute pin widget amp left and right (no gain on this amp) */
6299 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6300 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6303 /* mute analog inputs */
6304 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6305 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6306 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6309 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6310 /* Unmute Front out path */
6311 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6312 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6313 /* Unmute Headphone out path */
6314 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6315 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6316 /* Unmute Mono out path */
6317 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6318 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6323 static struct hda_verb alc260_hp_3013_init_verbs[] = {
6324 /* Line out and output */
6325 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6327 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6328 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6330 /* Mic2 (front panel) pin widget for input and vref at 80% */
6331 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6332 /* Line In pin widget for input */
6333 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6334 /* Headphone pin widget for output */
6335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6336 /* CD pin widget for input */
6337 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6338 /* unmute amp left and right */
6339 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6340 /* set connection select to line in (default select for this ADC) */
6341 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6342 /* unmute Line-Out mixer amp left and right (volume = 0) */
6343 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6344 /* mute pin widget amp left and right (no gain on this amp) */
6345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6346 /* unmute HP mixer amp left and right (volume = 0) */
6347 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6348 /* mute pin widget amp left and right (no gain on this amp) */
6349 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6350 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6353 /* mute analog inputs */
6354 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6355 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6356 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6358 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6359 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6360 /* Unmute Front out path */
6361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6362 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6363 /* Unmute Headphone out path */
6364 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6365 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6366 /* Unmute Mono out path */
6367 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6368 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6372 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6373 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6374 * audio = 0x16, internal speaker = 0x10.
6376 static struct hda_verb alc260_fujitsu_init_verbs[] = {
6377 /* Disable all GPIOs */
6378 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6379 /* Internal speaker is connected to headphone pin */
6380 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6381 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6383 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6384 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6385 /* Ensure all other unused pins are disabled and muted. */
6386 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6387 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6388 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6389 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6390 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6391 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6392 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6393 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6395 /* Disable digital (SPDIF) pins */
6396 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6397 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6399 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6400 * when acting as an output.
6402 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6404 /* Start with output sum widgets muted and their output gains at min */
6405 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6406 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6407 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6408 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6409 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6410 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6411 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6412 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6413 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6415 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6416 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6417 /* Unmute Line1 pin widget output buffer since it starts as an output.
6418 * If the pin mode is changed by the user the pin mode control will
6419 * take care of enabling the pin's input/output buffers as needed.
6420 * Therefore there's no need to enable the input buffer at this
6423 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6424 /* Unmute input buffer of pin widget used for Line-in (no equiv
6427 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6429 /* Mute capture amp left and right */
6430 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6431 /* Set ADC connection select to match default mixer setting - line
6434 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6436 /* Do the same for the second ADC: mute capture input amp and
6437 * set ADC connection to line in (on mic1 pin)
6439 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6440 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6442 /* Mute all inputs to mixer widget (even unconnected ones) */
6443 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6444 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6445 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6447 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6448 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6449 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6455 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6456 * similar laptops (adapted from Fujitsu init verbs).
6458 static struct hda_verb alc260_acer_init_verbs[] = {
6459 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6460 * the headphone jack. Turn this on and rely on the standard mute
6461 * methods whenever the user wants to turn these outputs off.
6463 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6464 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6465 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6466 /* Internal speaker/Headphone jack is connected to Line-out pin */
6467 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6468 /* Internal microphone/Mic jack is connected to Mic1 pin */
6469 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6470 /* Line In jack is connected to Line1 pin */
6471 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6472 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6473 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6474 /* Ensure all other unused pins are disabled and muted. */
6475 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6476 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6477 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6478 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6479 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6480 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6481 /* Disable digital (SPDIF) pins */
6482 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6483 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6485 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6486 * bus when acting as outputs.
6488 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6489 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6491 /* Start with output sum widgets muted and their output gains at min */
6492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6495 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6498 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6500 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6502 /* Unmute Line-out pin widget amp left and right
6503 * (no equiv mixer ctrl)
6505 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6506 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6507 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6509 * inputs. If the pin mode is changed by the user the pin mode control
6510 * will take care of enabling the pin's input/output buffers as needed.
6511 * Therefore there's no need to enable the input buffer at this
6514 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6515 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6517 /* Mute capture amp left and right */
6518 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6519 /* Set ADC connection select to match default mixer setting - mic
6522 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6524 /* Do similar with the second ADC: mute capture input amp and
6525 * set ADC connection to mic to match ALSA's default state.
6527 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6528 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6530 /* Mute all inputs to mixer widget (even unconnected ones) */
6531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6538 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6543 /* Initialisation sequence for Maxdata Favorit 100XS
6544 * (adapted from Acer init verbs).
6546 static struct hda_verb alc260_favorit100_init_verbs[] = {
6547 /* GPIO 0 enables the output jack.
6548 * Turn this on and rely on the standard mute
6549 * methods whenever the user wants to turn these outputs off.
6551 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6552 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6553 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6554 /* Line/Mic input jack is connected to Mic1 pin */
6555 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6556 /* Ensure all other unused pins are disabled and muted. */
6557 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6558 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6559 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6560 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6561 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6562 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6567 /* Disable digital (SPDIF) pins */
6568 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6569 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6571 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6572 * bus when acting as outputs.
6574 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6575 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6577 /* Start with output sum widgets muted and their output gains at min */
6578 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6581 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6584 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6588 /* Unmute Line-out pin widget amp left and right
6589 * (no equiv mixer ctrl)
6591 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6592 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6593 * inputs. If the pin mode is changed by the user the pin mode control
6594 * will take care of enabling the pin's input/output buffers as needed.
6595 * Therefore there's no need to enable the input buffer at this
6598 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6600 /* Mute capture amp left and right */
6601 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6602 /* Set ADC connection select to match default mixer setting - mic
6605 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6607 /* Do similar with the second ADC: mute capture input amp and
6608 * set ADC connection to mic to match ALSA's default state.
6610 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6611 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6613 /* Mute all inputs to mixer widget (even unconnected ones) */
6614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6615 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6626 static struct hda_verb alc260_will_verbs[] = {
6627 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6628 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6629 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6630 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6631 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6632 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6636 static struct hda_verb alc260_replacer_672v_verbs[] = {
6637 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6638 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6639 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6641 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6642 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6643 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6645 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6649 /* toggle speaker-output according to the hp-jack state */
6650 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6652 unsigned int present;
6654 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6655 present = snd_hda_jack_detect(codec, 0x0f);
6657 snd_hda_codec_write_cache(codec, 0x01, 0,
6658 AC_VERB_SET_GPIO_DATA, 1);
6659 snd_hda_codec_write_cache(codec, 0x0f, 0,
6660 AC_VERB_SET_PIN_WIDGET_CONTROL,
6663 snd_hda_codec_write_cache(codec, 0x01, 0,
6664 AC_VERB_SET_GPIO_DATA, 0);
6665 snd_hda_codec_write_cache(codec, 0x0f, 0,
6666 AC_VERB_SET_PIN_WIDGET_CONTROL,
6671 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6674 if ((res >> 26) == ALC880_HP_EVENT)
6675 alc260_replacer_672v_automute(codec);
6678 static struct hda_verb alc260_hp_dc7600_verbs[] = {
6679 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6680 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6681 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6682 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6683 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6684 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6685 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6686 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6687 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6688 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6692 /* Test configuration for debugging, modelled after the ALC880 test
6695 #ifdef CONFIG_SND_DEBUG
6696 static hda_nid_t alc260_test_dac_nids[1] = {
6699 static hda_nid_t alc260_test_adc_nids[2] = {
6702 /* For testing the ALC260, each input MUX needs its own definition since
6703 * the signal assignments are different. This assumes that the first ADC
6706 static struct hda_input_mux alc260_test_capture_sources[2] = {
6710 { "MIC1 pin", 0x0 },
6711 { "MIC2 pin", 0x1 },
6712 { "LINE1 pin", 0x2 },
6713 { "LINE2 pin", 0x3 },
6715 { "LINE-OUT pin", 0x5 },
6716 { "HP-OUT pin", 0x6 },
6722 { "MIC1 pin", 0x0 },
6723 { "MIC2 pin", 0x1 },
6724 { "LINE1 pin", 0x2 },
6725 { "LINE2 pin", 0x3 },
6728 { "LINE-OUT pin", 0x6 },
6729 { "HP-OUT pin", 0x7 },
6733 static struct snd_kcontrol_new alc260_test_mixer[] = {
6734 /* Output driver widgets */
6735 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6736 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6737 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6738 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6739 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6740 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6742 /* Modes for retasking pin widgets
6743 * Note: the ALC260 doesn't seem to act on requests to enable mic
6744 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6745 * mention this restriction. At this stage it's not clear whether
6746 * this behaviour is intentional or is a hardware bug in chip
6747 * revisions available at least up until early 2006. Therefore for
6748 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6749 * choices, but if it turns out that the lack of mic bias for these
6750 * NIDs is intentional we could change their modes from
6751 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6753 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6754 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6755 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6756 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6757 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6758 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6760 /* Loopback mixer controls */
6761 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6762 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6763 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6764 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6765 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6766 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6767 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6768 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6769 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6770 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6771 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6772 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6773 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6774 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6776 /* Controls for GPIO pins, assuming they are configured as outputs */
6777 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6778 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6779 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6780 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6782 /* Switches to allow the digital IO pins to be enabled. The datasheet
6783 * is ambigious as to which NID is which; testing on laptops which
6784 * make this output available should provide clarification.
6786 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6787 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6789 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6790 * this output to turn on an external amplifier.
6792 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6793 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6797 static struct hda_verb alc260_test_init_verbs[] = {
6798 /* Enable all GPIOs as outputs with an initial value of 0 */
6799 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6800 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6801 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6803 /* Enable retasking pins as output, initially without power amp */
6804 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6805 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6808 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6809 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6811 /* Disable digital (SPDIF) pins initially, but users can enable
6812 * them via a mixer switch. In the case of SPDIF-out, this initverb
6813 * payload also sets the generation to 0, output to be in "consumer"
6814 * PCM format, copyright asserted, no pre-emphasis and no validity
6817 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6818 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6820 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6821 * OUT1 sum bus when acting as an output.
6823 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6824 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6825 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6826 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6828 /* Start with output sum widgets muted and their output gains at min */
6829 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6830 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6831 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6832 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6833 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6834 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6835 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6836 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6837 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6839 /* Unmute retasking pin widget output buffers since the default
6840 * state appears to be output. As the pin mode is changed by the
6841 * user the pin mode control will take care of enabling the pin's
6842 * input/output buffers as needed.
6844 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6845 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6848 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6849 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6850 /* Also unmute the mono-out pin widget */
6851 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6853 /* Mute capture amp left and right */
6854 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 /* Set ADC connection select to match default mixer setting (mic1
6858 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6860 /* Do the same for the second ADC: mute capture input amp and
6861 * set ADC connection to mic1 pin
6863 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6864 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6866 /* Mute all inputs to mixer widget (even unconnected ones) */
6867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6868 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6869 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6870 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6871 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6880 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6881 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
6883 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
6884 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
6887 * for BIOS auto-configuration
6890 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6891 const char *pfx, int *vol_bits)
6894 unsigned long vol_val, sw_val;
6897 if (nid >= 0x0f && nid < 0x11) {
6898 nid_vol = nid - 0x7;
6899 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6900 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6901 } else if (nid == 0x11) {
6902 nid_vol = nid - 0x7;
6903 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6904 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6905 } else if (nid >= 0x12 && nid <= 0x15) {
6907 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6908 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6912 if (!(*vol_bits & (1 << nid_vol))) {
6913 /* first control for the volume widget */
6914 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6917 *vol_bits |= (1 << nid_vol);
6919 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6925 /* add playback controls from the parsed DAC table */
6926 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6927 const struct auto_pin_cfg *cfg)
6933 spec->multiout.num_dacs = 1;
6934 spec->multiout.dac_nids = spec->private_dac_nids;
6935 spec->multiout.dac_nids[0] = 0x02;
6937 nid = cfg->line_out_pins[0];
6940 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6942 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6946 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6951 nid = cfg->speaker_pins[0];
6953 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6958 nid = cfg->hp_pins[0];
6960 err = alc260_add_playback_controls(spec, nid, "Headphone",
6968 /* create playback/capture controls for input pins */
6969 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6970 const struct auto_pin_cfg *cfg)
6972 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6975 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6976 hda_nid_t nid, int pin_type,
6979 alc_set_pin_output(codec, nid, pin_type);
6980 /* need the manual connection? */
6982 int idx = nid - 0x12;
6983 snd_hda_codec_write(codec, idx + 0x0b, 0,
6984 AC_VERB_SET_CONNECT_SEL, sel_idx);
6988 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6990 struct alc_spec *spec = codec->spec;
6993 nid = spec->autocfg.line_out_pins[0];
6995 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6996 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6999 nid = spec->autocfg.speaker_pins[0];
7001 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7003 nid = spec->autocfg.hp_pins[0];
7005 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7008 #define ALC260_PIN_CD_NID 0x16
7009 static void alc260_auto_init_analog_input(struct hda_codec *codec)
7011 struct alc_spec *spec = codec->spec;
7012 struct auto_pin_cfg *cfg = &spec->autocfg;
7015 for (i = 0; i < cfg->num_inputs; i++) {
7016 hda_nid_t nid = cfg->inputs[i].pin;
7018 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7019 if (nid != ALC260_PIN_CD_NID &&
7020 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7021 snd_hda_codec_write(codec, nid, 0,
7022 AC_VERB_SET_AMP_GAIN_MUTE,
7028 #define alc260_auto_init_input_src alc880_auto_init_input_src
7031 * generic initialization of ADC, input mixers and output mixers
7033 static struct hda_verb alc260_volume_init_verbs[] = {
7035 * Unmute ADC0-1 and set the default input to mic-in
7037 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7038 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7039 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7040 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7042 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7044 * Note: PASD motherboards uses the Line In 2 as the input for
7045 * front panel mic (mic 2)
7047 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7048 /* mute analog inputs */
7049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7052 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7053 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7056 * Set up output mixers (0x08 - 0x0a)
7058 /* set vol=0 to output mixers */
7059 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7060 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7061 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7062 /* set up input amps for analog loopback */
7063 /* Amp Indices: DAC = 0, mixer = 1 */
7064 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7065 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7066 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7067 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7068 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7069 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7074 static int alc260_parse_auto_config(struct hda_codec *codec)
7076 struct alc_spec *spec = codec->spec;
7078 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7080 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7084 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7087 if (!spec->kctls.list)
7088 return 0; /* can't find valid BIOS pin config */
7089 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7093 spec->multiout.max_channels = 2;
7095 if (spec->autocfg.dig_outs)
7096 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7097 if (spec->kctls.list)
7098 add_mixer(spec, spec->kctls.list);
7100 add_verb(spec, alc260_volume_init_verbs);
7102 spec->num_mux_defs = 1;
7103 spec->input_mux = &spec->private_imux[0];
7105 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7110 /* additional initialization for auto-configuration model */
7111 static void alc260_auto_init(struct hda_codec *codec)
7113 struct alc_spec *spec = codec->spec;
7114 alc260_auto_init_multi_out(codec);
7115 alc260_auto_init_analog_input(codec);
7116 alc260_auto_init_input_src(codec);
7117 alc_auto_init_digital(codec);
7118 if (spec->unsol_event)
7119 alc_inithook(codec);
7122 #ifdef CONFIG_SND_HDA_POWER_SAVE
7123 static struct hda_amp_list alc260_loopbacks[] = {
7124 { 0x07, HDA_INPUT, 0 },
7125 { 0x07, HDA_INPUT, 1 },
7126 { 0x07, HDA_INPUT, 2 },
7127 { 0x07, HDA_INPUT, 3 },
7128 { 0x07, HDA_INPUT, 4 },
7140 static const struct alc_fixup alc260_fixups[] = {
7141 [PINFIX_HP_DC5750] = {
7142 .type = ALC_FIXUP_PINS,
7143 .v.pins = (const struct alc_pincfg[]) {
7144 { 0x11, 0x90130110 }, /* speaker */
7150 static struct snd_pci_quirk alc260_fixup_tbl[] = {
7151 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7156 * ALC260 configurations
7158 static const char *alc260_models[ALC260_MODEL_LAST] = {
7159 [ALC260_BASIC] = "basic",
7161 [ALC260_HP_3013] = "hp-3013",
7162 [ALC260_HP_DC7600] = "hp-dc7600",
7163 [ALC260_FUJITSU_S702X] = "fujitsu",
7164 [ALC260_ACER] = "acer",
7165 [ALC260_WILL] = "will",
7166 [ALC260_REPLACER_672V] = "replacer",
7167 [ALC260_FAVORIT100] = "favorit100",
7168 #ifdef CONFIG_SND_DEBUG
7169 [ALC260_TEST] = "test",
7171 [ALC260_AUTO] = "auto",
7174 static struct snd_pci_quirk alc260_cfg_tbl[] = {
7175 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7176 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7177 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7178 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7179 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7180 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7181 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7182 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7183 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7184 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7185 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7186 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7187 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7188 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7189 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7190 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7191 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7192 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7193 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7194 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7198 static struct alc_config_preset alc260_presets[] = {
7200 .mixers = { alc260_base_output_mixer,
7201 alc260_input_mixer },
7202 .init_verbs = { alc260_init_verbs },
7203 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7204 .dac_nids = alc260_dac_nids,
7205 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7206 .adc_nids = alc260_dual_adc_nids,
7207 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7208 .channel_mode = alc260_modes,
7209 .input_mux = &alc260_capture_source,
7212 .mixers = { alc260_hp_output_mixer,
7213 alc260_input_mixer },
7214 .init_verbs = { alc260_init_verbs,
7215 alc260_hp_unsol_verbs },
7216 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7217 .dac_nids = alc260_dac_nids,
7218 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7219 .adc_nids = alc260_adc_nids_alt,
7220 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7221 .channel_mode = alc260_modes,
7222 .input_mux = &alc260_capture_source,
7223 .unsol_event = alc260_hp_unsol_event,
7224 .init_hook = alc260_hp_automute,
7226 [ALC260_HP_DC7600] = {
7227 .mixers = { alc260_hp_dc7600_mixer,
7228 alc260_input_mixer },
7229 .init_verbs = { alc260_init_verbs,
7230 alc260_hp_dc7600_verbs },
7231 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7232 .dac_nids = alc260_dac_nids,
7233 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7234 .adc_nids = alc260_adc_nids_alt,
7235 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7236 .channel_mode = alc260_modes,
7237 .input_mux = &alc260_capture_source,
7238 .unsol_event = alc260_hp_3012_unsol_event,
7239 .init_hook = alc260_hp_3012_automute,
7241 [ALC260_HP_3013] = {
7242 .mixers = { alc260_hp_3013_mixer,
7243 alc260_input_mixer },
7244 .init_verbs = { alc260_hp_3013_init_verbs,
7245 alc260_hp_3013_unsol_verbs },
7246 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7247 .dac_nids = alc260_dac_nids,
7248 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7249 .adc_nids = alc260_adc_nids_alt,
7250 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7251 .channel_mode = alc260_modes,
7252 .input_mux = &alc260_capture_source,
7253 .unsol_event = alc260_hp_3013_unsol_event,
7254 .init_hook = alc260_hp_3013_automute,
7256 [ALC260_FUJITSU_S702X] = {
7257 .mixers = { alc260_fujitsu_mixer },
7258 .init_verbs = { alc260_fujitsu_init_verbs },
7259 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7260 .dac_nids = alc260_dac_nids,
7261 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7262 .adc_nids = alc260_dual_adc_nids,
7263 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7264 .channel_mode = alc260_modes,
7265 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7266 .input_mux = alc260_fujitsu_capture_sources,
7269 .mixers = { alc260_acer_mixer },
7270 .init_verbs = { alc260_acer_init_verbs },
7271 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7272 .dac_nids = alc260_dac_nids,
7273 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7274 .adc_nids = alc260_dual_adc_nids,
7275 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7276 .channel_mode = alc260_modes,
7277 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7278 .input_mux = alc260_acer_capture_sources,
7280 [ALC260_FAVORIT100] = {
7281 .mixers = { alc260_favorit100_mixer },
7282 .init_verbs = { alc260_favorit100_init_verbs },
7283 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7284 .dac_nids = alc260_dac_nids,
7285 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7286 .adc_nids = alc260_dual_adc_nids,
7287 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7288 .channel_mode = alc260_modes,
7289 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7290 .input_mux = alc260_favorit100_capture_sources,
7293 .mixers = { alc260_will_mixer },
7294 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7295 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7296 .dac_nids = alc260_dac_nids,
7297 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7298 .adc_nids = alc260_adc_nids,
7299 .dig_out_nid = ALC260_DIGOUT_NID,
7300 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7301 .channel_mode = alc260_modes,
7302 .input_mux = &alc260_capture_source,
7304 [ALC260_REPLACER_672V] = {
7305 .mixers = { alc260_replacer_672v_mixer },
7306 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7307 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7308 .dac_nids = alc260_dac_nids,
7309 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7310 .adc_nids = alc260_adc_nids,
7311 .dig_out_nid = ALC260_DIGOUT_NID,
7312 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7313 .channel_mode = alc260_modes,
7314 .input_mux = &alc260_capture_source,
7315 .unsol_event = alc260_replacer_672v_unsol_event,
7316 .init_hook = alc260_replacer_672v_automute,
7318 #ifdef CONFIG_SND_DEBUG
7320 .mixers = { alc260_test_mixer },
7321 .init_verbs = { alc260_test_init_verbs },
7322 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7323 .dac_nids = alc260_test_dac_nids,
7324 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7325 .adc_nids = alc260_test_adc_nids,
7326 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7327 .channel_mode = alc260_modes,
7328 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7329 .input_mux = alc260_test_capture_sources,
7334 static int patch_alc260(struct hda_codec *codec)
7336 struct alc_spec *spec;
7337 int err, board_config;
7339 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7345 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7348 if (board_config < 0) {
7349 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7351 board_config = ALC260_AUTO;
7354 if (board_config == ALC260_AUTO) {
7355 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7356 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7359 if (board_config == ALC260_AUTO) {
7360 /* automatic parse from the BIOS config */
7361 err = alc260_parse_auto_config(codec);
7367 "hda_codec: Cannot set up configuration "
7368 "from BIOS. Using base mode...\n");
7369 board_config = ALC260_BASIC;
7373 err = snd_hda_attach_beep_device(codec, 0x1);
7379 if (board_config != ALC260_AUTO)
7380 setup_preset(codec, &alc260_presets[board_config]);
7382 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7383 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7384 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7386 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7387 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7389 if (!spec->adc_nids && spec->input_mux) {
7390 /* check whether NID 0x04 is valid */
7391 unsigned int wcap = get_wcaps(codec, 0x04);
7392 wcap = get_wcaps_type(wcap);
7394 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7395 spec->adc_nids = alc260_adc_nids_alt;
7396 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7398 spec->adc_nids = alc260_adc_nids;
7399 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7402 set_capture_mixer(codec);
7403 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7405 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7407 spec->vmaster_nid = 0x08;
7409 codec->patch_ops = alc_patch_ops;
7410 if (board_config == ALC260_AUTO)
7411 spec->init_hook = alc260_auto_init;
7412 #ifdef CONFIG_SND_HDA_POWER_SAVE
7413 if (!spec->loopback.amplist)
7414 spec->loopback.amplist = alc260_loopbacks;
7422 * ALC882/883/885/888/889 support
7424 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7425 * configuration. Each pin widget can choose any input DACs and a mixer.
7426 * Each ADC is connected from a mixer of all inputs. This makes possible
7427 * 6-channel independent captures.
7429 * In addition, an independent DAC for the multi-playback (not used in this
7432 #define ALC882_DIGOUT_NID 0x06
7433 #define ALC882_DIGIN_NID 0x0a
7434 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7435 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7436 #define ALC1200_DIGOUT_NID 0x10
7439 static struct hda_channel_mode alc882_ch_modes[1] = {
7444 static hda_nid_t alc882_dac_nids[4] = {
7445 /* front, rear, clfe, rear_surr */
7446 0x02, 0x03, 0x04, 0x05
7448 #define alc883_dac_nids alc882_dac_nids
7451 #define alc882_adc_nids alc880_adc_nids
7452 #define alc882_adc_nids_alt alc880_adc_nids_alt
7453 #define alc883_adc_nids alc882_adc_nids_alt
7454 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7455 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7456 #define alc889_adc_nids alc880_adc_nids
7458 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7459 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7460 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7461 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7462 #define alc889_capsrc_nids alc882_capsrc_nids
7465 /* FIXME: should be a matrix-type input source selection */
7467 static struct hda_input_mux alc882_capture_source = {
7471 { "Front Mic", 0x1 },
7477 #define alc883_capture_source alc882_capture_source
7479 static struct hda_input_mux alc889_capture_source = {
7482 { "Front Mic", 0x0 },
7488 static struct hda_input_mux mb5_capture_source = {
7497 static struct hda_input_mux macmini3_capture_source = {
7505 static struct hda_input_mux alc883_3stack_6ch_intel = {
7509 { "Front Mic", 0x0 },
7515 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7523 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7527 { "Internal Mic", 0x1 },
7533 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7537 { "Internal Mic", 0x1 },
7541 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7545 { "Front Mic", 0x1 },
7550 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7558 static struct hda_input_mux alc889A_mb31_capture_source = {
7562 /* Front Mic (0x01) unused */
7564 /* Line 2 (0x03) unused */
7565 /* CD (0x04) unused? */
7569 static struct hda_input_mux alc889A_imac91_capture_source = {
7573 { "Line", 0x2 }, /* Not sure! */
7580 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7587 static struct hda_verb alc882_3ST_ch2_init[] = {
7588 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7589 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7590 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7591 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7598 static struct hda_verb alc882_3ST_ch4_init[] = {
7599 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7600 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7601 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7602 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7603 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7610 static struct hda_verb alc882_3ST_ch6_init[] = {
7611 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7612 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7613 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7614 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7615 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7616 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7620 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7621 { 2, alc882_3ST_ch2_init },
7622 { 4, alc882_3ST_ch4_init },
7623 { 6, alc882_3ST_ch6_init },
7626 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7631 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7632 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7633 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7634 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7635 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7636 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7643 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7644 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7645 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7646 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7647 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7648 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7649 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7656 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7657 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7658 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7659 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7660 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7661 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7662 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7663 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7667 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7668 { 2, alc883_3ST_ch2_clevo_init },
7669 { 4, alc883_3ST_ch4_clevo_init },
7670 { 6, alc883_3ST_ch6_clevo_init },
7677 static struct hda_verb alc882_sixstack_ch6_init[] = {
7678 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7679 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7680 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7681 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7688 static struct hda_verb alc882_sixstack_ch8_init[] = {
7689 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7690 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7691 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7692 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7696 static struct hda_channel_mode alc882_sixstack_modes[2] = {
7697 { 6, alc882_sixstack_ch6_init },
7698 { 8, alc882_sixstack_ch8_init },
7702 /* Macbook Air 2,1 */
7704 static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7709 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7715 static struct hda_verb alc885_mbp_ch2_init[] = {
7716 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7717 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7718 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7725 static struct hda_verb alc885_mbp_ch4_init[] = {
7726 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7727 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7728 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7729 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7730 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7734 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7735 { 2, alc885_mbp_ch2_init },
7736 { 4, alc885_mbp_ch4_init },
7741 * Speakers/Woofer/HP = Front
7744 static struct hda_verb alc885_mb5_ch2_init[] = {
7745 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7746 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7752 * Speakers/HP = Front
7756 static struct hda_verb alc885_mb5_ch6_init[] = {
7757 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7758 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7759 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7763 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7764 { 2, alc885_mb5_ch2_init },
7765 { 6, alc885_mb5_ch6_init },
7768 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7773 static struct hda_verb alc883_4ST_ch2_init[] = {
7774 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7775 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7776 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7777 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7778 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7779 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7786 static struct hda_verb alc883_4ST_ch4_init[] = {
7787 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7788 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7789 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7790 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7791 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7792 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7793 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7800 static struct hda_verb alc883_4ST_ch6_init[] = {
7801 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7802 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7803 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7804 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7805 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7806 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7807 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7808 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7815 static struct hda_verb alc883_4ST_ch8_init[] = {
7816 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7817 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7818 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7819 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7820 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7821 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7822 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7823 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7824 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7828 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7829 { 2, alc883_4ST_ch2_init },
7830 { 4, alc883_4ST_ch4_init },
7831 { 6, alc883_4ST_ch6_init },
7832 { 8, alc883_4ST_ch8_init },
7839 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7840 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7841 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7842 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7843 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7850 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7851 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7852 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7853 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7854 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7855 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7862 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7863 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7866 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7867 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7868 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7872 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7873 { 2, alc883_3ST_ch2_intel_init },
7874 { 4, alc883_3ST_ch4_intel_init },
7875 { 6, alc883_3ST_ch6_intel_init },
7881 static struct hda_verb alc889_ch2_intel_init[] = {
7882 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7883 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7884 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7885 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7886 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7887 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7894 static struct hda_verb alc889_ch6_intel_init[] = {
7895 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7896 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7897 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7898 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7899 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7900 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7907 static struct hda_verb alc889_ch8_intel_init[] = {
7908 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7909 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7910 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7911 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7912 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7913 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7914 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7918 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7919 { 2, alc889_ch2_intel_init },
7920 { 6, alc889_ch6_intel_init },
7921 { 8, alc889_ch8_intel_init },
7927 static struct hda_verb alc883_sixstack_ch6_init[] = {
7928 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7929 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7931 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7938 static struct hda_verb alc883_sixstack_ch8_init[] = {
7939 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7942 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7946 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7947 { 6, alc883_sixstack_ch6_init },
7948 { 8, alc883_sixstack_ch8_init },
7952 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7953 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7955 static struct snd_kcontrol_new alc882_base_mixer[] = {
7956 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7957 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7958 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7959 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7960 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7961 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7962 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7963 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7964 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7965 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7966 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7975 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7980 /* Macbook Air 2,1 same control for HP and internal Speaker */
7982 static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7983 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7984 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7989 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7990 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7991 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7992 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7993 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7994 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7996 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7998 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7999 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8000 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8004 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
8005 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8006 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8007 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8008 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8009 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8010 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8011 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8012 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8013 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8014 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8016 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8017 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8018 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8022 static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8023 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8024 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8025 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8026 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8027 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8028 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8029 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8030 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8032 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8033 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8037 static struct snd_kcontrol_new alc885_imac91_mixer[] = {
8038 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8039 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8044 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8045 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8046 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8047 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8048 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8049 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8050 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8057 static struct snd_kcontrol_new alc882_targa_mixer[] = {
8058 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8059 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8060 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8061 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8062 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8063 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8064 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8067 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8068 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8069 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8070 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8074 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8075 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8077 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8078 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8079 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8080 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8081 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8082 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8083 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8084 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8085 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8086 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8087 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8088 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8089 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8090 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8094 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8095 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8096 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8097 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8098 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8099 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8100 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8101 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8103 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8108 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8111 .name = "Channel Mode",
8112 .info = alc_ch_mode_info,
8113 .get = alc_ch_mode_get,
8114 .put = alc_ch_mode_put,
8119 static struct hda_verb alc882_base_init_verbs[] = {
8120 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8121 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8122 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8124 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8125 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8127 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8128 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8130 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8131 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8133 /* Front Pin: output 0 (0x0c) */
8134 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8135 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8136 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8137 /* Rear Pin: output 1 (0x0d) */
8138 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8139 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8140 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8141 /* CLFE Pin: output 2 (0x0e) */
8142 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8143 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8144 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8145 /* Side Pin: output 3 (0x0f) */
8146 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8147 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8148 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8149 /* Mic (rear) pin: input vref at 80% */
8150 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8151 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8152 /* Front Mic pin: input vref at 80% */
8153 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8154 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8155 /* Line In pin: input */
8156 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8157 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8158 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8159 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8160 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8161 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8162 /* CD pin widget for input */
8163 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8165 /* FIXME: use matrix-type input source selection */
8166 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8168 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8170 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8171 /* ADC2: mute amp left and right */
8172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8173 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8174 /* ADC3: mute amp left and right */
8175 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8176 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8181 static struct hda_verb alc882_adc1_init_verbs[] = {
8182 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8183 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8184 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8185 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8186 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8187 /* ADC1: mute amp left and right */
8188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8189 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8193 static struct hda_verb alc882_eapd_verbs[] = {
8194 /* change to EAPD mode */
8195 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8196 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8200 static struct hda_verb alc889_eapd_verbs[] = {
8201 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8202 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8206 static struct hda_verb alc_hp15_unsol_verbs[] = {
8207 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8212 static struct hda_verb alc885_init_verbs[] = {
8213 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8215 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8217 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8218 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8223 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8224 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8226 /* Front HP Pin: output 0 (0x0c) */
8227 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8228 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8229 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8230 /* Front Pin: output 0 (0x0c) */
8231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8233 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8234 /* Rear Pin: output 1 (0x0d) */
8235 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8237 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8238 /* CLFE Pin: output 2 (0x0e) */
8239 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8240 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8241 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8242 /* Side Pin: output 3 (0x0f) */
8243 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8244 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8245 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8246 /* Mic (rear) pin: input vref at 80% */
8247 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8248 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8249 /* Front Mic pin: input vref at 80% */
8250 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8251 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8252 /* Line In pin: input */
8253 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8256 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8258 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8260 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8262 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8263 /* ADC2: mute amp left and right */
8264 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8265 /* ADC3: mute amp left and right */
8266 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8271 static struct hda_verb alc885_init_input_verbs[] = {
8272 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8273 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8274 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8279 /* Unmute Selector 24h and set the default input to front mic */
8280 static struct hda_verb alc889_init_input_verbs[] = {
8281 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8287 #define alc883_init_verbs alc882_base_init_verbs
8290 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8293 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8294 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8295 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8296 /* FIXME: this looks suspicious...
8297 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8298 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8303 static struct hda_verb alc882_macpro_init_verbs[] = {
8304 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8305 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8308 /* Front Pin: output 0 (0x0c) */
8309 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8310 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8311 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8312 /* Front Mic pin: input vref at 80% */
8313 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8314 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8315 /* Speaker: output */
8316 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8317 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8318 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8319 /* Headphone output (output 0 - 0x0c) */
8320 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8321 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8322 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8324 /* FIXME: use matrix-type input source selection */
8325 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8326 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8329 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8330 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8334 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8335 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8340 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8341 /* ADC1: mute amp left and right */
8342 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8343 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8344 /* ADC2: mute amp left and right */
8345 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8346 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8347 /* ADC3: mute amp left and right */
8348 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8349 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8355 static struct hda_verb alc885_mb5_init_verbs[] = {
8357 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8358 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8359 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8360 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8365 /* Surround mixer */
8366 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8367 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8372 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8375 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8376 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8377 /* Front Pin (0x0c) */
8378 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8379 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8380 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8381 /* LFE Pin (0x0e) */
8382 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8383 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8384 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8387 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8388 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8389 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8390 /* Front Mic pin: input vref at 80% */
8391 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8392 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8394 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8397 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8398 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8399 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8404 static struct hda_verb alc885_macmini3_init_verbs[] = {
8406 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8407 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8408 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8414 /* Surround mixer */
8415 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8421 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8423 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8426 /* Front Pin (0x0c) */
8427 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8428 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8429 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8430 /* LFE Pin (0x0e) */
8431 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8432 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8433 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8435 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8436 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8437 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8438 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8440 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8441 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8451 static struct hda_verb alc885_mba21_init_verbs[] = {
8452 /*Internal and HP Speaker Mixer*/
8453 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8455 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8456 /*Internal Speaker Pin (0x0c)*/
8457 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8458 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8459 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8460 /* HP Pin: output 0 (0x0e) */
8461 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8462 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8463 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8464 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8465 /* Line in (is hp when jack connected)*/
8466 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8467 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8473 /* Macbook Pro rev3 */
8474 static struct hda_verb alc885_mbp3_init_verbs[] = {
8475 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8478 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8480 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8485 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8486 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8487 /* Front Pin: output 0 (0x0c) */
8488 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8491 /* HP Pin: output 0 (0x0e) */
8492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8495 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8496 /* Mic (rear) pin: input vref at 80% */
8497 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8498 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8499 /* Front Mic pin: input vref at 80% */
8500 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8501 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8502 /* Line In pin: use output 1 when in LineOut mode */
8503 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8504 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8505 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8507 /* FIXME: use matrix-type input source selection */
8508 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8509 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8510 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8511 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8512 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8513 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8516 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8518 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8520 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8522 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8524 /* ADC1: mute amp left and right */
8525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8526 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8527 /* ADC2: mute amp left and right */
8528 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8529 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8530 /* ADC3: mute amp left and right */
8531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8532 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8538 static struct hda_verb alc885_imac91_init_verbs[] = {
8539 /* Internal Speaker Pin (0x0c) */
8540 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8542 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8545 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8548 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8549 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8550 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8552 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8553 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8554 /* Front Mic pin: input vref at 80% */
8555 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8560 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8561 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8565 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8569 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8570 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8571 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8575 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8580 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8581 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8582 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8583 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8584 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8585 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8586 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8587 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8588 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 /* iMac 24 mixer. */
8593 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8594 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8595 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8599 /* iMac 24 init verbs. */
8600 static struct hda_verb alc885_imac24_init_verbs[] = {
8601 /* Internal speakers: output 0 (0x0c) */
8602 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8603 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8604 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8605 /* Internal speakers: output 0 (0x0c) */
8606 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8607 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8609 /* Headphone: output 0 (0x0c) */
8610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8611 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8612 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8613 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8614 /* Front Mic: input vref at 80% */
8615 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8616 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8620 /* Toggle speaker-output according to the hp-jack state */
8621 static void alc885_imac24_setup(struct hda_codec *codec)
8623 struct alc_spec *spec = codec->spec;
8625 spec->autocfg.hp_pins[0] = 0x14;
8626 spec->autocfg.speaker_pins[0] = 0x18;
8627 spec->autocfg.speaker_pins[1] = 0x1a;
8630 #define alc885_mb5_setup alc885_imac24_setup
8631 #define alc885_macmini3_setup alc885_imac24_setup
8633 /* Macbook Air 2,1 */
8634 static void alc885_mba21_setup(struct hda_codec *codec)
8636 struct alc_spec *spec = codec->spec;
8638 spec->autocfg.hp_pins[0] = 0x14;
8639 spec->autocfg.speaker_pins[0] = 0x18;
8644 static void alc885_mbp3_setup(struct hda_codec *codec)
8646 struct alc_spec *spec = codec->spec;
8648 spec->autocfg.hp_pins[0] = 0x15;
8649 spec->autocfg.speaker_pins[0] = 0x14;
8652 static void alc885_imac91_setup(struct hda_codec *codec)
8654 struct alc_spec *spec = codec->spec;
8656 spec->autocfg.hp_pins[0] = 0x14;
8657 spec->autocfg.speaker_pins[0] = 0x18;
8658 spec->autocfg.speaker_pins[1] = 0x1a;
8661 static struct hda_verb alc882_targa_verbs[] = {
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8665 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8666 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8668 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8669 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8670 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8672 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8676 /* toggle speaker-output according to the hp-jack state */
8677 static void alc882_targa_automute(struct hda_codec *codec)
8679 struct alc_spec *spec = codec->spec;
8680 alc_automute_amp(codec);
8681 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8682 spec->jack_present ? 1 : 3);
8685 static void alc882_targa_setup(struct hda_codec *codec)
8687 struct alc_spec *spec = codec->spec;
8689 spec->autocfg.hp_pins[0] = 0x14;
8690 spec->autocfg.speaker_pins[0] = 0x1b;
8693 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8695 if ((res >> 26) == ALC880_HP_EVENT)
8696 alc882_targa_automute(codec);
8699 static struct hda_verb alc882_asus_a7j_verbs[] = {
8700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8703 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8704 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8705 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8707 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8708 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8709 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8711 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8712 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8713 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8717 static struct hda_verb alc882_asus_a7m_verbs[] = {
8718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8721 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8723 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8726 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8727 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8729 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8730 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8731 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8735 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8737 unsigned int gpiostate, gpiomask, gpiodir;
8739 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8740 AC_VERB_GET_GPIO_DATA, 0);
8743 gpiostate |= (1 << pin);
8745 gpiostate &= ~(1 << pin);
8747 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8748 AC_VERB_GET_GPIO_MASK, 0);
8749 gpiomask |= (1 << pin);
8751 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8752 AC_VERB_GET_GPIO_DIRECTION, 0);
8753 gpiodir |= (1 << pin);
8756 snd_hda_codec_write(codec, codec->afg, 0,
8757 AC_VERB_SET_GPIO_MASK, gpiomask);
8758 snd_hda_codec_write(codec, codec->afg, 0,
8759 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8763 snd_hda_codec_write(codec, codec->afg, 0,
8764 AC_VERB_SET_GPIO_DATA, gpiostate);
8767 /* set up GPIO at initialization */
8768 static void alc885_macpro_init_hook(struct hda_codec *codec)
8770 alc882_gpio_mute(codec, 0, 0);
8771 alc882_gpio_mute(codec, 1, 0);
8774 /* set up GPIO and update auto-muting at initialization */
8775 static void alc885_imac24_init_hook(struct hda_codec *codec)
8777 alc885_macpro_init_hook(codec);
8778 alc_automute_amp(codec);
8782 * generic initialization of ADC, input mixers and output mixers
8784 static struct hda_verb alc883_auto_init_verbs[] = {
8786 * Unmute ADC0-2 and set the default input to mic-in
8788 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8789 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8790 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8794 * Set up output mixers (0x0c - 0x0f)
8796 /* set vol=0 to output mixers */
8797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8798 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8799 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8801 /* set up input amps for analog loopback */
8802 /* Amp Indices: DAC = 0, mixer = 1 */
8803 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8805 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8808 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8809 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8810 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8811 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8812 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8814 /* FIXME: use matrix-type input source selection */
8815 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8817 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8823 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8824 static struct hda_verb alc889A_mb31_ch2_init[] = {
8825 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8827 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8832 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8833 static struct hda_verb alc889A_mb31_ch4_init[] = {
8834 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8835 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8836 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8837 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8841 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8842 static struct hda_verb alc889A_mb31_ch5_init[] = {
8843 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8844 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8845 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8846 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8850 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8851 static struct hda_verb alc889A_mb31_ch6_init[] = {
8852 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8853 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8859 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8860 { 2, alc889A_mb31_ch2_init },
8861 { 4, alc889A_mb31_ch4_init },
8862 { 5, alc889A_mb31_ch5_init },
8863 { 6, alc889A_mb31_ch6_init },
8866 static struct hda_verb alc883_medion_eapd_verbs[] = {
8867 /* eanable EAPD on medion laptop */
8868 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8869 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8873 #define alc883_base_mixer alc882_base_mixer
8875 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8876 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8877 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8878 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8879 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8880 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8881 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8884 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8885 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8886 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8887 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8888 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8892 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8893 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8894 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8895 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8896 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8898 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8900 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8901 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8902 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8906 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8907 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8908 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8909 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8910 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8912 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8914 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8915 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8916 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8920 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8921 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8922 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8923 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8924 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8925 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8926 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8927 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8929 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8930 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8931 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8932 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8933 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8937 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8938 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8939 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8940 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8941 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8942 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8943 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8944 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8945 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8946 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8947 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8948 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8949 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8950 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8952 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8954 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8955 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8956 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8960 static struct snd_kcontrol_new alc883_3ST_6ch_intel_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_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8964 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8965 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8967 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8968 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8969 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8970 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8973 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8974 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8978 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8980 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8984 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8985 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8986 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8987 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8988 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8989 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8991 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8992 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8993 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8995 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8996 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8997 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8998 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9002 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9003 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9004 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9008 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9009 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9010 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9011 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9012 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9013 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9014 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9015 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9016 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9017 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9018 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9019 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9020 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9021 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9022 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9023 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9024 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9025 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9026 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9027 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9031 static struct snd_kcontrol_new alc883_targa_mixer[] = {
9032 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9033 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9035 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9036 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9037 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9038 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9039 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9040 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9041 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9042 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9043 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9044 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9045 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9047 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9052 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9053 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9055 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9056 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9059 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9060 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9062 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9063 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9064 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9068 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9069 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9070 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9071 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9072 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9073 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9077 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9078 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9079 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9080 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9081 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9084 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9089 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9090 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9091 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9092 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9093 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9094 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9095 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9096 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9097 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9098 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9102 static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9103 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9104 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9105 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9106 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9107 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9108 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9112 static struct hda_verb alc883_medion_wim2160_verbs[] = {
9113 /* Unmute front mixer */
9114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9117 /* Set speaker pin to front mixer */
9118 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9120 /* Init headphone pin */
9121 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9122 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9123 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9124 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9129 /* toggle speaker-output according to the hp-jack state */
9130 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9132 struct alc_spec *spec = codec->spec;
9134 spec->autocfg.hp_pins[0] = 0x1a;
9135 spec->autocfg.speaker_pins[0] = 0x15;
9138 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9139 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9140 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9141 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9142 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9143 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9150 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9151 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9152 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9153 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9154 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9155 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9156 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9158 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9163 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9166 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9167 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9168 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9169 0x0d, 1, 0x0, HDA_OUTPUT),
9170 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9171 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9172 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9173 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9174 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9175 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9176 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9180 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9181 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9182 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9183 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9184 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9188 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9190 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9191 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9192 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9193 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9194 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9196 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9197 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9198 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9199 /* Output switches */
9200 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9201 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9202 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9204 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9205 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9208 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9214 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9215 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9216 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9217 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9219 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9220 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9224 static struct hda_bind_ctls alc883_bind_cap_vol = {
9225 .ops = &snd_hda_bind_vol,
9227 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9228 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9233 static struct hda_bind_ctls alc883_bind_cap_switch = {
9234 .ops = &snd_hda_bind_sw,
9236 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9237 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9242 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9245 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9246 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9247 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9248 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9254 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9255 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9256 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9258 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9259 /* .name = "Capture Source", */
9260 .name = "Input Source",
9262 .info = alc_mux_enum_info,
9263 .get = alc_mux_enum_get,
9264 .put = alc_mux_enum_put,
9269 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9271 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9272 .name = "Channel Mode",
9273 .info = alc_ch_mode_info,
9274 .get = alc_ch_mode_get,
9275 .put = alc_ch_mode_put,
9280 /* toggle speaker-output according to the hp-jack state */
9281 static void alc883_mitac_setup(struct hda_codec *codec)
9283 struct alc_spec *spec = codec->spec;
9285 spec->autocfg.hp_pins[0] = 0x15;
9286 spec->autocfg.speaker_pins[0] = 0x14;
9287 spec->autocfg.speaker_pins[1] = 0x17;
9290 static struct hda_verb alc883_mitac_verbs[] = {
9292 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9293 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9295 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9296 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9298 /* enable unsolicited event */
9299 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9300 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9305 static struct hda_verb alc883_clevo_m540r_verbs[] = {
9307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9308 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9310 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9312 /* enable unsolicited event */
9314 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9315 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9321 static struct hda_verb alc883_clevo_m720_verbs[] = {
9323 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9324 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9326 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9327 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9329 /* enable unsolicited event */
9330 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9331 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9336 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9338 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9344 /* enable unsolicited event */
9345 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9350 static struct hda_verb alc883_targa_verbs[] = {
9351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9357 /* Connect Line-Out side jack (SPDIF) to Side */
9358 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9359 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9360 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9361 /* Connect Mic jack to CLFE */
9362 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9363 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9364 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9365 /* Connect Line-in jack to Surround */
9366 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9367 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9368 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9369 /* Connect HP out jack to Front */
9370 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9371 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9372 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9374 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9379 static struct hda_verb alc883_lenovo_101e_verbs[] = {
9380 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9381 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9382 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9386 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9387 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9388 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9389 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9390 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9394 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9395 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9396 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9397 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9398 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9399 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9403 static struct hda_verb alc883_haier_w66_verbs[] = {
9404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9405 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9409 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9410 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9411 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9416 static struct hda_verb alc888_lenovo_sky_verbs[] = {
9417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9418 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9421 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9422 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9423 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9424 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9428 static struct hda_verb alc888_6st_dell_verbs[] = {
9429 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9433 static struct hda_verb alc883_vaiott_verbs[] = {
9435 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9436 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9438 /* enable unsolicited event */
9439 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9444 static void alc888_3st_hp_setup(struct hda_codec *codec)
9446 struct alc_spec *spec = codec->spec;
9448 spec->autocfg.hp_pins[0] = 0x1b;
9449 spec->autocfg.speaker_pins[0] = 0x14;
9450 spec->autocfg.speaker_pins[1] = 0x16;
9451 spec->autocfg.speaker_pins[2] = 0x18;
9454 static struct hda_verb alc888_3st_hp_verbs[] = {
9455 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9456 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9457 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9458 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9465 static struct hda_verb alc888_3st_hp_2ch_init[] = {
9466 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9467 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9468 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9469 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9476 static struct hda_verb alc888_3st_hp_4ch_init[] = {
9477 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9478 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9479 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9480 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9481 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9488 static struct hda_verb alc888_3st_hp_6ch_init[] = {
9489 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9490 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9491 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9492 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9493 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9494 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9498 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
9499 { 2, alc888_3st_hp_2ch_init },
9500 { 4, alc888_3st_hp_4ch_init },
9501 { 6, alc888_3st_hp_6ch_init },
9504 /* toggle front-jack and RCA according to the hp-jack state */
9505 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9507 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
9509 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9510 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9511 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9512 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9515 /* toggle RCA according to the front-jack state */
9516 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9518 unsigned int present = snd_hda_jack_detect(codec, 0x14);
9520 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9521 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9524 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9527 if ((res >> 26) == ALC880_HP_EVENT)
9528 alc888_lenovo_ms7195_front_automute(codec);
9529 if ((res >> 26) == ALC880_FRONT_EVENT)
9530 alc888_lenovo_ms7195_rca_automute(codec);
9533 /* toggle speaker-output according to the hp-jack state */
9534 static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9536 struct alc_spec *spec = codec->spec;
9538 spec->autocfg.hp_pins[0] = 0x14;
9539 spec->autocfg.speaker_pins[0] = 0x15;
9542 /* toggle speaker-output according to the hp-jack state */
9543 #define alc883_targa_init_hook alc882_targa_init_hook
9544 #define alc883_targa_unsol_event alc882_targa_unsol_event
9546 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9548 struct alc_spec *spec = codec->spec;
9550 spec->autocfg.hp_pins[0] = 0x15;
9551 spec->autocfg.speaker_pins[0] = 0x14;
9554 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9556 alc_automute_amp(codec);
9557 alc88x_simple_mic_automute(codec);
9560 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9563 switch (res >> 26) {
9564 case ALC880_MIC_EVENT:
9565 alc88x_simple_mic_automute(codec);
9568 alc_automute_amp_unsol_event(codec, res);
9573 /* toggle speaker-output according to the hp-jack state */
9574 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9576 struct alc_spec *spec = codec->spec;
9578 spec->autocfg.hp_pins[0] = 0x14;
9579 spec->autocfg.speaker_pins[0] = 0x15;
9582 static void alc883_haier_w66_setup(struct hda_codec *codec)
9584 struct alc_spec *spec = codec->spec;
9586 spec->autocfg.hp_pins[0] = 0x1b;
9587 spec->autocfg.speaker_pins[0] = 0x14;
9590 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9592 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
9594 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9595 HDA_AMP_MUTE, bits);
9598 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9600 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9602 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9603 HDA_AMP_MUTE, bits);
9604 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9605 HDA_AMP_MUTE, bits);
9608 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9611 if ((res >> 26) == ALC880_HP_EVENT)
9612 alc883_lenovo_101e_all_automute(codec);
9613 if ((res >> 26) == ALC880_FRONT_EVENT)
9614 alc883_lenovo_101e_ispeaker_automute(codec);
9617 /* toggle speaker-output according to the hp-jack state */
9618 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9620 struct alc_spec *spec = codec->spec;
9622 spec->autocfg.hp_pins[0] = 0x14;
9623 spec->autocfg.speaker_pins[0] = 0x15;
9624 spec->autocfg.speaker_pins[1] = 0x16;
9627 static struct hda_verb alc883_acer_eapd_verbs[] = {
9628 /* HP Pin: output 0 (0x0c) */
9629 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9630 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9631 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9632 /* Front Pin: output 0 (0x0c) */
9633 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9635 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9636 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9637 /* eanable EAPD on medion laptop */
9638 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9639 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9640 /* enable unsolicited event */
9641 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9645 static void alc888_6st_dell_setup(struct hda_codec *codec)
9647 struct alc_spec *spec = codec->spec;
9649 spec->autocfg.hp_pins[0] = 0x1b;
9650 spec->autocfg.speaker_pins[0] = 0x14;
9651 spec->autocfg.speaker_pins[1] = 0x15;
9652 spec->autocfg.speaker_pins[2] = 0x16;
9653 spec->autocfg.speaker_pins[3] = 0x17;
9656 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9658 struct alc_spec *spec = codec->spec;
9660 spec->autocfg.hp_pins[0] = 0x1b;
9661 spec->autocfg.speaker_pins[0] = 0x14;
9662 spec->autocfg.speaker_pins[1] = 0x15;
9663 spec->autocfg.speaker_pins[2] = 0x16;
9664 spec->autocfg.speaker_pins[3] = 0x17;
9665 spec->autocfg.speaker_pins[4] = 0x1a;
9668 static void alc883_vaiott_setup(struct hda_codec *codec)
9670 struct alc_spec *spec = codec->spec;
9672 spec->autocfg.hp_pins[0] = 0x15;
9673 spec->autocfg.speaker_pins[0] = 0x14;
9674 spec->autocfg.speaker_pins[1] = 0x17;
9677 static struct hda_verb alc888_asus_m90v_verbs[] = {
9678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9679 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9680 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9681 /* enable unsolicited event */
9682 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9683 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9687 static void alc883_mode2_setup(struct hda_codec *codec)
9689 struct alc_spec *spec = codec->spec;
9691 spec->autocfg.hp_pins[0] = 0x1b;
9692 spec->autocfg.speaker_pins[0] = 0x14;
9693 spec->autocfg.speaker_pins[1] = 0x15;
9694 spec->autocfg.speaker_pins[2] = 0x16;
9695 spec->ext_mic.pin = 0x18;
9696 spec->int_mic.pin = 0x19;
9697 spec->ext_mic.mux_idx = 0;
9698 spec->int_mic.mux_idx = 1;
9702 static struct hda_verb alc888_asus_eee1601_verbs[] = {
9703 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9705 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9706 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9707 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9708 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9709 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9710 /* enable unsolicited event */
9711 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9715 static void alc883_eee1601_inithook(struct hda_codec *codec)
9717 struct alc_spec *spec = codec->spec;
9719 spec->autocfg.hp_pins[0] = 0x14;
9720 spec->autocfg.speaker_pins[0] = 0x1b;
9721 alc_automute_pin(codec);
9724 static struct hda_verb alc889A_mb31_verbs[] = {
9725 /* Init rear pin (used as headphone output) */
9726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9727 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9728 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9729 /* Init line pin (used as output in 4ch and 6ch mode) */
9730 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9731 /* Init line 2 pin (used as headphone out by default) */
9732 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9733 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9737 /* Mute speakers according to the headphone jack state */
9738 static void alc889A_mb31_automute(struct hda_codec *codec)
9740 unsigned int present;
9742 /* Mute only in 2ch or 4ch mode */
9743 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9745 present = snd_hda_jack_detect(codec, 0x15);
9746 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9747 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9748 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9749 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9753 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9755 if ((res >> 26) == ALC880_HP_EVENT)
9756 alc889A_mb31_automute(codec);
9760 #ifdef CONFIG_SND_HDA_POWER_SAVE
9761 #define alc882_loopbacks alc880_loopbacks
9764 /* pcm configuration: identical with ALC880 */
9765 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9766 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9767 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9768 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9770 static hda_nid_t alc883_slave_dig_outs[] = {
9771 ALC1200_DIGOUT_NID, 0,
9774 static hda_nid_t alc1200_slave_dig_outs[] = {
9775 ALC883_DIGOUT_NID, 0,
9779 * configuration and preset
9781 static const char *alc882_models[ALC882_MODEL_LAST] = {
9782 [ALC882_3ST_DIG] = "3stack-dig",
9783 [ALC882_6ST_DIG] = "6stack-dig",
9784 [ALC882_ARIMA] = "arima",
9785 [ALC882_W2JC] = "w2jc",
9786 [ALC882_TARGA] = "targa",
9787 [ALC882_ASUS_A7J] = "asus-a7j",
9788 [ALC882_ASUS_A7M] = "asus-a7m",
9789 [ALC885_MACPRO] = "macpro",
9790 [ALC885_MB5] = "mb5",
9791 [ALC885_MACMINI3] = "macmini3",
9792 [ALC885_MBA21] = "mba21",
9793 [ALC885_MBP3] = "mbp3",
9794 [ALC885_IMAC24] = "imac24",
9795 [ALC885_IMAC91] = "imac91",
9796 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9797 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9798 [ALC883_3ST_6ch] = "3stack-6ch",
9799 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9800 [ALC883_TARGA_DIG] = "targa-dig",
9801 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9802 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9803 [ALC883_ACER] = "acer",
9804 [ALC883_ACER_ASPIRE] = "acer-aspire",
9805 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9806 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9807 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9808 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9809 [ALC883_MEDION] = "medion",
9810 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9811 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9812 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9813 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9814 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9815 [ALC888_LENOVO_SKY] = "lenovo-sky",
9816 [ALC883_HAIER_W66] = "haier-w66",
9817 [ALC888_3ST_HP] = "3stack-hp",
9818 [ALC888_6ST_DELL] = "6stack-dell",
9819 [ALC883_MITAC] = "mitac",
9820 [ALC883_CLEVO_M540R] = "clevo-m540r",
9821 [ALC883_CLEVO_M720] = "clevo-m720",
9822 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9823 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9824 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9825 [ALC889A_INTEL] = "intel-alc889a",
9826 [ALC889_INTEL] = "intel-x58",
9827 [ALC1200_ASUS_P5Q] = "asus-p5q",
9828 [ALC889A_MB31] = "mb31",
9829 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9830 [ALC882_AUTO] = "auto",
9833 static struct snd_pci_quirk alc882_cfg_tbl[] = {
9834 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9836 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9837 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9838 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9839 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9840 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9841 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9842 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9843 ALC888_ACER_ASPIRE_4930G),
9844 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9845 ALC888_ACER_ASPIRE_4930G),
9846 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9847 ALC888_ACER_ASPIRE_8930G),
9848 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9849 ALC888_ACER_ASPIRE_8930G),
9850 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9851 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9852 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9853 ALC888_ACER_ASPIRE_6530G),
9854 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9855 ALC888_ACER_ASPIRE_6530G),
9856 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9857 ALC888_ACER_ASPIRE_7730G),
9858 /* default Acer -- disabled as it causes more problems.
9859 * model=auto should work fine now
9861 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9863 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9865 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9866 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9867 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9868 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9869 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9870 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9872 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9873 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9874 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9875 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9876 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9877 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9878 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9879 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9880 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9881 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9882 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9884 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9885 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9886 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9887 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9888 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9889 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9890 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9891 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9892 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9894 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9895 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9896 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9897 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9898 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9899 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9900 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9901 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9902 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9903 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9904 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9905 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9906 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9907 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9908 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9909 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9910 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9911 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9912 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9913 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9914 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9915 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9916 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9917 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9918 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9919 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9920 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9921 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9922 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9923 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9924 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9926 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9927 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9928 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9929 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9930 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9931 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9932 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9933 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9934 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9935 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9936 ALC883_FUJITSU_PI2515),
9937 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9938 ALC888_FUJITSU_XA3530),
9939 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9940 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9941 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9942 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9943 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9944 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9945 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9946 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9948 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9949 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9950 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9951 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9952 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9953 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9954 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9959 /* codec SSID table for Intel Mac */
9960 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9961 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9962 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9963 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9964 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9965 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9966 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9967 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9968 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9969 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9970 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9971 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9972 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9973 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9974 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9975 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9976 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9977 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
9978 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9979 * so apparently no perfect solution yet
9981 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9982 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9983 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9987 static struct alc_config_preset alc882_presets[] = {
9988 [ALC882_3ST_DIG] = {
9989 .mixers = { alc882_base_mixer },
9990 .init_verbs = { alc882_base_init_verbs,
9991 alc882_adc1_init_verbs },
9992 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9993 .dac_nids = alc882_dac_nids,
9994 .dig_out_nid = ALC882_DIGOUT_NID,
9995 .dig_in_nid = ALC882_DIGIN_NID,
9996 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9997 .channel_mode = alc882_ch_modes,
9999 .input_mux = &alc882_capture_source,
10001 [ALC882_6ST_DIG] = {
10002 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10003 .init_verbs = { alc882_base_init_verbs,
10004 alc882_adc1_init_verbs },
10005 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10006 .dac_nids = alc882_dac_nids,
10007 .dig_out_nid = ALC882_DIGOUT_NID,
10008 .dig_in_nid = ALC882_DIGIN_NID,
10009 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10010 .channel_mode = alc882_sixstack_modes,
10011 .input_mux = &alc882_capture_source,
10014 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10015 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10016 alc882_eapd_verbs },
10017 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10018 .dac_nids = alc882_dac_nids,
10019 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10020 .channel_mode = alc882_sixstack_modes,
10021 .input_mux = &alc882_capture_source,
10024 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10025 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10026 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10027 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10028 .dac_nids = alc882_dac_nids,
10029 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10030 .channel_mode = alc880_threestack_modes,
10032 .input_mux = &alc882_capture_source,
10033 .dig_out_nid = ALC882_DIGOUT_NID,
10036 .mixers = { alc885_mba21_mixer },
10037 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10039 .dac_nids = alc882_dac_nids,
10040 .channel_mode = alc885_mba21_ch_modes,
10041 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10042 .input_mux = &alc882_capture_source,
10043 .unsol_event = alc_automute_amp_unsol_event,
10044 .setup = alc885_mba21_setup,
10045 .init_hook = alc_automute_amp,
10048 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10049 .init_verbs = { alc885_mbp3_init_verbs,
10050 alc880_gpio1_init_verbs },
10052 .dac_nids = alc882_dac_nids,
10054 .channel_mode = alc885_mbp_4ch_modes,
10055 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10056 .input_mux = &alc882_capture_source,
10057 .dig_out_nid = ALC882_DIGOUT_NID,
10058 .dig_in_nid = ALC882_DIGIN_NID,
10059 .unsol_event = alc_automute_amp_unsol_event,
10060 .setup = alc885_mbp3_setup,
10061 .init_hook = alc_automute_amp,
10064 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10065 .init_verbs = { alc885_mb5_init_verbs,
10066 alc880_gpio1_init_verbs },
10067 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10068 .dac_nids = alc882_dac_nids,
10069 .channel_mode = alc885_mb5_6ch_modes,
10070 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10071 .input_mux = &mb5_capture_source,
10072 .dig_out_nid = ALC882_DIGOUT_NID,
10073 .dig_in_nid = ALC882_DIGIN_NID,
10074 .unsol_event = alc_automute_amp_unsol_event,
10075 .setup = alc885_mb5_setup,
10076 .init_hook = alc_automute_amp,
10078 [ALC885_MACMINI3] = {
10079 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10080 .init_verbs = { alc885_macmini3_init_verbs,
10081 alc880_gpio1_init_verbs },
10082 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10083 .dac_nids = alc882_dac_nids,
10084 .channel_mode = alc885_macmini3_6ch_modes,
10085 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10086 .input_mux = &macmini3_capture_source,
10087 .dig_out_nid = ALC882_DIGOUT_NID,
10088 .dig_in_nid = ALC882_DIGIN_NID,
10089 .unsol_event = alc_automute_amp_unsol_event,
10090 .setup = alc885_macmini3_setup,
10091 .init_hook = alc_automute_amp,
10093 [ALC885_MACPRO] = {
10094 .mixers = { alc882_macpro_mixer },
10095 .init_verbs = { alc882_macpro_init_verbs },
10096 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10097 .dac_nids = alc882_dac_nids,
10098 .dig_out_nid = ALC882_DIGOUT_NID,
10099 .dig_in_nid = ALC882_DIGIN_NID,
10100 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10101 .channel_mode = alc882_ch_modes,
10102 .input_mux = &alc882_capture_source,
10103 .init_hook = alc885_macpro_init_hook,
10105 [ALC885_IMAC24] = {
10106 .mixers = { alc885_imac24_mixer },
10107 .init_verbs = { alc885_imac24_init_verbs },
10108 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10109 .dac_nids = alc882_dac_nids,
10110 .dig_out_nid = ALC882_DIGOUT_NID,
10111 .dig_in_nid = ALC882_DIGIN_NID,
10112 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10113 .channel_mode = alc882_ch_modes,
10114 .input_mux = &alc882_capture_source,
10115 .unsol_event = alc_automute_amp_unsol_event,
10116 .setup = alc885_imac24_setup,
10117 .init_hook = alc885_imac24_init_hook,
10119 [ALC885_IMAC91] = {
10120 .mixers = {alc885_imac91_mixer},
10121 .init_verbs = { alc885_imac91_init_verbs,
10122 alc880_gpio1_init_verbs },
10123 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10124 .dac_nids = alc882_dac_nids,
10125 .channel_mode = alc885_mba21_ch_modes,
10126 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10127 .input_mux = &alc889A_imac91_capture_source,
10128 .dig_out_nid = ALC882_DIGOUT_NID,
10129 .dig_in_nid = ALC882_DIGIN_NID,
10130 .unsol_event = alc_automute_amp_unsol_event,
10131 .setup = alc885_imac91_setup,
10132 .init_hook = alc_automute_amp,
10135 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10136 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10137 alc880_gpio3_init_verbs, alc882_targa_verbs},
10138 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10139 .dac_nids = alc882_dac_nids,
10140 .dig_out_nid = ALC882_DIGOUT_NID,
10141 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10142 .adc_nids = alc882_adc_nids,
10143 .capsrc_nids = alc882_capsrc_nids,
10144 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10145 .channel_mode = alc882_3ST_6ch_modes,
10147 .input_mux = &alc882_capture_source,
10148 .unsol_event = alc882_targa_unsol_event,
10149 .setup = alc882_targa_setup,
10150 .init_hook = alc882_targa_automute,
10152 [ALC882_ASUS_A7J] = {
10153 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10154 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10155 alc882_asus_a7j_verbs},
10156 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10157 .dac_nids = alc882_dac_nids,
10158 .dig_out_nid = ALC882_DIGOUT_NID,
10159 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10160 .adc_nids = alc882_adc_nids,
10161 .capsrc_nids = alc882_capsrc_nids,
10162 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10163 .channel_mode = alc882_3ST_6ch_modes,
10165 .input_mux = &alc882_capture_source,
10167 [ALC882_ASUS_A7M] = {
10168 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10169 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10170 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10171 alc882_asus_a7m_verbs },
10172 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10173 .dac_nids = alc882_dac_nids,
10174 .dig_out_nid = ALC882_DIGOUT_NID,
10175 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10176 .channel_mode = alc880_threestack_modes,
10178 .input_mux = &alc882_capture_source,
10180 [ALC883_3ST_2ch_DIG] = {
10181 .mixers = { alc883_3ST_2ch_mixer },
10182 .init_verbs = { alc883_init_verbs },
10183 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10184 .dac_nids = alc883_dac_nids,
10185 .dig_out_nid = ALC883_DIGOUT_NID,
10186 .dig_in_nid = ALC883_DIGIN_NID,
10187 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10188 .channel_mode = alc883_3ST_2ch_modes,
10189 .input_mux = &alc883_capture_source,
10191 [ALC883_3ST_6ch_DIG] = {
10192 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10193 .init_verbs = { alc883_init_verbs },
10194 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10195 .dac_nids = alc883_dac_nids,
10196 .dig_out_nid = ALC883_DIGOUT_NID,
10197 .dig_in_nid = ALC883_DIGIN_NID,
10198 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10199 .channel_mode = alc883_3ST_6ch_modes,
10201 .input_mux = &alc883_capture_source,
10203 [ALC883_3ST_6ch] = {
10204 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10205 .init_verbs = { alc883_init_verbs },
10206 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10207 .dac_nids = alc883_dac_nids,
10208 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10209 .channel_mode = alc883_3ST_6ch_modes,
10211 .input_mux = &alc883_capture_source,
10213 [ALC883_3ST_6ch_INTEL] = {
10214 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10215 .init_verbs = { alc883_init_verbs },
10216 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10217 .dac_nids = alc883_dac_nids,
10218 .dig_out_nid = ALC883_DIGOUT_NID,
10219 .dig_in_nid = ALC883_DIGIN_NID,
10220 .slave_dig_outs = alc883_slave_dig_outs,
10221 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10222 .channel_mode = alc883_3ST_6ch_intel_modes,
10224 .input_mux = &alc883_3stack_6ch_intel,
10226 [ALC889A_INTEL] = {
10227 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10228 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10229 alc_hp15_unsol_verbs },
10230 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10231 .dac_nids = alc883_dac_nids,
10232 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10233 .adc_nids = alc889_adc_nids,
10234 .dig_out_nid = ALC883_DIGOUT_NID,
10235 .dig_in_nid = ALC883_DIGIN_NID,
10236 .slave_dig_outs = alc883_slave_dig_outs,
10237 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10238 .channel_mode = alc889_8ch_intel_modes,
10239 .capsrc_nids = alc889_capsrc_nids,
10240 .input_mux = &alc889_capture_source,
10241 .setup = alc889_automute_setup,
10242 .init_hook = alc_automute_amp,
10243 .unsol_event = alc_automute_amp_unsol_event,
10247 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10248 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10249 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10250 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10251 .dac_nids = alc883_dac_nids,
10252 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10253 .adc_nids = alc889_adc_nids,
10254 .dig_out_nid = ALC883_DIGOUT_NID,
10255 .dig_in_nid = ALC883_DIGIN_NID,
10256 .slave_dig_outs = alc883_slave_dig_outs,
10257 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10258 .channel_mode = alc889_8ch_intel_modes,
10259 .capsrc_nids = alc889_capsrc_nids,
10260 .input_mux = &alc889_capture_source,
10261 .setup = alc889_automute_setup,
10262 .init_hook = alc889_intel_init_hook,
10263 .unsol_event = alc_automute_amp_unsol_event,
10266 [ALC883_6ST_DIG] = {
10267 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10268 .init_verbs = { alc883_init_verbs },
10269 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10270 .dac_nids = alc883_dac_nids,
10271 .dig_out_nid = ALC883_DIGOUT_NID,
10272 .dig_in_nid = ALC883_DIGIN_NID,
10273 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10274 .channel_mode = alc883_sixstack_modes,
10275 .input_mux = &alc883_capture_source,
10277 [ALC883_TARGA_DIG] = {
10278 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10279 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10280 alc883_targa_verbs},
10281 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10282 .dac_nids = alc883_dac_nids,
10283 .dig_out_nid = ALC883_DIGOUT_NID,
10284 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10285 .channel_mode = alc883_3ST_6ch_modes,
10287 .input_mux = &alc883_capture_source,
10288 .unsol_event = alc883_targa_unsol_event,
10289 .setup = alc882_targa_setup,
10290 .init_hook = alc882_targa_automute,
10292 [ALC883_TARGA_2ch_DIG] = {
10293 .mixers = { alc883_targa_2ch_mixer},
10294 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10295 alc883_targa_verbs},
10296 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10297 .dac_nids = alc883_dac_nids,
10298 .adc_nids = alc883_adc_nids_alt,
10299 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10300 .capsrc_nids = alc883_capsrc_nids,
10301 .dig_out_nid = ALC883_DIGOUT_NID,
10302 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10303 .channel_mode = alc883_3ST_2ch_modes,
10304 .input_mux = &alc883_capture_source,
10305 .unsol_event = alc883_targa_unsol_event,
10306 .setup = alc882_targa_setup,
10307 .init_hook = alc882_targa_automute,
10309 [ALC883_TARGA_8ch_DIG] = {
10310 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10311 alc883_chmode_mixer },
10312 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10313 alc883_targa_verbs },
10314 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10315 .dac_nids = alc883_dac_nids,
10316 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10317 .adc_nids = alc883_adc_nids_rev,
10318 .capsrc_nids = alc883_capsrc_nids_rev,
10319 .dig_out_nid = ALC883_DIGOUT_NID,
10320 .dig_in_nid = ALC883_DIGIN_NID,
10321 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10322 .channel_mode = alc883_4ST_8ch_modes,
10324 .input_mux = &alc883_capture_source,
10325 .unsol_event = alc883_targa_unsol_event,
10326 .setup = alc882_targa_setup,
10327 .init_hook = alc882_targa_automute,
10330 .mixers = { alc883_base_mixer },
10331 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10332 * and the headphone jack. Turn this on and rely on the
10333 * standard mute methods whenever the user wants to turn
10334 * these outputs off.
10336 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10337 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10338 .dac_nids = alc883_dac_nids,
10339 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10340 .channel_mode = alc883_3ST_2ch_modes,
10341 .input_mux = &alc883_capture_source,
10343 [ALC883_ACER_ASPIRE] = {
10344 .mixers = { alc883_acer_aspire_mixer },
10345 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10346 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10347 .dac_nids = alc883_dac_nids,
10348 .dig_out_nid = ALC883_DIGOUT_NID,
10349 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10350 .channel_mode = alc883_3ST_2ch_modes,
10351 .input_mux = &alc883_capture_source,
10352 .unsol_event = alc_automute_amp_unsol_event,
10353 .setup = alc883_acer_aspire_setup,
10354 .init_hook = alc_automute_amp,
10356 [ALC888_ACER_ASPIRE_4930G] = {
10357 .mixers = { alc888_base_mixer,
10358 alc883_chmode_mixer },
10359 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10360 alc888_acer_aspire_4930g_verbs },
10361 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10362 .dac_nids = alc883_dac_nids,
10363 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10364 .adc_nids = alc883_adc_nids_rev,
10365 .capsrc_nids = alc883_capsrc_nids_rev,
10366 .dig_out_nid = ALC883_DIGOUT_NID,
10367 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10368 .channel_mode = alc883_3ST_6ch_modes,
10370 .const_channel_count = 6,
10372 ARRAY_SIZE(alc888_2_capture_sources),
10373 .input_mux = alc888_2_capture_sources,
10374 .unsol_event = alc_automute_amp_unsol_event,
10375 .setup = alc888_acer_aspire_4930g_setup,
10376 .init_hook = alc_automute_amp,
10378 [ALC888_ACER_ASPIRE_6530G] = {
10379 .mixers = { alc888_acer_aspire_6530_mixer },
10380 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10381 alc888_acer_aspire_6530g_verbs },
10382 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10383 .dac_nids = alc883_dac_nids,
10384 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10385 .adc_nids = alc883_adc_nids_rev,
10386 .capsrc_nids = alc883_capsrc_nids_rev,
10387 .dig_out_nid = ALC883_DIGOUT_NID,
10388 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10389 .channel_mode = alc883_3ST_2ch_modes,
10391 ARRAY_SIZE(alc888_2_capture_sources),
10392 .input_mux = alc888_acer_aspire_6530_sources,
10393 .unsol_event = alc_automute_amp_unsol_event,
10394 .setup = alc888_acer_aspire_6530g_setup,
10395 .init_hook = alc_automute_amp,
10397 [ALC888_ACER_ASPIRE_8930G] = {
10398 .mixers = { alc889_acer_aspire_8930g_mixer,
10399 alc883_chmode_mixer },
10400 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10401 alc889_acer_aspire_8930g_verbs,
10402 alc889_eapd_verbs},
10403 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10404 .dac_nids = alc883_dac_nids,
10405 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10406 .adc_nids = alc889_adc_nids,
10407 .capsrc_nids = alc889_capsrc_nids,
10408 .dig_out_nid = ALC883_DIGOUT_NID,
10409 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10410 .channel_mode = alc883_3ST_6ch_modes,
10412 .const_channel_count = 6,
10414 ARRAY_SIZE(alc889_capture_sources),
10415 .input_mux = alc889_capture_sources,
10416 .unsol_event = alc_automute_amp_unsol_event,
10417 .setup = alc889_acer_aspire_8930g_setup,
10418 .init_hook = alc_automute_amp,
10419 #ifdef CONFIG_SND_HDA_POWER_SAVE
10420 .power_hook = alc_power_eapd,
10423 [ALC888_ACER_ASPIRE_7730G] = {
10424 .mixers = { alc883_3ST_6ch_mixer,
10425 alc883_chmode_mixer },
10426 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10427 alc888_acer_aspire_7730G_verbs },
10428 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10429 .dac_nids = alc883_dac_nids,
10430 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10431 .adc_nids = alc883_adc_nids_rev,
10432 .capsrc_nids = alc883_capsrc_nids_rev,
10433 .dig_out_nid = ALC883_DIGOUT_NID,
10434 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10435 .channel_mode = alc883_3ST_6ch_modes,
10437 .const_channel_count = 6,
10438 .input_mux = &alc883_capture_source,
10439 .unsol_event = alc_automute_amp_unsol_event,
10440 .setup = alc888_acer_aspire_7730g_setup,
10441 .init_hook = alc_automute_amp,
10443 [ALC883_MEDION] = {
10444 .mixers = { alc883_fivestack_mixer,
10445 alc883_chmode_mixer },
10446 .init_verbs = { alc883_init_verbs,
10447 alc883_medion_eapd_verbs },
10448 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10449 .dac_nids = alc883_dac_nids,
10450 .adc_nids = alc883_adc_nids_alt,
10451 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10452 .capsrc_nids = alc883_capsrc_nids,
10453 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10454 .channel_mode = alc883_sixstack_modes,
10455 .input_mux = &alc883_capture_source,
10457 [ALC883_MEDION_WIM2160] = {
10458 .mixers = { alc883_medion_wim2160_mixer },
10459 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10460 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10461 .dac_nids = alc883_dac_nids,
10462 .dig_out_nid = ALC883_DIGOUT_NID,
10463 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10464 .adc_nids = alc883_adc_nids,
10465 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10466 .channel_mode = alc883_3ST_2ch_modes,
10467 .input_mux = &alc883_capture_source,
10468 .unsol_event = alc_automute_amp_unsol_event,
10469 .setup = alc883_medion_wim2160_setup,
10470 .init_hook = alc_automute_amp,
10472 [ALC883_LAPTOP_EAPD] = {
10473 .mixers = { alc883_base_mixer },
10474 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10475 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10476 .dac_nids = alc883_dac_nids,
10477 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10478 .channel_mode = alc883_3ST_2ch_modes,
10479 .input_mux = &alc883_capture_source,
10481 [ALC883_CLEVO_M540R] = {
10482 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10483 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10485 .dac_nids = alc883_dac_nids,
10486 .dig_out_nid = ALC883_DIGOUT_NID,
10487 .dig_in_nid = ALC883_DIGIN_NID,
10488 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10489 .channel_mode = alc883_3ST_6ch_clevo_modes,
10491 .input_mux = &alc883_capture_source,
10492 /* This machine has the hardware HP auto-muting, thus
10493 * we need no software mute via unsol event
10496 [ALC883_CLEVO_M720] = {
10497 .mixers = { alc883_clevo_m720_mixer },
10498 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10499 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10500 .dac_nids = alc883_dac_nids,
10501 .dig_out_nid = ALC883_DIGOUT_NID,
10502 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10503 .channel_mode = alc883_3ST_2ch_modes,
10504 .input_mux = &alc883_capture_source,
10505 .unsol_event = alc883_clevo_m720_unsol_event,
10506 .setup = alc883_clevo_m720_setup,
10507 .init_hook = alc883_clevo_m720_init_hook,
10509 [ALC883_LENOVO_101E_2ch] = {
10510 .mixers = { alc883_lenovo_101e_2ch_mixer},
10511 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10512 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10513 .dac_nids = alc883_dac_nids,
10514 .adc_nids = alc883_adc_nids_alt,
10515 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10516 .capsrc_nids = alc883_capsrc_nids,
10517 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10518 .channel_mode = alc883_3ST_2ch_modes,
10519 .input_mux = &alc883_lenovo_101e_capture_source,
10520 .unsol_event = alc883_lenovo_101e_unsol_event,
10521 .init_hook = alc883_lenovo_101e_all_automute,
10523 [ALC883_LENOVO_NB0763] = {
10524 .mixers = { alc883_lenovo_nb0763_mixer },
10525 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10526 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10527 .dac_nids = alc883_dac_nids,
10528 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10529 .channel_mode = alc883_3ST_2ch_modes,
10531 .input_mux = &alc883_lenovo_nb0763_capture_source,
10532 .unsol_event = alc_automute_amp_unsol_event,
10533 .setup = alc883_lenovo_nb0763_setup,
10534 .init_hook = alc_automute_amp,
10536 [ALC888_LENOVO_MS7195_DIG] = {
10537 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10538 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10539 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10540 .dac_nids = alc883_dac_nids,
10541 .dig_out_nid = ALC883_DIGOUT_NID,
10542 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10543 .channel_mode = alc883_3ST_6ch_modes,
10545 .input_mux = &alc883_capture_source,
10546 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10547 .init_hook = alc888_lenovo_ms7195_front_automute,
10549 [ALC883_HAIER_W66] = {
10550 .mixers = { alc883_targa_2ch_mixer},
10551 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10552 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10553 .dac_nids = alc883_dac_nids,
10554 .dig_out_nid = ALC883_DIGOUT_NID,
10555 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10556 .channel_mode = alc883_3ST_2ch_modes,
10557 .input_mux = &alc883_capture_source,
10558 .unsol_event = alc_automute_amp_unsol_event,
10559 .setup = alc883_haier_w66_setup,
10560 .init_hook = alc_automute_amp,
10562 [ALC888_3ST_HP] = {
10563 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10564 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10565 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10566 .dac_nids = alc883_dac_nids,
10567 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10568 .channel_mode = alc888_3st_hp_modes,
10570 .input_mux = &alc883_capture_source,
10571 .unsol_event = alc_automute_amp_unsol_event,
10572 .setup = alc888_3st_hp_setup,
10573 .init_hook = alc_automute_amp,
10575 [ALC888_6ST_DELL] = {
10576 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10577 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10578 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10579 .dac_nids = alc883_dac_nids,
10580 .dig_out_nid = ALC883_DIGOUT_NID,
10581 .dig_in_nid = ALC883_DIGIN_NID,
10582 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10583 .channel_mode = alc883_sixstack_modes,
10584 .input_mux = &alc883_capture_source,
10585 .unsol_event = alc_automute_amp_unsol_event,
10586 .setup = alc888_6st_dell_setup,
10587 .init_hook = alc_automute_amp,
10590 .mixers = { alc883_mitac_mixer },
10591 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10592 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10593 .dac_nids = alc883_dac_nids,
10594 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10595 .channel_mode = alc883_3ST_2ch_modes,
10596 .input_mux = &alc883_capture_source,
10597 .unsol_event = alc_automute_amp_unsol_event,
10598 .setup = alc883_mitac_setup,
10599 .init_hook = alc_automute_amp,
10601 [ALC883_FUJITSU_PI2515] = {
10602 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10603 .init_verbs = { alc883_init_verbs,
10604 alc883_2ch_fujitsu_pi2515_verbs},
10605 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10606 .dac_nids = alc883_dac_nids,
10607 .dig_out_nid = ALC883_DIGOUT_NID,
10608 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10609 .channel_mode = alc883_3ST_2ch_modes,
10610 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10611 .unsol_event = alc_automute_amp_unsol_event,
10612 .setup = alc883_2ch_fujitsu_pi2515_setup,
10613 .init_hook = alc_automute_amp,
10615 [ALC888_FUJITSU_XA3530] = {
10616 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10617 .init_verbs = { alc883_init_verbs,
10618 alc888_fujitsu_xa3530_verbs },
10619 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10620 .dac_nids = alc883_dac_nids,
10621 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10622 .adc_nids = alc883_adc_nids_rev,
10623 .capsrc_nids = alc883_capsrc_nids_rev,
10624 .dig_out_nid = ALC883_DIGOUT_NID,
10625 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10626 .channel_mode = alc888_4ST_8ch_intel_modes,
10628 ARRAY_SIZE(alc888_2_capture_sources),
10629 .input_mux = alc888_2_capture_sources,
10630 .unsol_event = alc_automute_amp_unsol_event,
10631 .setup = alc888_fujitsu_xa3530_setup,
10632 .init_hook = alc_automute_amp,
10634 [ALC888_LENOVO_SKY] = {
10635 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10636 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10637 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10638 .dac_nids = alc883_dac_nids,
10639 .dig_out_nid = ALC883_DIGOUT_NID,
10640 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10641 .channel_mode = alc883_sixstack_modes,
10643 .input_mux = &alc883_lenovo_sky_capture_source,
10644 .unsol_event = alc_automute_amp_unsol_event,
10645 .setup = alc888_lenovo_sky_setup,
10646 .init_hook = alc_automute_amp,
10648 [ALC888_ASUS_M90V] = {
10649 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10650 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10651 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10652 .dac_nids = alc883_dac_nids,
10653 .dig_out_nid = ALC883_DIGOUT_NID,
10654 .dig_in_nid = ALC883_DIGIN_NID,
10655 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10656 .channel_mode = alc883_3ST_6ch_modes,
10658 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10659 .unsol_event = alc_sku_unsol_event,
10660 .setup = alc883_mode2_setup,
10661 .init_hook = alc_inithook,
10663 [ALC888_ASUS_EEE1601] = {
10664 .mixers = { alc883_asus_eee1601_mixer },
10665 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10666 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10667 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10668 .dac_nids = alc883_dac_nids,
10669 .dig_out_nid = ALC883_DIGOUT_NID,
10670 .dig_in_nid = ALC883_DIGIN_NID,
10671 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10672 .channel_mode = alc883_3ST_2ch_modes,
10674 .input_mux = &alc883_asus_eee1601_capture_source,
10675 .unsol_event = alc_sku_unsol_event,
10676 .init_hook = alc883_eee1601_inithook,
10678 [ALC1200_ASUS_P5Q] = {
10679 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10680 .init_verbs = { alc883_init_verbs },
10681 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10682 .dac_nids = alc883_dac_nids,
10683 .dig_out_nid = ALC1200_DIGOUT_NID,
10684 .dig_in_nid = ALC883_DIGIN_NID,
10685 .slave_dig_outs = alc1200_slave_dig_outs,
10686 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10687 .channel_mode = alc883_sixstack_modes,
10688 .input_mux = &alc883_capture_source,
10691 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10692 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10693 alc880_gpio1_init_verbs },
10694 .adc_nids = alc883_adc_nids,
10695 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10696 .capsrc_nids = alc883_capsrc_nids,
10697 .dac_nids = alc883_dac_nids,
10698 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10699 .channel_mode = alc889A_mb31_6ch_modes,
10700 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10701 .input_mux = &alc889A_mb31_capture_source,
10702 .dig_out_nid = ALC883_DIGOUT_NID,
10703 .unsol_event = alc889A_mb31_unsol_event,
10704 .init_hook = alc889A_mb31_automute,
10706 [ALC883_SONY_VAIO_TT] = {
10707 .mixers = { alc883_vaiott_mixer },
10708 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10709 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10710 .dac_nids = alc883_dac_nids,
10711 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10712 .channel_mode = alc883_3ST_2ch_modes,
10713 .input_mux = &alc883_capture_source,
10714 .unsol_event = alc_automute_amp_unsol_event,
10715 .setup = alc883_vaiott_setup,
10716 .init_hook = alc_automute_amp,
10725 PINFIX_ABIT_AW9D_MAX,
10727 PINFIX_ACER_ASPIRE_7736,
10730 static const struct alc_fixup alc882_fixups[] = {
10731 [PINFIX_ABIT_AW9D_MAX] = {
10732 .type = ALC_FIXUP_PINS,
10733 .v.pins = (const struct alc_pincfg[]) {
10734 { 0x15, 0x01080104 }, /* side */
10735 { 0x16, 0x01011012 }, /* rear */
10736 { 0x17, 0x01016011 }, /* clfe */
10740 [PINFIX_PB_M5210] = {
10741 .type = ALC_FIXUP_VERBS,
10742 .v.verbs = (const struct hda_verb[]) {
10743 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10747 [PINFIX_ACER_ASPIRE_7736] = {
10748 .type = ALC_FIXUP_SKU,
10749 .v.sku = ALC_FIXUP_SKU_IGNORE,
10753 static struct snd_pci_quirk alc882_fixup_tbl[] = {
10754 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10755 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10756 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10761 * BIOS auto configuration
10763 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10764 const struct auto_pin_cfg *cfg)
10766 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10769 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10770 hda_nid_t nid, int pin_type,
10775 /* set as output */
10776 alc_set_pin_output(codec, nid, pin_type);
10780 else if (dac >= 0x02 && dac <= 0x05)
10784 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10787 static void alc882_auto_init_multi_out(struct hda_codec *codec)
10789 struct alc_spec *spec = codec->spec;
10792 for (i = 0; i <= HDA_SIDE; i++) {
10793 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10794 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10796 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10797 spec->multiout.dac_nids[i]);
10801 static void alc882_auto_init_hp_out(struct hda_codec *codec)
10803 struct alc_spec *spec = codec->spec;
10804 hda_nid_t pin, dac;
10807 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10808 pin = spec->autocfg.hp_pins[i];
10811 dac = spec->multiout.hp_nid;
10813 dac = spec->multiout.dac_nids[0]; /* to front */
10814 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10816 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10817 pin = spec->autocfg.speaker_pins[i];
10820 dac = spec->multiout.extra_out_nid[0];
10822 dac = spec->multiout.dac_nids[0]; /* to front */
10823 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10827 static void alc882_auto_init_analog_input(struct hda_codec *codec)
10829 struct alc_spec *spec = codec->spec;
10830 struct auto_pin_cfg *cfg = &spec->autocfg;
10833 for (i = 0; i < cfg->num_inputs; i++) {
10834 hda_nid_t nid = cfg->inputs[i].pin;
10835 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
10836 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10837 snd_hda_codec_write(codec, nid, 0,
10838 AC_VERB_SET_AMP_GAIN_MUTE,
10843 static void alc882_auto_init_input_src(struct hda_codec *codec)
10845 struct alc_spec *spec = codec->spec;
10848 for (c = 0; c < spec->num_adc_nids; c++) {
10849 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10850 hda_nid_t nid = spec->capsrc_nids[c];
10851 unsigned int mux_idx;
10852 const struct hda_input_mux *imux;
10853 int conns, mute, idx, item;
10855 conns = snd_hda_get_connections(codec, nid, conn_list,
10856 ARRAY_SIZE(conn_list));
10859 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10860 imux = &spec->input_mux[mux_idx];
10861 if (!imux->num_items && mux_idx > 0)
10862 imux = &spec->input_mux[0];
10863 for (idx = 0; idx < conns; idx++) {
10864 /* if the current connection is the selected one,
10865 * unmute it as default - otherwise mute it
10867 mute = AMP_IN_MUTE(idx);
10868 for (item = 0; item < imux->num_items; item++) {
10869 if (imux->items[item].index == idx) {
10870 if (spec->cur_mux[c] == item)
10871 mute = AMP_IN_UNMUTE(idx);
10875 /* check if we have a selector or mixer
10876 * we could check for the widget type instead, but
10877 * just check for Amp-In presence (in case of mixer
10878 * without amp-in there is something wrong, this
10879 * function shouldn't be used or capsrc nid is wrong)
10881 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
10882 snd_hda_codec_write(codec, nid, 0,
10883 AC_VERB_SET_AMP_GAIN_MUTE,
10885 else if (mute != AMP_IN_MUTE(idx))
10886 snd_hda_codec_write(codec, nid, 0,
10887 AC_VERB_SET_CONNECT_SEL,
10893 /* add mic boosts if needed */
10894 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10896 struct alc_spec *spec = codec->spec;
10897 struct auto_pin_cfg *cfg = &spec->autocfg;
10901 const char *prev_label = NULL;
10903 for (i = 0; i < cfg->num_inputs; i++) {
10904 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10906 nid = cfg->inputs[i].pin;
10907 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10909 char boost_label[32];
10911 label = hda_get_autocfg_input_label(codec, cfg, i);
10912 if (prev_label && !strcmp(label, prev_label))
10916 prev_label = label;
10918 snprintf(boost_label, sizeof(boost_label),
10919 "%s Boost Volume", label);
10920 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10921 boost_label, type_idx,
10922 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10930 /* almost identical with ALC880 parser... */
10931 static int alc882_parse_auto_config(struct hda_codec *codec)
10933 struct alc_spec *spec = codec->spec;
10934 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10937 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10941 if (!spec->autocfg.line_outs)
10942 return 0; /* can't find valid BIOS pin config */
10944 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10947 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10950 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10954 err = alc880_auto_create_extra_out(spec,
10955 spec->autocfg.speaker_pins[0],
10959 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10963 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10965 alc_auto_parse_digital(codec);
10967 if (spec->kctls.list)
10968 add_mixer(spec, spec->kctls.list);
10970 add_verb(spec, alc883_auto_init_verbs);
10971 /* if ADC 0x07 is available, initialize it, too */
10972 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10973 add_verb(spec, alc882_adc1_init_verbs);
10975 spec->num_mux_defs = 1;
10976 spec->input_mux = &spec->private_imux[0];
10978 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10980 err = alc_auto_add_mic_boost(codec);
10984 return 1; /* config found */
10987 /* additional initialization for auto-configuration model */
10988 static void alc882_auto_init(struct hda_codec *codec)
10990 struct alc_spec *spec = codec->spec;
10991 alc882_auto_init_multi_out(codec);
10992 alc882_auto_init_hp_out(codec);
10993 alc882_auto_init_analog_input(codec);
10994 alc882_auto_init_input_src(codec);
10995 alc_auto_init_digital(codec);
10996 if (spec->unsol_event)
10997 alc_inithook(codec);
11000 static int patch_alc882(struct hda_codec *codec)
11002 struct alc_spec *spec;
11003 int err, board_config;
11005 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11009 codec->spec = spec;
11011 switch (codec->vendor_id) {
11016 /* ALC883 and variants */
11017 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11021 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11025 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11026 board_config = snd_hda_check_board_codec_sid_config(codec,
11027 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11029 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11030 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11032 board_config = ALC882_AUTO;
11035 if (board_config == ALC882_AUTO) {
11036 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11037 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11040 alc_auto_parse_customize_define(codec);
11042 if (board_config == ALC882_AUTO) {
11043 /* automatic parse from the BIOS config */
11044 err = alc882_parse_auto_config(codec);
11050 "hda_codec: Cannot set up configuration "
11051 "from BIOS. Using base mode...\n");
11052 board_config = ALC882_3ST_DIG;
11056 if (has_cdefine_beep(codec)) {
11057 err = snd_hda_attach_beep_device(codec, 0x1);
11064 if (board_config != ALC882_AUTO)
11065 setup_preset(codec, &alc882_presets[board_config]);
11067 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11068 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11069 /* FIXME: setup DAC5 */
11070 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11071 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11073 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11074 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11076 if (!spec->adc_nids && spec->input_mux) {
11078 spec->num_adc_nids = 0;
11079 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11080 const struct hda_input_mux *imux = spec->input_mux;
11082 hda_nid_t items[16];
11083 hda_nid_t nid = alc882_adc_nids[i];
11084 unsigned int wcap = get_wcaps(codec, nid);
11086 wcap = get_wcaps_type(wcap);
11087 if (wcap != AC_WID_AUD_IN)
11089 spec->private_adc_nids[spec->num_adc_nids] = nid;
11090 err = snd_hda_get_connections(codec, nid, &cap, 1);
11093 err = snd_hda_get_connections(codec, cap, items,
11094 ARRAY_SIZE(items));
11097 for (j = 0; j < imux->num_items; j++)
11098 if (imux->items[j].index >= err)
11100 if (j < imux->num_items)
11102 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11103 spec->num_adc_nids++;
11105 spec->adc_nids = spec->private_adc_nids;
11106 spec->capsrc_nids = spec->private_capsrc_nids;
11109 set_capture_mixer(codec);
11111 if (has_cdefine_beep(codec))
11112 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11114 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11116 spec->vmaster_nid = 0x0c;
11118 codec->patch_ops = alc_patch_ops;
11119 if (board_config == ALC882_AUTO)
11120 spec->init_hook = alc882_auto_init;
11122 alc_init_jacks(codec);
11123 #ifdef CONFIG_SND_HDA_POWER_SAVE
11124 if (!spec->loopback.amplist)
11125 spec->loopback.amplist = alc882_loopbacks;
11136 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11137 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
11139 #define alc262_dac_nids alc260_dac_nids
11140 #define alc262_adc_nids alc882_adc_nids
11141 #define alc262_adc_nids_alt alc882_adc_nids_alt
11142 #define alc262_capsrc_nids alc882_capsrc_nids
11143 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11145 #define alc262_modes alc260_modes
11146 #define alc262_capture_source alc882_capture_source
11148 static hda_nid_t alc262_dmic_adc_nids[1] = {
11153 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11155 static struct snd_kcontrol_new alc262_base_mixer[] = {
11156 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11157 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11158 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11159 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11160 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11161 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11164 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11165 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11166 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11167 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11168 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11170 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11171 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11175 /* update HP, line and mono-out pins according to the master switch */
11176 static void alc262_hp_master_update(struct hda_codec *codec)
11178 struct alc_spec *spec = codec->spec;
11179 int val = spec->master_sw;
11181 /* HP & line-out */
11182 snd_hda_codec_write_cache(codec, 0x1b, 0,
11183 AC_VERB_SET_PIN_WIDGET_CONTROL,
11185 snd_hda_codec_write_cache(codec, 0x15, 0,
11186 AC_VERB_SET_PIN_WIDGET_CONTROL,
11188 /* mono (speaker) depending on the HP jack sense */
11189 val = val && !spec->jack_present;
11190 snd_hda_codec_write_cache(codec, 0x16, 0,
11191 AC_VERB_SET_PIN_WIDGET_CONTROL,
11192 val ? PIN_OUT : 0);
11195 static void alc262_hp_bpc_automute(struct hda_codec *codec)
11197 struct alc_spec *spec = codec->spec;
11199 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11200 alc262_hp_master_update(codec);
11203 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11205 if ((res >> 26) != ALC880_HP_EVENT)
11207 alc262_hp_bpc_automute(codec);
11210 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11212 struct alc_spec *spec = codec->spec;
11214 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11215 alc262_hp_master_update(codec);
11218 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11221 if ((res >> 26) != ALC880_HP_EVENT)
11223 alc262_hp_wildwest_automute(codec);
11226 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11228 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11229 struct snd_ctl_elem_value *ucontrol)
11231 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11232 struct alc_spec *spec = codec->spec;
11233 int val = !!*ucontrol->value.integer.value;
11235 if (val == spec->master_sw)
11237 spec->master_sw = val;
11238 alc262_hp_master_update(codec);
11242 #define ALC262_HP_MASTER_SWITCH \
11244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11245 .name = "Master Playback Switch", \
11246 .info = snd_ctl_boolean_mono_info, \
11247 .get = alc262_hp_master_sw_get, \
11248 .put = alc262_hp_master_sw_put, \
11251 .iface = NID_MAPPING, \
11252 .name = "Master Playback Switch", \
11253 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11257 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11258 ALC262_HP_MASTER_SWITCH,
11259 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11260 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11261 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11262 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11264 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11268 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11269 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11271 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11272 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11273 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11276 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11277 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11281 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11282 ALC262_HP_MASTER_SWITCH,
11283 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11284 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11285 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11287 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11289 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11291 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11292 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11293 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11295 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11301 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11302 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11303 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11304 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11308 /* mute/unmute internal speaker according to the hp jack and mute state */
11309 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11311 struct alc_spec *spec = codec->spec;
11313 spec->autocfg.hp_pins[0] = 0x15;
11314 spec->autocfg.speaker_pins[0] = 0x14;
11317 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11318 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11319 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11320 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11321 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11322 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11323 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11324 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11328 static struct hda_verb alc262_hp_t5735_verbs[] = {
11329 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11332 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11336 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11337 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11338 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11339 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11340 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11341 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11342 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11346 static struct hda_verb alc262_hp_rp5700_verbs[] = {
11347 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11348 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11349 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11350 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11351 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11352 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11355 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11360 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11367 /* bind hp and internal speaker mute (with plug check) as master switch */
11368 static void alc262_hippo_master_update(struct hda_codec *codec)
11370 struct alc_spec *spec = codec->spec;
11371 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11372 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11373 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11377 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11378 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11379 HDA_AMP_MUTE, mute);
11380 /* mute internal speaker per jack sense */
11381 if (spec->jack_present)
11382 mute = HDA_AMP_MUTE;
11384 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11385 HDA_AMP_MUTE, mute);
11386 if (speaker_nid && speaker_nid != line_nid)
11387 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
11388 HDA_AMP_MUTE, mute);
11391 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11393 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11394 struct snd_ctl_elem_value *ucontrol)
11396 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11397 struct alc_spec *spec = codec->spec;
11398 int val = !!*ucontrol->value.integer.value;
11400 if (val == spec->master_sw)
11402 spec->master_sw = val;
11403 alc262_hippo_master_update(codec);
11407 #define ALC262_HIPPO_MASTER_SWITCH \
11409 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11410 .name = "Master Playback Switch", \
11411 .info = snd_ctl_boolean_mono_info, \
11412 .get = alc262_hippo_master_sw_get, \
11413 .put = alc262_hippo_master_sw_put, \
11416 .iface = NID_MAPPING, \
11417 .name = "Master Playback Switch", \
11418 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11419 (SUBDEV_SPEAKER(0) << 16), \
11422 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11423 ALC262_HIPPO_MASTER_SWITCH,
11424 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11425 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11426 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11427 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11428 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11430 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11431 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11434 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11435 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11439 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11440 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11441 ALC262_HIPPO_MASTER_SWITCH,
11442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11444 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11445 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11448 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11451 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11455 /* mute/unmute internal speaker according to the hp jack and mute state */
11456 static void alc262_hippo_automute(struct hda_codec *codec)
11458 struct alc_spec *spec = codec->spec;
11459 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11461 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
11462 alc262_hippo_master_update(codec);
11465 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11467 if ((res >> 26) != ALC880_HP_EVENT)
11469 alc262_hippo_automute(codec);
11472 static void alc262_hippo_setup(struct hda_codec *codec)
11474 struct alc_spec *spec = codec->spec;
11476 spec->autocfg.hp_pins[0] = 0x15;
11477 spec->autocfg.speaker_pins[0] = 0x14;
11480 static void alc262_hippo1_setup(struct hda_codec *codec)
11482 struct alc_spec *spec = codec->spec;
11484 spec->autocfg.hp_pins[0] = 0x1b;
11485 spec->autocfg.speaker_pins[0] = 0x14;
11489 static struct snd_kcontrol_new alc262_sony_mixer[] = {
11490 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11491 ALC262_HIPPO_MASTER_SWITCH,
11492 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11493 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11494 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11495 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11499 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11500 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11501 ALC262_HIPPO_MASTER_SWITCH,
11502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11503 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11504 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11505 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11506 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11510 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11511 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11512 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11513 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11514 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11515 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11516 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11519 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11520 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11521 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11522 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11526 static struct hda_verb alc262_tyan_verbs[] = {
11527 /* Headphone automute */
11528 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11530 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11532 /* P11 AUX_IN, white 4-pin connector */
11533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11534 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11535 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11536 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11541 /* unsolicited event for HP jack sensing */
11542 static void alc262_tyan_setup(struct hda_codec *codec)
11544 struct alc_spec *spec = codec->spec;
11546 spec->autocfg.hp_pins[0] = 0x1b;
11547 spec->autocfg.speaker_pins[0] = 0x15;
11551 #define alc262_capture_mixer alc882_capture_mixer
11552 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11555 * generic initialization of ADC, input mixers and output mixers
11557 static struct hda_verb alc262_init_verbs[] = {
11559 * Unmute ADC0-2 and set the default input to mic-in
11561 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11562 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11563 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11564 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11565 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11566 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11568 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11570 * Note: PASD motherboards uses the Line In 2 as the input for
11571 * front panel mic (mic 2)
11573 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11578 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11581 * Set up output mixers (0x0c - 0x0e)
11583 /* set vol=0 to output mixers */
11584 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11585 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11587 /* set up input amps for analog loopback */
11588 /* Amp Indices: DAC = 0, mixer = 1 */
11589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11591 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11592 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11593 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11594 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11596 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11597 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11598 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11599 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11600 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11601 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11603 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11605 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11606 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11607 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11609 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11610 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11612 /* FIXME: use matrix-type input source selection */
11613 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11614 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11615 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11616 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11617 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11618 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11620 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11621 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11622 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11623 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11625 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11627 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11633 static struct hda_verb alc262_eapd_verbs[] = {
11634 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11635 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11639 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11640 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11641 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11642 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11644 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11645 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11649 static struct hda_verb alc262_sony_unsol_verbs[] = {
11650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11651 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11654 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11655 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11659 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11660 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11661 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11662 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11668 static struct hda_verb alc262_toshiba_s06_verbs[] = {
11669 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11671 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11673 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11674 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11675 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11676 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11680 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11682 struct alc_spec *spec = codec->spec;
11684 spec->autocfg.hp_pins[0] = 0x15;
11685 spec->autocfg.speaker_pins[0] = 0x14;
11686 spec->ext_mic.pin = 0x18;
11687 spec->ext_mic.mux_idx = 0;
11688 spec->int_mic.pin = 0x12;
11689 spec->int_mic.mux_idx = 9;
11690 spec->auto_mic = 1;
11696 * 0x16 = internal speaker
11697 * 0x18 = external mic
11700 static struct snd_kcontrol_new alc262_nec_mixer[] = {
11701 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11702 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11704 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11705 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11706 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11708 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11709 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11713 static struct hda_verb alc262_nec_verbs[] = {
11714 /* Unmute Speaker */
11715 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11719 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11721 /* External mic to headphone */
11722 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11723 /* External mic to speaker */
11724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11730 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11731 * 0x1b = port replicator headphone out
11734 #define ALC_HP_EVENT 0x37
11736 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11737 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11738 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11739 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11740 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11744 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11745 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11746 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11750 static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11751 /* Front Mic pin: input vref at 50% */
11752 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11753 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11757 static struct hda_input_mux alc262_fujitsu_capture_source = {
11761 { "Internal Mic", 0x1 },
11766 static struct hda_input_mux alc262_HP_capture_source = {
11770 { "Front Mic", 0x1 },
11777 static struct hda_input_mux alc262_HP_D7000_capture_source = {
11781 { "Front Mic", 0x2 },
11787 /* mute/unmute internal speaker according to the hp jacks and mute state */
11788 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11790 struct alc_spec *spec = codec->spec;
11793 if (force || !spec->sense_updated) {
11794 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11795 snd_hda_jack_detect(codec, 0x1b);
11796 spec->sense_updated = 1;
11798 /* unmute internal speaker only if both HPs are unplugged and
11799 * master switch is on
11801 if (spec->jack_present)
11802 mute = HDA_AMP_MUTE;
11804 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11805 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11806 HDA_AMP_MUTE, mute);
11809 /* unsolicited event for HP jack sensing */
11810 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11813 if ((res >> 26) != ALC_HP_EVENT)
11815 alc262_fujitsu_automute(codec, 1);
11818 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11820 alc262_fujitsu_automute(codec, 1);
11823 /* bind volumes of both NID 0x0c and 0x0d */
11824 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11825 .ops = &snd_hda_bind_vol,
11827 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11828 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11833 /* mute/unmute internal speaker according to the hp jack and mute state */
11834 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11836 struct alc_spec *spec = codec->spec;
11839 if (force || !spec->sense_updated) {
11840 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11841 spec->sense_updated = 1;
11843 if (spec->jack_present) {
11844 /* mute internal speaker */
11845 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11846 HDA_AMP_MUTE, HDA_AMP_MUTE);
11847 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11848 HDA_AMP_MUTE, HDA_AMP_MUTE);
11850 /* unmute internal speaker if necessary */
11851 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11852 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11853 HDA_AMP_MUTE, mute);
11854 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11855 HDA_AMP_MUTE, mute);
11859 /* unsolicited event for HP jack sensing */
11860 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11863 if ((res >> 26) != ALC_HP_EVENT)
11865 alc262_lenovo_3000_automute(codec, 1);
11868 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11869 int dir, int idx, long *valp)
11873 for (i = 0; i < 2; i++, valp++)
11874 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11876 *valp ? 0 : HDA_AMP_MUTE);
11880 /* bind hp and internal speaker mute (with plug check) */
11881 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11882 struct snd_ctl_elem_value *ucontrol)
11884 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11885 long *valp = ucontrol->value.integer.value;
11888 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11889 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11891 alc262_fujitsu_automute(codec, 0);
11895 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11896 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11899 .name = "Master Playback Switch",
11900 .subdevice = HDA_SUBDEV_AMP_FLAG,
11901 .info = snd_hda_mixer_amp_switch_info,
11902 .get = snd_hda_mixer_amp_switch_get,
11903 .put = alc262_fujitsu_master_sw_put,
11904 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11907 .iface = NID_MAPPING,
11908 .name = "Master Playback Switch",
11909 .private_value = 0x1b,
11911 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11912 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11913 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11914 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11915 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11916 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11917 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11918 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11922 /* bind hp and internal speaker mute (with plug check) */
11923 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11924 struct snd_ctl_elem_value *ucontrol)
11926 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11927 long *valp = ucontrol->value.integer.value;
11930 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11932 alc262_lenovo_3000_automute(codec, 0);
11936 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11937 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11939 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11940 .name = "Master Playback Switch",
11941 .subdevice = HDA_SUBDEV_AMP_FLAG,
11942 .info = snd_hda_mixer_amp_switch_info,
11943 .get = snd_hda_mixer_amp_switch_get,
11944 .put = alc262_lenovo_3000_master_sw_put,
11945 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11947 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11948 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11950 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11951 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11952 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11953 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11954 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11958 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11959 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11960 ALC262_HIPPO_MASTER_SWITCH,
11961 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11962 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11963 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11964 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11965 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11966 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11970 /* additional init verbs for Benq laptops */
11971 static struct hda_verb alc262_EAPD_verbs[] = {
11972 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11973 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11977 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11978 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11979 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11981 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11982 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11986 /* Samsung Q1 Ultra Vista model setup */
11987 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11988 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11989 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11992 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11993 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11997 static struct hda_verb alc262_ultra_verbs[] = {
11999 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12000 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12001 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12004 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12005 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12006 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12008 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12009 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12010 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12011 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12012 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12014 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12016 /* ADC, choose mic */
12017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12018 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12019 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12020 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12030 /* mute/unmute internal speaker according to the hp jack and mute state */
12031 static void alc262_ultra_automute(struct hda_codec *codec)
12033 struct alc_spec *spec = codec->spec;
12037 /* auto-mute only when HP is used as HP */
12038 if (!spec->cur_mux[0]) {
12039 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12040 if (spec->jack_present)
12041 mute = HDA_AMP_MUTE;
12043 /* mute/unmute internal speaker */
12044 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12045 HDA_AMP_MUTE, mute);
12046 /* mute/unmute HP */
12047 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12048 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12051 /* unsolicited event for HP jack sensing */
12052 static void alc262_ultra_unsol_event(struct hda_codec *codec,
12055 if ((res >> 26) != ALC880_HP_EVENT)
12057 alc262_ultra_automute(codec);
12060 static struct hda_input_mux alc262_ultra_capture_source = {
12064 { "Headphone", 0x7 },
12068 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12069 struct snd_ctl_elem_value *ucontrol)
12071 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12072 struct alc_spec *spec = codec->spec;
12075 ret = alc_mux_enum_put(kcontrol, ucontrol);
12078 /* reprogram the HP pin as mic or HP according to the input source */
12079 snd_hda_codec_write_cache(codec, 0x15, 0,
12080 AC_VERB_SET_PIN_WIDGET_CONTROL,
12081 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12082 alc262_ultra_automute(codec); /* mute/unmute HP */
12086 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12087 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12088 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12090 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12091 .name = "Capture Source",
12092 .info = alc_mux_enum_info,
12093 .get = alc_mux_enum_get,
12094 .put = alc262_ultra_mux_enum_put,
12097 .iface = NID_MAPPING,
12098 .name = "Capture Source",
12099 .private_value = 0x15,
12104 /* We use two mixers depending on the output pin; 0x16 is a mono output
12105 * and thus it's bound with a different mixer.
12106 * This function returns which mixer amp should be used.
12108 static int alc262_check_volbit(hda_nid_t nid)
12112 else if (nid == 0x16)
12118 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12119 const char *pfx, int *vbits, int idx)
12124 vbit = alc262_check_volbit(nid);
12127 if (*vbits & vbit) /* a volume control for this mixer already there */
12131 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12133 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12134 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12137 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12138 const char *pfx, int idx)
12145 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12147 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12148 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12151 /* add playback controls from the parsed DAC table */
12152 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12153 const struct auto_pin_cfg *cfg)
12159 spec->multiout.num_dacs = 1; /* only use one dac */
12160 spec->multiout.dac_nids = spec->private_dac_nids;
12161 spec->multiout.dac_nids[0] = 2;
12163 pfx = alc_get_line_out_pfx(cfg, true);
12166 for (i = 0; i < 2; i++) {
12167 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12170 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12171 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12176 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12177 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12184 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12185 alc262_check_volbit(cfg->speaker_pins[0]) |
12186 alc262_check_volbit(cfg->hp_pins[0]);
12187 if (vbits == 1 || vbits == 2)
12188 pfx = "Master"; /* only one mixer is used */
12190 for (i = 0; i < 2; i++) {
12191 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12195 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12196 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12197 "Speaker", &vbits, i);
12201 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12202 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12203 "Headphone", &vbits, i);
12211 #define alc262_auto_create_input_ctls \
12212 alc882_auto_create_input_ctls
12215 * generic initialization of ADC, input mixers and output mixers
12217 static struct hda_verb alc262_volume_init_verbs[] = {
12219 * Unmute ADC0-2 and set the default input to mic-in
12221 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12222 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12223 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12224 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12225 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12226 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12228 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12230 * Note: PASD motherboards uses the Line In 2 as the input for
12231 * front panel mic (mic 2)
12233 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12234 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12235 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12236 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12237 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12238 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12241 * Set up output mixers (0x0c - 0x0f)
12243 /* set vol=0 to output mixers */
12244 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12245 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12246 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12248 /* set up input amps for analog loopback */
12249 /* Amp Indices: DAC = 0, mixer = 1 */
12250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12252 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12254 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12257 /* FIXME: use matrix-type input source selection */
12258 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12259 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12260 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12261 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12262 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12263 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12265 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12266 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12267 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12268 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12270 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12271 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12272 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12273 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12278 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12280 * Unmute ADC0-2 and set the default input to mic-in
12282 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12284 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12286 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12287 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12289 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12291 * Note: PASD motherboards uses the Line In 2 as the input for
12292 * front panel mic (mic 2)
12294 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12295 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12296 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12297 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12301 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12304 * Set up output mixers (0x0c - 0x0e)
12306 /* set vol=0 to output mixers */
12307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12308 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12309 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12311 /* set up input amps for analog loopback */
12312 /* Amp Indices: DAC = 0, mixer = 1 */
12313 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12314 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12316 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12317 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12318 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12320 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12321 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12322 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12324 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12325 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12327 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12328 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12330 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12331 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12333 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12334 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12338 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12339 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12340 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12341 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12344 /* FIXME: use matrix-type input source selection */
12345 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12346 /* Input mixer1: only unmute Mic */
12347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12349 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12350 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12351 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12359 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12361 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12368 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12369 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12377 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12382 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12384 * Unmute ADC0-2 and set the default input to mic-in
12386 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12387 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12388 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12390 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12391 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12393 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12395 * Note: PASD motherboards uses the Line In 2 as the input for front
12396 * panel mic (mic 2)
12398 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12408 * Set up output mixers (0x0c - 0x0e)
12410 /* set vol=0 to output mixers */
12411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12415 /* set up input amps for analog loopback */
12416 /* Amp Indices: DAC = 0, mixer = 1 */
12417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12418 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12421 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12422 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12425 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12426 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12427 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12428 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12429 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12430 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12431 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12433 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12436 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12437 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12439 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12440 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12441 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12442 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12443 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12444 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12446 /* FIXME: use matrix-type input source selection */
12447 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12448 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12454 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12457 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12458 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12462 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12467 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12470 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12473 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12478 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12484 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12485 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12486 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12487 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12489 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12490 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12502 static const struct alc_fixup alc262_fixups[] = {
12503 [PINFIX_FSC_H270] = {
12504 .type = ALC_FIXUP_PINS,
12505 .v.pins = (const struct alc_pincfg[]) {
12506 { 0x14, 0x99130110 }, /* speaker */
12507 { 0x15, 0x0221142f }, /* front HP */
12508 { 0x1b, 0x0121141f }, /* rear HP */
12514 static struct snd_pci_quirk alc262_fixup_tbl[] = {
12515 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12520 #ifdef CONFIG_SND_HDA_POWER_SAVE
12521 #define alc262_loopbacks alc880_loopbacks
12524 /* pcm configuration: identical with ALC880 */
12525 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12526 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12527 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12528 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12531 * BIOS auto configuration
12533 static int alc262_parse_auto_config(struct hda_codec *codec)
12535 struct alc_spec *spec = codec->spec;
12537 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12539 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12543 if (!spec->autocfg.line_outs) {
12544 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12545 spec->multiout.max_channels = 2;
12546 spec->no_analog = 1;
12549 return 0; /* can't find valid BIOS pin config */
12551 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12554 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12558 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12561 alc_auto_parse_digital(codec);
12563 if (spec->kctls.list)
12564 add_mixer(spec, spec->kctls.list);
12566 add_verb(spec, alc262_volume_init_verbs);
12567 spec->num_mux_defs = 1;
12568 spec->input_mux = &spec->private_imux[0];
12570 err = alc_auto_add_mic_boost(codec);
12574 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12579 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12580 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12581 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12582 #define alc262_auto_init_input_src alc882_auto_init_input_src
12585 /* init callback for auto-configuration model -- overriding the default init */
12586 static void alc262_auto_init(struct hda_codec *codec)
12588 struct alc_spec *spec = codec->spec;
12589 alc262_auto_init_multi_out(codec);
12590 alc262_auto_init_hp_out(codec);
12591 alc262_auto_init_analog_input(codec);
12592 alc262_auto_init_input_src(codec);
12593 alc_auto_init_digital(codec);
12594 if (spec->unsol_event)
12595 alc_inithook(codec);
12599 * configuration and preset
12601 static const char *alc262_models[ALC262_MODEL_LAST] = {
12602 [ALC262_BASIC] = "basic",
12603 [ALC262_HIPPO] = "hippo",
12604 [ALC262_HIPPO_1] = "hippo_1",
12605 [ALC262_FUJITSU] = "fujitsu",
12606 [ALC262_HP_BPC] = "hp-bpc",
12607 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12608 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12609 [ALC262_HP_RP5700] = "hp-rp5700",
12610 [ALC262_BENQ_ED8] = "benq",
12611 [ALC262_BENQ_T31] = "benq-t31",
12612 [ALC262_SONY_ASSAMD] = "sony-assamd",
12613 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12614 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12615 [ALC262_ULTRA] = "ultra",
12616 [ALC262_LENOVO_3000] = "lenovo-3000",
12617 [ALC262_NEC] = "nec",
12618 [ALC262_TYAN] = "tyan",
12619 [ALC262_AUTO] = "auto",
12622 static struct snd_pci_quirk alc262_cfg_tbl[] = {
12623 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12624 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12625 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12627 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12629 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12631 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12632 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12633 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12634 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12635 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12636 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12637 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12638 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12639 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12640 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12641 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12642 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12643 ALC262_HP_TC_T5735),
12644 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12645 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12646 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12647 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12648 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12649 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12650 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12651 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12652 #if 0 /* disable the quirk since model=auto works better in recent versions */
12653 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12654 ALC262_SONY_ASSAMD),
12656 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12657 ALC262_TOSHIBA_RX1),
12658 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12659 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12660 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12661 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12662 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12664 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12665 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12666 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12667 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12668 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12672 static struct alc_config_preset alc262_presets[] = {
12674 .mixers = { alc262_base_mixer },
12675 .init_verbs = { alc262_init_verbs },
12676 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12677 .dac_nids = alc262_dac_nids,
12679 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12680 .channel_mode = alc262_modes,
12681 .input_mux = &alc262_capture_source,
12684 .mixers = { alc262_hippo_mixer },
12685 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12686 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12687 .dac_nids = alc262_dac_nids,
12689 .dig_out_nid = ALC262_DIGOUT_NID,
12690 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12691 .channel_mode = alc262_modes,
12692 .input_mux = &alc262_capture_source,
12693 .unsol_event = alc262_hippo_unsol_event,
12694 .setup = alc262_hippo_setup,
12695 .init_hook = alc262_hippo_automute,
12697 [ALC262_HIPPO_1] = {
12698 .mixers = { alc262_hippo1_mixer },
12699 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12700 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12701 .dac_nids = alc262_dac_nids,
12703 .dig_out_nid = ALC262_DIGOUT_NID,
12704 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12705 .channel_mode = alc262_modes,
12706 .input_mux = &alc262_capture_source,
12707 .unsol_event = alc262_hippo_unsol_event,
12708 .setup = alc262_hippo1_setup,
12709 .init_hook = alc262_hippo_automute,
12711 [ALC262_FUJITSU] = {
12712 .mixers = { alc262_fujitsu_mixer },
12713 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12714 alc262_fujitsu_unsol_verbs },
12715 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12716 .dac_nids = alc262_dac_nids,
12718 .dig_out_nid = ALC262_DIGOUT_NID,
12719 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12720 .channel_mode = alc262_modes,
12721 .input_mux = &alc262_fujitsu_capture_source,
12722 .unsol_event = alc262_fujitsu_unsol_event,
12723 .init_hook = alc262_fujitsu_init_hook,
12725 [ALC262_HP_BPC] = {
12726 .mixers = { alc262_HP_BPC_mixer },
12727 .init_verbs = { alc262_HP_BPC_init_verbs },
12728 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12729 .dac_nids = alc262_dac_nids,
12731 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12732 .channel_mode = alc262_modes,
12733 .input_mux = &alc262_HP_capture_source,
12734 .unsol_event = alc262_hp_bpc_unsol_event,
12735 .init_hook = alc262_hp_bpc_automute,
12737 [ALC262_HP_BPC_D7000_WF] = {
12738 .mixers = { alc262_HP_BPC_WildWest_mixer },
12739 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12740 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12741 .dac_nids = alc262_dac_nids,
12743 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12744 .channel_mode = alc262_modes,
12745 .input_mux = &alc262_HP_D7000_capture_source,
12746 .unsol_event = alc262_hp_wildwest_unsol_event,
12747 .init_hook = alc262_hp_wildwest_automute,
12749 [ALC262_HP_BPC_D7000_WL] = {
12750 .mixers = { alc262_HP_BPC_WildWest_mixer,
12751 alc262_HP_BPC_WildWest_option_mixer },
12752 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12753 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12754 .dac_nids = alc262_dac_nids,
12756 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12757 .channel_mode = alc262_modes,
12758 .input_mux = &alc262_HP_D7000_capture_source,
12759 .unsol_event = alc262_hp_wildwest_unsol_event,
12760 .init_hook = alc262_hp_wildwest_automute,
12762 [ALC262_HP_TC_T5735] = {
12763 .mixers = { alc262_hp_t5735_mixer },
12764 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12765 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12766 .dac_nids = alc262_dac_nids,
12768 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12769 .channel_mode = alc262_modes,
12770 .input_mux = &alc262_capture_source,
12771 .unsol_event = alc_sku_unsol_event,
12772 .setup = alc262_hp_t5735_setup,
12773 .init_hook = alc_inithook,
12775 [ALC262_HP_RP5700] = {
12776 .mixers = { alc262_hp_rp5700_mixer },
12777 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12778 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12779 .dac_nids = alc262_dac_nids,
12780 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12781 .channel_mode = alc262_modes,
12782 .input_mux = &alc262_hp_rp5700_capture_source,
12784 [ALC262_BENQ_ED8] = {
12785 .mixers = { alc262_base_mixer },
12786 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12787 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12788 .dac_nids = alc262_dac_nids,
12790 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12791 .channel_mode = alc262_modes,
12792 .input_mux = &alc262_capture_source,
12794 [ALC262_SONY_ASSAMD] = {
12795 .mixers = { alc262_sony_mixer },
12796 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12797 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12798 .dac_nids = alc262_dac_nids,
12800 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12801 .channel_mode = alc262_modes,
12802 .input_mux = &alc262_capture_source,
12803 .unsol_event = alc262_hippo_unsol_event,
12804 .setup = alc262_hippo_setup,
12805 .init_hook = alc262_hippo_automute,
12807 [ALC262_BENQ_T31] = {
12808 .mixers = { alc262_benq_t31_mixer },
12809 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12810 alc_hp15_unsol_verbs },
12811 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12812 .dac_nids = alc262_dac_nids,
12814 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12815 .channel_mode = alc262_modes,
12816 .input_mux = &alc262_capture_source,
12817 .unsol_event = alc262_hippo_unsol_event,
12818 .setup = alc262_hippo_setup,
12819 .init_hook = alc262_hippo_automute,
12822 .mixers = { alc262_ultra_mixer },
12823 .cap_mixer = alc262_ultra_capture_mixer,
12824 .init_verbs = { alc262_ultra_verbs },
12825 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12826 .dac_nids = alc262_dac_nids,
12827 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12828 .channel_mode = alc262_modes,
12829 .input_mux = &alc262_ultra_capture_source,
12830 .adc_nids = alc262_adc_nids, /* ADC0 */
12831 .capsrc_nids = alc262_capsrc_nids,
12832 .num_adc_nids = 1, /* single ADC */
12833 .unsol_event = alc262_ultra_unsol_event,
12834 .init_hook = alc262_ultra_automute,
12836 [ALC262_LENOVO_3000] = {
12837 .mixers = { alc262_lenovo_3000_mixer },
12838 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12839 alc262_lenovo_3000_unsol_verbs,
12840 alc262_lenovo_3000_init_verbs },
12841 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12842 .dac_nids = alc262_dac_nids,
12844 .dig_out_nid = ALC262_DIGOUT_NID,
12845 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12846 .channel_mode = alc262_modes,
12847 .input_mux = &alc262_fujitsu_capture_source,
12848 .unsol_event = alc262_lenovo_3000_unsol_event,
12851 .mixers = { alc262_nec_mixer },
12852 .init_verbs = { alc262_nec_verbs },
12853 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12854 .dac_nids = alc262_dac_nids,
12856 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12857 .channel_mode = alc262_modes,
12858 .input_mux = &alc262_capture_source,
12860 [ALC262_TOSHIBA_S06] = {
12861 .mixers = { alc262_toshiba_s06_mixer },
12862 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12863 alc262_eapd_verbs },
12864 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12865 .capsrc_nids = alc262_dmic_capsrc_nids,
12866 .dac_nids = alc262_dac_nids,
12867 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12868 .num_adc_nids = 1, /* single ADC */
12869 .dig_out_nid = ALC262_DIGOUT_NID,
12870 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12871 .channel_mode = alc262_modes,
12872 .unsol_event = alc_sku_unsol_event,
12873 .setup = alc262_toshiba_s06_setup,
12874 .init_hook = alc_inithook,
12876 [ALC262_TOSHIBA_RX1] = {
12877 .mixers = { alc262_toshiba_rx1_mixer },
12878 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12879 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12880 .dac_nids = alc262_dac_nids,
12882 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12883 .channel_mode = alc262_modes,
12884 .input_mux = &alc262_capture_source,
12885 .unsol_event = alc262_hippo_unsol_event,
12886 .setup = alc262_hippo_setup,
12887 .init_hook = alc262_hippo_automute,
12890 .mixers = { alc262_tyan_mixer },
12891 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12892 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12893 .dac_nids = alc262_dac_nids,
12895 .dig_out_nid = ALC262_DIGOUT_NID,
12896 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12897 .channel_mode = alc262_modes,
12898 .input_mux = &alc262_capture_source,
12899 .unsol_event = alc_automute_amp_unsol_event,
12900 .setup = alc262_tyan_setup,
12901 .init_hook = alc_automute_amp,
12905 static int patch_alc262(struct hda_codec *codec)
12907 struct alc_spec *spec;
12911 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12915 codec->spec = spec;
12917 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12922 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12923 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12924 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12925 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12928 alc_auto_parse_customize_define(codec);
12930 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12932 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12936 if (board_config < 0) {
12937 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12939 board_config = ALC262_AUTO;
12942 if (board_config == ALC262_AUTO) {
12943 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12944 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12947 if (board_config == ALC262_AUTO) {
12948 /* automatic parse from the BIOS config */
12949 err = alc262_parse_auto_config(codec);
12955 "hda_codec: Cannot set up configuration "
12956 "from BIOS. Using base mode...\n");
12957 board_config = ALC262_BASIC;
12961 if (!spec->no_analog && has_cdefine_beep(codec)) {
12962 err = snd_hda_attach_beep_device(codec, 0x1);
12969 if (board_config != ALC262_AUTO)
12970 setup_preset(codec, &alc262_presets[board_config]);
12972 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12973 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12975 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12976 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12978 if (!spec->adc_nids && spec->input_mux) {
12980 /* check whether the digital-mic has to be supported */
12981 for (i = 0; i < spec->input_mux->num_items; i++) {
12982 if (spec->input_mux->items[i].index >= 9)
12985 if (i < spec->input_mux->num_items) {
12986 /* use only ADC0 */
12987 spec->adc_nids = alc262_dmic_adc_nids;
12988 spec->num_adc_nids = 1;
12989 spec->capsrc_nids = alc262_dmic_capsrc_nids;
12991 /* all analog inputs */
12992 /* check whether NID 0x07 is valid */
12993 unsigned int wcap = get_wcaps(codec, 0x07);
12996 wcap = get_wcaps_type(wcap);
12997 if (wcap != AC_WID_AUD_IN) {
12998 spec->adc_nids = alc262_adc_nids_alt;
12999 spec->num_adc_nids =
13000 ARRAY_SIZE(alc262_adc_nids_alt);
13001 spec->capsrc_nids = alc262_capsrc_nids_alt;
13003 spec->adc_nids = alc262_adc_nids;
13004 spec->num_adc_nids =
13005 ARRAY_SIZE(alc262_adc_nids);
13006 spec->capsrc_nids = alc262_capsrc_nids;
13010 if (!spec->cap_mixer && !spec->no_analog)
13011 set_capture_mixer(codec);
13012 if (!spec->no_analog && has_cdefine_beep(codec))
13013 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13015 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13017 spec->vmaster_nid = 0x0c;
13019 codec->patch_ops = alc_patch_ops;
13020 if (board_config == ALC262_AUTO)
13021 spec->init_hook = alc262_auto_init;
13023 alc_init_jacks(codec);
13024 #ifdef CONFIG_SND_HDA_POWER_SAVE
13025 if (!spec->loopback.amplist)
13026 spec->loopback.amplist = alc262_loopbacks;
13033 * ALC268 channel source setting (2 channel)
13035 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13036 #define alc268_modes alc260_modes
13038 static hda_nid_t alc268_dac_nids[2] = {
13043 static hda_nid_t alc268_adc_nids[2] = {
13048 static hda_nid_t alc268_adc_nids_alt[1] = {
13053 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13055 static struct snd_kcontrol_new alc268_base_mixer[] = {
13056 /* output mixer control */
13057 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13058 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13059 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13060 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13061 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13062 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13063 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13067 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13068 /* output mixer control */
13069 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13071 ALC262_HIPPO_MASTER_SWITCH,
13072 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13073 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13074 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13078 /* bind Beep switches of both NID 0x0f and 0x10 */
13079 static struct hda_bind_ctls alc268_bind_beep_sw = {
13080 .ops = &snd_hda_bind_sw,
13082 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13083 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13088 static struct snd_kcontrol_new alc268_beep_mixer[] = {
13089 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13090 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13094 static struct hda_verb alc268_eapd_verbs[] = {
13095 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13096 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13100 /* Toshiba specific */
13101 static struct hda_verb alc268_toshiba_verbs[] = {
13102 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13106 /* Acer specific */
13107 /* bind volumes of both NID 0x02 and 0x03 */
13108 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13109 .ops = &snd_hda_bind_vol,
13111 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13112 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13117 /* mute/unmute internal speaker according to the hp jack and mute state */
13118 static void alc268_acer_automute(struct hda_codec *codec, int force)
13120 struct alc_spec *spec = codec->spec;
13123 if (force || !spec->sense_updated) {
13124 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
13125 spec->sense_updated = 1;
13127 if (spec->jack_present)
13128 mute = HDA_AMP_MUTE; /* mute internal speaker */
13129 else /* unmute internal speaker if necessary */
13130 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13131 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13132 HDA_AMP_MUTE, mute);
13136 /* bind hp and internal speaker mute (with plug check) */
13137 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13138 struct snd_ctl_elem_value *ucontrol)
13140 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13141 long *valp = ucontrol->value.integer.value;
13144 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
13146 alc268_acer_automute(codec, 0);
13150 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13151 /* output mixer control */
13152 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13155 .name = "Master Playback Switch",
13156 .subdevice = HDA_SUBDEV_AMP_FLAG,
13157 .info = snd_hda_mixer_amp_switch_info,
13158 .get = snd_hda_mixer_amp_switch_get,
13159 .put = alc268_acer_master_sw_put,
13160 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13162 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13166 static struct snd_kcontrol_new alc268_acer_mixer[] = {
13167 /* output mixer control */
13168 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13170 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13171 .name = "Master Playback Switch",
13172 .subdevice = HDA_SUBDEV_AMP_FLAG,
13173 .info = snd_hda_mixer_amp_switch_info,
13174 .get = snd_hda_mixer_amp_switch_get,
13175 .put = alc268_acer_master_sw_put,
13176 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13178 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13179 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13180 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13184 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13185 /* output mixer control */
13186 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13189 .name = "Master Playback Switch",
13190 .subdevice = HDA_SUBDEV_AMP_FLAG,
13191 .info = snd_hda_mixer_amp_switch_info,
13192 .get = snd_hda_mixer_amp_switch_get,
13193 .put = alc268_acer_master_sw_put,
13194 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13196 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13197 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13201 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13202 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13204 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13205 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13206 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13207 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13211 static struct hda_verb alc268_acer_verbs[] = {
13212 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13213 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13216 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13217 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13218 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13222 /* unsolicited event for HP jack sensing */
13223 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
13224 #define alc268_toshiba_setup alc262_hippo_setup
13225 #define alc268_toshiba_automute alc262_hippo_automute
13227 static void alc268_acer_unsol_event(struct hda_codec *codec,
13230 if ((res >> 26) != ALC880_HP_EVENT)
13232 alc268_acer_automute(codec, 1);
13235 static void alc268_acer_init_hook(struct hda_codec *codec)
13237 alc268_acer_automute(codec, 1);
13240 /* toggle speaker-output according to the hp-jack state */
13241 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13243 unsigned int present;
13244 unsigned char bits;
13246 present = snd_hda_jack_detect(codec, 0x15);
13247 bits = present ? HDA_AMP_MUTE : 0;
13248 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
13249 HDA_AMP_MUTE, bits);
13250 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
13251 HDA_AMP_MUTE, bits);
13254 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13257 switch (res >> 26) {
13258 case ALC880_HP_EVENT:
13259 alc268_aspire_one_speaker_automute(codec);
13261 case ALC880_MIC_EVENT:
13262 alc_mic_automute(codec);
13267 static void alc268_acer_lc_setup(struct hda_codec *codec)
13269 struct alc_spec *spec = codec->spec;
13270 spec->ext_mic.pin = 0x18;
13271 spec->ext_mic.mux_idx = 0;
13272 spec->int_mic.pin = 0x12;
13273 spec->int_mic.mux_idx = 6;
13274 spec->auto_mic = 1;
13277 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13279 alc268_aspire_one_speaker_automute(codec);
13280 alc_mic_automute(codec);
13283 static struct snd_kcontrol_new alc268_dell_mixer[] = {
13284 /* output mixer control */
13285 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13286 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13287 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13288 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13289 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13290 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13294 static struct hda_verb alc268_dell_verbs[] = {
13295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13297 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13298 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13302 /* mute/unmute internal speaker according to the hp jack and mute state */
13303 static void alc268_dell_setup(struct hda_codec *codec)
13305 struct alc_spec *spec = codec->spec;
13307 spec->autocfg.hp_pins[0] = 0x15;
13308 spec->autocfg.speaker_pins[0] = 0x14;
13309 spec->ext_mic.pin = 0x18;
13310 spec->ext_mic.mux_idx = 0;
13311 spec->int_mic.pin = 0x19;
13312 spec->int_mic.mux_idx = 1;
13313 spec->auto_mic = 1;
13316 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13317 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13318 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13319 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13320 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13321 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13322 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13323 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13324 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13328 static struct hda_verb alc267_quanta_il1_verbs[] = {
13329 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13330 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13334 static void alc267_quanta_il1_setup(struct hda_codec *codec)
13336 struct alc_spec *spec = codec->spec;
13337 spec->autocfg.hp_pins[0] = 0x15;
13338 spec->autocfg.speaker_pins[0] = 0x14;
13339 spec->ext_mic.pin = 0x18;
13340 spec->ext_mic.mux_idx = 0;
13341 spec->int_mic.pin = 0x19;
13342 spec->int_mic.mux_idx = 1;
13343 spec->auto_mic = 1;
13347 * generic initialization of ADC, input mixers and output mixers
13349 static struct hda_verb alc268_base_init_verbs[] = {
13350 /* Unmute DAC0-1 and set vol = 0 */
13351 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13352 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13355 * Set up output mixers (0x0c - 0x0e)
13357 /* set vol=0 to output mixers */
13358 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13359 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13361 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13362 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13364 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13365 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13366 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13367 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13369 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13370 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13371 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13373 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13374 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13375 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13376 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13377 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13379 /* set PCBEEP vol = 0, mute connections */
13380 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13381 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13382 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13384 /* Unmute Selector 23h,24h and set the default input to mic-in */
13386 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13388 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13389 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13395 * generic initialization of ADC, input mixers and output mixers
13397 static struct hda_verb alc268_volume_init_verbs[] = {
13398 /* set output DAC */
13399 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13400 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13402 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13403 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13404 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13405 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13406 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13408 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13410 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13413 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13415 /* set PCBEEP vol = 0, mute connections */
13416 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13417 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13418 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13423 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13424 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13425 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13429 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13430 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13431 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13436 static struct snd_kcontrol_new alc268_capture_mixer[] = {
13437 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13438 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13439 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13440 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13445 static struct hda_input_mux alc268_capture_source = {
13449 { "Front Mic", 0x1 },
13455 static struct hda_input_mux alc268_acer_capture_source = {
13459 { "Internal Mic", 0x1 },
13464 static struct hda_input_mux alc268_acer_dmic_capture_source = {
13468 { "Internal Mic", 0x6 },
13473 #ifdef CONFIG_SND_DEBUG
13474 static struct snd_kcontrol_new alc268_test_mixer[] = {
13475 /* Volume widgets */
13476 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13477 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13478 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13479 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13480 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13481 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13482 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13483 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13484 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13485 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13486 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13487 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13488 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13489 /* The below appears problematic on some hardwares */
13490 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13491 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13492 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13493 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13494 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13496 /* Modes for retasking pin widgets */
13497 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13498 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13499 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13500 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13502 /* Controls for GPIO pins, assuming they are configured as outputs */
13503 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13504 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13505 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13506 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13508 /* Switches to allow the digital SPDIF output pin to be enabled.
13509 * The ALC268 does not have an SPDIF input.
13511 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13513 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13514 * this output to turn on an external amplifier.
13516 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13517 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13523 /* create input playback/capture controls for the given pin */
13524 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13525 const char *ctlname, int idx)
13536 case 0x1a: /* ALC259/269 only */
13537 case 0x1b: /* ALC259/269 only */
13538 case 0x21: /* ALC269vb has this pin, too */
13542 snd_printd(KERN_WARNING "hda_codec: "
13543 "ignoring pin 0x%x as unknown\n", nid);
13546 if (spec->multiout.dac_nids[0] != dac &&
13547 spec->multiout.dac_nids[1] != dac) {
13548 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13549 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13553 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13557 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13558 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13560 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13561 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13567 /* add playback controls from the parsed DAC table */
13568 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13569 const struct auto_pin_cfg *cfg)
13574 spec->multiout.dac_nids = spec->private_dac_nids;
13576 nid = cfg->line_out_pins[0];
13579 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13583 err = alc268_new_analog_output(spec, nid, name, 0);
13588 nid = cfg->speaker_pins[0];
13590 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13591 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13595 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13599 nid = cfg->hp_pins[0];
13601 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13606 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13608 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13609 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13616 /* create playback/capture controls for input pins */
13617 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13618 const struct auto_pin_cfg *cfg)
13620 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13623 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13624 hda_nid_t nid, int pin_type)
13628 alc_set_pin_output(codec, nid, pin_type);
13629 if (nid == 0x14 || nid == 0x16)
13633 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13636 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13638 struct alc_spec *spec = codec->spec;
13641 for (i = 0; i < spec->autocfg.line_outs; i++) {
13642 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13643 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13644 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13648 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13650 struct alc_spec *spec = codec->spec;
13654 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13655 pin = spec->autocfg.hp_pins[i];
13656 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13658 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13659 pin = spec->autocfg.speaker_pins[i];
13660 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13662 if (spec->autocfg.mono_out_pin)
13663 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13664 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13667 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13669 struct alc_spec *spec = codec->spec;
13670 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13671 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13672 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13673 unsigned int dac_vol1, dac_vol2;
13675 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13676 snd_hda_codec_write(codec, speaker_nid, 0,
13677 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13678 /* mute mixer inputs from 0x1d */
13679 snd_hda_codec_write(codec, 0x0f, 0,
13680 AC_VERB_SET_AMP_GAIN_MUTE,
13682 snd_hda_codec_write(codec, 0x10, 0,
13683 AC_VERB_SET_AMP_GAIN_MUTE,
13686 /* unmute mixer inputs from 0x1d */
13687 snd_hda_codec_write(codec, 0x0f, 0,
13688 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13689 snd_hda_codec_write(codec, 0x10, 0,
13690 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13693 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13694 if (line_nid == 0x14)
13695 dac_vol2 = AMP_OUT_ZERO;
13696 else if (line_nid == 0x15)
13697 dac_vol1 = AMP_OUT_ZERO;
13698 if (hp_nid == 0x14)
13699 dac_vol2 = AMP_OUT_ZERO;
13700 else if (hp_nid == 0x15)
13701 dac_vol1 = AMP_OUT_ZERO;
13702 if (line_nid != 0x16 || hp_nid != 0x16 ||
13703 spec->autocfg.line_out_pins[1] != 0x16 ||
13704 spec->autocfg.line_out_pins[2] != 0x16)
13705 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13707 snd_hda_codec_write(codec, 0x02, 0,
13708 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13709 snd_hda_codec_write(codec, 0x03, 0,
13710 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13713 /* pcm configuration: identical with ALC880 */
13714 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13715 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13716 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13717 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13720 * BIOS auto configuration
13722 static int alc268_parse_auto_config(struct hda_codec *codec)
13724 struct alc_spec *spec = codec->spec;
13726 static hda_nid_t alc268_ignore[] = { 0 };
13728 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13732 if (!spec->autocfg.line_outs) {
13733 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13734 spec->multiout.max_channels = 2;
13735 spec->no_analog = 1;
13738 return 0; /* can't find valid BIOS pin config */
13740 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13743 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13747 spec->multiout.max_channels = 2;
13750 /* digital only support output */
13751 alc_auto_parse_digital(codec);
13752 if (spec->kctls.list)
13753 add_mixer(spec, spec->kctls.list);
13755 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13756 add_mixer(spec, alc268_beep_mixer);
13758 add_verb(spec, alc268_volume_init_verbs);
13759 spec->num_mux_defs = 2;
13760 spec->input_mux = &spec->private_imux[0];
13762 err = alc_auto_add_mic_boost(codec);
13766 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13771 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13773 /* init callback for auto-configuration model -- overriding the default init */
13774 static void alc268_auto_init(struct hda_codec *codec)
13776 struct alc_spec *spec = codec->spec;
13777 alc268_auto_init_multi_out(codec);
13778 alc268_auto_init_hp_out(codec);
13779 alc268_auto_init_mono_speaker_out(codec);
13780 alc268_auto_init_analog_input(codec);
13781 alc_auto_init_digital(codec);
13782 if (spec->unsol_event)
13783 alc_inithook(codec);
13787 * configuration and preset
13789 static const char *alc268_models[ALC268_MODEL_LAST] = {
13790 [ALC267_QUANTA_IL1] = "quanta-il1",
13791 [ALC268_3ST] = "3stack",
13792 [ALC268_TOSHIBA] = "toshiba",
13793 [ALC268_ACER] = "acer",
13794 [ALC268_ACER_DMIC] = "acer-dmic",
13795 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13796 [ALC268_DELL] = "dell",
13797 [ALC268_ZEPTO] = "zepto",
13798 #ifdef CONFIG_SND_DEBUG
13799 [ALC268_TEST] = "test",
13801 [ALC268_AUTO] = "auto",
13804 static struct snd_pci_quirk alc268_cfg_tbl[] = {
13805 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13806 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13807 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13808 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13809 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13810 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13811 ALC268_ACER_ASPIRE_ONE),
13812 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13813 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13814 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13815 /* almost compatible with toshiba but with optional digital outs;
13816 * auto-probing seems working fine
13818 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13820 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13821 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13822 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13823 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13824 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13828 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13829 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13830 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13831 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13832 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13837 static struct alc_config_preset alc268_presets[] = {
13838 [ALC267_QUANTA_IL1] = {
13839 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13840 alc268_capture_nosrc_mixer },
13841 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13842 alc267_quanta_il1_verbs },
13843 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13844 .dac_nids = alc268_dac_nids,
13845 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13846 .adc_nids = alc268_adc_nids_alt,
13848 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13849 .channel_mode = alc268_modes,
13850 .unsol_event = alc_sku_unsol_event,
13851 .setup = alc267_quanta_il1_setup,
13852 .init_hook = alc_inithook,
13855 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13856 alc268_beep_mixer },
13857 .init_verbs = { alc268_base_init_verbs },
13858 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13859 .dac_nids = alc268_dac_nids,
13860 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13861 .adc_nids = alc268_adc_nids_alt,
13862 .capsrc_nids = alc268_capsrc_nids,
13864 .dig_out_nid = ALC268_DIGOUT_NID,
13865 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13866 .channel_mode = alc268_modes,
13867 .input_mux = &alc268_capture_source,
13869 [ALC268_TOSHIBA] = {
13870 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13871 alc268_beep_mixer },
13872 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13873 alc268_toshiba_verbs },
13874 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13875 .dac_nids = alc268_dac_nids,
13876 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13877 .adc_nids = alc268_adc_nids_alt,
13878 .capsrc_nids = alc268_capsrc_nids,
13880 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13881 .channel_mode = alc268_modes,
13882 .input_mux = &alc268_capture_source,
13883 .unsol_event = alc268_toshiba_unsol_event,
13884 .setup = alc268_toshiba_setup,
13885 .init_hook = alc268_toshiba_automute,
13888 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13889 alc268_beep_mixer },
13890 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13891 alc268_acer_verbs },
13892 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13893 .dac_nids = alc268_dac_nids,
13894 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13895 .adc_nids = alc268_adc_nids_alt,
13896 .capsrc_nids = alc268_capsrc_nids,
13898 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13899 .channel_mode = alc268_modes,
13900 .input_mux = &alc268_acer_capture_source,
13901 .unsol_event = alc268_acer_unsol_event,
13902 .init_hook = alc268_acer_init_hook,
13904 [ALC268_ACER_DMIC] = {
13905 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13906 alc268_beep_mixer },
13907 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13908 alc268_acer_verbs },
13909 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13910 .dac_nids = alc268_dac_nids,
13911 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13912 .adc_nids = alc268_adc_nids_alt,
13913 .capsrc_nids = alc268_capsrc_nids,
13915 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13916 .channel_mode = alc268_modes,
13917 .input_mux = &alc268_acer_dmic_capture_source,
13918 .unsol_event = alc268_acer_unsol_event,
13919 .init_hook = alc268_acer_init_hook,
13921 [ALC268_ACER_ASPIRE_ONE] = {
13922 .mixers = { alc268_acer_aspire_one_mixer,
13924 alc268_capture_nosrc_mixer },
13925 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13926 alc268_acer_aspire_one_verbs },
13927 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13928 .dac_nids = alc268_dac_nids,
13929 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13930 .adc_nids = alc268_adc_nids_alt,
13931 .capsrc_nids = alc268_capsrc_nids,
13933 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13934 .channel_mode = alc268_modes,
13935 .unsol_event = alc268_acer_lc_unsol_event,
13936 .setup = alc268_acer_lc_setup,
13937 .init_hook = alc268_acer_lc_init_hook,
13940 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13941 alc268_capture_nosrc_mixer },
13942 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13943 alc268_dell_verbs },
13944 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13945 .dac_nids = alc268_dac_nids,
13946 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13947 .adc_nids = alc268_adc_nids_alt,
13948 .capsrc_nids = alc268_capsrc_nids,
13950 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13951 .channel_mode = alc268_modes,
13952 .unsol_event = alc_sku_unsol_event,
13953 .setup = alc268_dell_setup,
13954 .init_hook = alc_inithook,
13957 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13958 alc268_beep_mixer },
13959 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13960 alc268_toshiba_verbs },
13961 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13962 .dac_nids = alc268_dac_nids,
13963 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13964 .adc_nids = alc268_adc_nids_alt,
13965 .capsrc_nids = alc268_capsrc_nids,
13967 .dig_out_nid = ALC268_DIGOUT_NID,
13968 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13969 .channel_mode = alc268_modes,
13970 .input_mux = &alc268_capture_source,
13971 .setup = alc268_toshiba_setup,
13972 .init_hook = alc268_toshiba_automute,
13974 #ifdef CONFIG_SND_DEBUG
13976 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13977 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13978 alc268_volume_init_verbs },
13979 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13980 .dac_nids = alc268_dac_nids,
13981 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13982 .adc_nids = alc268_adc_nids_alt,
13983 .capsrc_nids = alc268_capsrc_nids,
13985 .dig_out_nid = ALC268_DIGOUT_NID,
13986 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13987 .channel_mode = alc268_modes,
13988 .input_mux = &alc268_capture_source,
13993 static int patch_alc268(struct hda_codec *codec)
13995 struct alc_spec *spec;
13997 int i, has_beep, err;
13999 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14003 codec->spec = spec;
14005 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14009 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14010 board_config = snd_hda_check_board_codec_sid_config(codec,
14011 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14013 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
14014 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14016 board_config = ALC268_AUTO;
14019 if (board_config == ALC268_AUTO) {
14020 /* automatic parse from the BIOS config */
14021 err = alc268_parse_auto_config(codec);
14027 "hda_codec: Cannot set up configuration "
14028 "from BIOS. Using base mode...\n");
14029 board_config = ALC268_3ST;
14033 if (board_config != ALC268_AUTO)
14034 setup_preset(codec, &alc268_presets[board_config]);
14036 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14037 spec->stream_analog_capture = &alc268_pcm_analog_capture;
14038 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14040 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14043 for (i = 0; i < spec->num_mixers; i++) {
14044 if (spec->mixers[i] == alc268_beep_mixer) {
14051 err = snd_hda_attach_beep_device(codec, 0x1);
14056 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14057 /* override the amp caps for beep generator */
14058 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14059 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14060 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14061 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14062 (0 << AC_AMPCAP_MUTE_SHIFT));
14065 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14066 /* check whether NID 0x07 is valid */
14067 unsigned int wcap = get_wcaps(codec, 0x07);
14070 spec->capsrc_nids = alc268_capsrc_nids;
14072 wcap = get_wcaps_type(wcap);
14073 if (spec->auto_mic ||
14074 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14075 spec->adc_nids = alc268_adc_nids_alt;
14076 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14077 if (spec->auto_mic)
14078 fixup_automic_adc(codec);
14079 if (spec->auto_mic || spec->input_mux->num_items == 1)
14080 add_mixer(spec, alc268_capture_nosrc_mixer);
14082 add_mixer(spec, alc268_capture_alt_mixer);
14084 spec->adc_nids = alc268_adc_nids;
14085 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14086 add_mixer(spec, alc268_capture_mixer);
14088 /* set default input source */
14089 for (i = 0; i < spec->num_adc_nids; i++)
14090 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14091 0, AC_VERB_SET_CONNECT_SEL,
14092 i < spec->num_mux_defs ?
14093 spec->input_mux[i].items[0].index :
14094 spec->input_mux->items[0].index);
14097 spec->vmaster_nid = 0x02;
14099 codec->patch_ops = alc_patch_ops;
14100 if (board_config == ALC268_AUTO)
14101 spec->init_hook = alc268_auto_init;
14103 alc_init_jacks(codec);
14109 * ALC269 channel source setting (2 channel)
14111 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14113 #define alc269_dac_nids alc260_dac_nids
14115 static hda_nid_t alc269_adc_nids[1] = {
14120 static hda_nid_t alc269_capsrc_nids[1] = {
14124 static hda_nid_t alc269vb_adc_nids[1] = {
14129 static hda_nid_t alc269vb_capsrc_nids[1] = {
14133 static hda_nid_t alc269_adc_candidates[] = {
14137 #define alc269_modes alc260_modes
14138 #define alc269_capture_source alc880_lg_lw_capture_source
14140 static struct snd_kcontrol_new alc269_base_mixer[] = {
14141 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14142 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14147 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14148 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14149 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14150 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14152 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14156 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14157 /* output mixer control */
14158 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14160 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14161 .name = "Master Playback Switch",
14162 .subdevice = HDA_SUBDEV_AMP_FLAG,
14163 .info = snd_hda_mixer_amp_switch_info,
14164 .get = snd_hda_mixer_amp_switch_get,
14165 .put = alc268_acer_master_sw_put,
14166 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14168 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14169 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14171 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14172 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14173 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14177 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14178 /* output mixer control */
14179 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14182 .name = "Master Playback Switch",
14183 .subdevice = HDA_SUBDEV_AMP_FLAG,
14184 .info = snd_hda_mixer_amp_switch_info,
14185 .get = snd_hda_mixer_amp_switch_get,
14186 .put = alc268_acer_master_sw_put,
14187 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14189 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14190 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14192 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14193 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14194 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14195 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14196 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14197 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14201 static struct snd_kcontrol_new alc269_laptop_mixer[] = {
14202 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14203 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14205 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14209 static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14210 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14211 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14217 static struct snd_kcontrol_new alc269_asus_mixer[] = {
14218 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14219 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14223 /* capture mixer elements */
14224 static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14225 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14226 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14227 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14228 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14232 static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14233 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14234 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14235 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14239 static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14240 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14241 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14242 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14243 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14247 static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14248 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14249 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14250 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14255 #define alc269_fujitsu_mixer alc269_laptop_mixer
14257 static struct hda_verb alc269_quanta_fl1_verbs[] = {
14258 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14259 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14261 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14262 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14263 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14267 static struct hda_verb alc269_lifebook_verbs[] = {
14268 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14269 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14270 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14272 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14273 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14274 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14275 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14276 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14277 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14281 /* toggle speaker-output according to the hp-jack state */
14282 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14284 unsigned int present;
14285 unsigned char bits;
14287 present = snd_hda_jack_detect(codec, 0x15);
14288 bits = present ? HDA_AMP_MUTE : 0;
14289 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14290 HDA_AMP_MUTE, bits);
14291 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14292 HDA_AMP_MUTE, bits);
14294 snd_hda_codec_write(codec, 0x20, 0,
14295 AC_VERB_SET_COEF_INDEX, 0x0c);
14296 snd_hda_codec_write(codec, 0x20, 0,
14297 AC_VERB_SET_PROC_COEF, 0x680);
14299 snd_hda_codec_write(codec, 0x20, 0,
14300 AC_VERB_SET_COEF_INDEX, 0x0c);
14301 snd_hda_codec_write(codec, 0x20, 0,
14302 AC_VERB_SET_PROC_COEF, 0x480);
14305 /* toggle speaker-output according to the hp-jacks state */
14306 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14308 unsigned int present;
14309 unsigned char bits;
14311 /* Check laptop headphone socket */
14312 present = snd_hda_jack_detect(codec, 0x15);
14314 /* Check port replicator headphone socket */
14315 present |= snd_hda_jack_detect(codec, 0x1a);
14317 bits = present ? HDA_AMP_MUTE : 0;
14318 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14319 HDA_AMP_MUTE, bits);
14320 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14321 HDA_AMP_MUTE, bits);
14323 snd_hda_codec_write(codec, 0x20, 0,
14324 AC_VERB_SET_COEF_INDEX, 0x0c);
14325 snd_hda_codec_write(codec, 0x20, 0,
14326 AC_VERB_SET_PROC_COEF, 0x680);
14328 snd_hda_codec_write(codec, 0x20, 0,
14329 AC_VERB_SET_COEF_INDEX, 0x0c);
14330 snd_hda_codec_write(codec, 0x20, 0,
14331 AC_VERB_SET_PROC_COEF, 0x480);
14334 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14336 unsigned int present_laptop;
14337 unsigned int present_dock;
14339 present_laptop = snd_hda_jack_detect(codec, 0x18);
14340 present_dock = snd_hda_jack_detect(codec, 0x1b);
14342 /* Laptop mic port overrides dock mic port, design decision */
14344 snd_hda_codec_write(codec, 0x23, 0,
14345 AC_VERB_SET_CONNECT_SEL, 0x3);
14346 if (present_laptop)
14347 snd_hda_codec_write(codec, 0x23, 0,
14348 AC_VERB_SET_CONNECT_SEL, 0x0);
14349 if (!present_dock && !present_laptop)
14350 snd_hda_codec_write(codec, 0x23, 0,
14351 AC_VERB_SET_CONNECT_SEL, 0x1);
14354 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14357 switch (res >> 26) {
14358 case ALC880_HP_EVENT:
14359 alc269_quanta_fl1_speaker_automute(codec);
14361 case ALC880_MIC_EVENT:
14362 alc_mic_automute(codec);
14367 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14370 if ((res >> 26) == ALC880_HP_EVENT)
14371 alc269_lifebook_speaker_automute(codec);
14372 if ((res >> 26) == ALC880_MIC_EVENT)
14373 alc269_lifebook_mic_autoswitch(codec);
14376 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14378 struct alc_spec *spec = codec->spec;
14379 spec->autocfg.hp_pins[0] = 0x15;
14380 spec->autocfg.speaker_pins[0] = 0x14;
14381 spec->ext_mic.pin = 0x18;
14382 spec->ext_mic.mux_idx = 0;
14383 spec->int_mic.pin = 0x19;
14384 spec->int_mic.mux_idx = 1;
14385 spec->auto_mic = 1;
14388 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14390 alc269_quanta_fl1_speaker_automute(codec);
14391 alc_mic_automute(codec);
14394 static void alc269_lifebook_init_hook(struct hda_codec *codec)
14396 alc269_lifebook_speaker_automute(codec);
14397 alc269_lifebook_mic_autoswitch(codec);
14400 static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14401 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14402 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14403 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14405 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14406 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14407 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14411 static struct hda_verb alc269_laptop_amic_init_verbs[] = {
14412 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14413 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14414 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14415 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14416 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14417 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14421 static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14422 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14423 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14424 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14425 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14426 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14427 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14428 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14432 static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14433 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14434 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14435 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14436 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14437 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14438 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14439 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14443 static struct hda_verb alc271_acer_dmic_verbs[] = {
14444 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14445 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14446 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14447 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14448 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14449 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14450 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14451 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14452 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14453 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14457 /* toggle speaker-output according to the hp-jack state */
14458 static void alc269_speaker_automute(struct hda_codec *codec)
14460 struct alc_spec *spec = codec->spec;
14461 unsigned int nid = spec->autocfg.hp_pins[0];
14462 unsigned int present;
14463 unsigned char bits;
14465 present = snd_hda_jack_detect(codec, nid);
14466 bits = present ? HDA_AMP_MUTE : 0;
14467 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14468 HDA_AMP_MUTE, bits);
14469 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14470 HDA_AMP_MUTE, bits);
14471 alc_report_jack(codec, nid);
14474 /* unsolicited event for HP jack sensing */
14475 static void alc269_laptop_unsol_event(struct hda_codec *codec,
14478 switch (res >> 26) {
14479 case ALC880_HP_EVENT:
14480 alc269_speaker_automute(codec);
14482 case ALC880_MIC_EVENT:
14483 alc_mic_automute(codec);
14488 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14490 struct alc_spec *spec = codec->spec;
14491 spec->autocfg.hp_pins[0] = 0x15;
14492 spec->autocfg.speaker_pins[0] = 0x14;
14493 spec->ext_mic.pin = 0x18;
14494 spec->ext_mic.mux_idx = 0;
14495 spec->int_mic.pin = 0x19;
14496 spec->int_mic.mux_idx = 1;
14497 spec->auto_mic = 1;
14500 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14502 struct alc_spec *spec = codec->spec;
14503 spec->autocfg.hp_pins[0] = 0x15;
14504 spec->autocfg.speaker_pins[0] = 0x14;
14505 spec->ext_mic.pin = 0x18;
14506 spec->ext_mic.mux_idx = 0;
14507 spec->int_mic.pin = 0x12;
14508 spec->int_mic.mux_idx = 5;
14509 spec->auto_mic = 1;
14512 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14514 struct alc_spec *spec = codec->spec;
14515 spec->autocfg.hp_pins[0] = 0x21;
14516 spec->autocfg.speaker_pins[0] = 0x14;
14517 spec->ext_mic.pin = 0x18;
14518 spec->ext_mic.mux_idx = 0;
14519 spec->int_mic.pin = 0x19;
14520 spec->int_mic.mux_idx = 1;
14521 spec->auto_mic = 1;
14524 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14526 struct alc_spec *spec = codec->spec;
14527 spec->autocfg.hp_pins[0] = 0x21;
14528 spec->autocfg.speaker_pins[0] = 0x14;
14529 spec->ext_mic.pin = 0x18;
14530 spec->ext_mic.mux_idx = 0;
14531 spec->int_mic.pin = 0x12;
14532 spec->int_mic.mux_idx = 6;
14533 spec->auto_mic = 1;
14536 static void alc269_laptop_inithook(struct hda_codec *codec)
14538 alc269_speaker_automute(codec);
14539 alc_mic_automute(codec);
14543 * generic initialization of ADC, input mixers and output mixers
14545 static struct hda_verb alc269_init_verbs[] = {
14547 * Unmute ADC0 and set the default input to mic-in
14549 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14552 * Set up output mixers (0x02 - 0x03)
14554 /* set vol=0 to output mixers */
14555 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14556 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14558 /* set up input amps for analog loopback */
14559 /* Amp Indices: DAC = 0, mixer = 1 */
14560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14564 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14567 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14568 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14569 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14570 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14571 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14572 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14573 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14578 /* FIXME: use Mux-type input source selection */
14579 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14580 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14581 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14584 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14588 static struct hda_verb alc269vb_init_verbs[] = {
14590 * Unmute ADC0 and set the default input to mic-in
14592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14595 * Set up output mixers (0x02 - 0x03)
14597 /* set vol=0 to output mixers */
14598 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14599 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14601 /* set up input amps for analog loopback */
14602 /* Amp Indices: DAC = 0, mixer = 1 */
14603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14605 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14607 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14608 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14611 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14612 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14613 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14614 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14615 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14616 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14618 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14619 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14621 /* FIXME: use Mux-type input source selection */
14622 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14623 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14624 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14627 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14631 #define alc269_auto_create_multi_out_ctls \
14632 alc268_auto_create_multi_out_ctls
14633 #define alc269_auto_create_input_ctls \
14634 alc268_auto_create_input_ctls
14636 #ifdef CONFIG_SND_HDA_POWER_SAVE
14637 #define alc269_loopbacks alc880_loopbacks
14640 /* pcm configuration: identical with ALC880 */
14641 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14642 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14643 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14644 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14646 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14650 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14651 /* NID is set in alc_build_pcms */
14653 .open = alc880_playback_pcm_open,
14654 .prepare = alc880_playback_pcm_prepare,
14655 .cleanup = alc880_playback_pcm_cleanup
14659 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14663 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14664 /* NID is set in alc_build_pcms */
14667 #ifdef CONFIG_SND_HDA_POWER_SAVE
14668 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14670 switch (codec->subsystem_id) {
14677 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14679 /* update mute-LED according to the speaker mute state */
14680 if (nid == 0x01 || nid == 0x14) {
14682 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14687 /* mic2 vref pin is used for mute LED control */
14688 snd_hda_codec_update_cache(codec, 0x19, 0,
14689 AC_VERB_SET_PIN_WIDGET_CONTROL,
14692 return alc_check_power_status(codec, nid);
14694 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14696 static int alc275_setup_dual_adc(struct hda_codec *codec)
14698 struct alc_spec *spec = codec->spec;
14700 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14702 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14703 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14704 if (spec->ext_mic.pin <= 0x12) {
14705 spec->private_adc_nids[0] = 0x08;
14706 spec->private_adc_nids[1] = 0x11;
14707 spec->private_capsrc_nids[0] = 0x23;
14708 spec->private_capsrc_nids[1] = 0x22;
14710 spec->private_adc_nids[0] = 0x11;
14711 spec->private_adc_nids[1] = 0x08;
14712 spec->private_capsrc_nids[0] = 0x22;
14713 spec->private_capsrc_nids[1] = 0x23;
14715 spec->adc_nids = spec->private_adc_nids;
14716 spec->capsrc_nids = spec->private_capsrc_nids;
14717 spec->num_adc_nids = 2;
14718 spec->dual_adc_switch = 1;
14719 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14720 spec->adc_nids[0], spec->adc_nids[1]);
14726 /* different alc269-variants */
14728 ALC269_TYPE_NORMAL,
14729 ALC269_TYPE_ALC258,
14730 ALC269_TYPE_ALC259,
14731 ALC269_TYPE_ALC269VB,
14732 ALC269_TYPE_ALC270,
14733 ALC269_TYPE_ALC271X,
14737 * BIOS auto configuration
14739 static int alc269_parse_auto_config(struct hda_codec *codec)
14741 struct alc_spec *spec = codec->spec;
14743 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14745 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14750 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14753 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14754 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14756 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14761 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14763 alc_auto_parse_digital(codec);
14765 if (spec->kctls.list)
14766 add_mixer(spec, spec->kctls.list);
14768 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14769 add_verb(spec, alc269vb_init_verbs);
14770 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14772 add_verb(spec, alc269_init_verbs);
14773 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14776 spec->num_mux_defs = 1;
14777 spec->input_mux = &spec->private_imux[0];
14779 if (!alc275_setup_dual_adc(codec))
14780 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14781 sizeof(alc269_adc_candidates));
14783 /* set default input source */
14784 if (!spec->dual_adc_switch)
14785 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14786 spec->input_mux->items[0].index);
14788 err = alc_auto_add_mic_boost(codec);
14792 if (!spec->cap_mixer && !spec->no_analog)
14793 set_capture_mixer(codec);
14798 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14799 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14800 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14803 /* init callback for auto-configuration model -- overriding the default init */
14804 static void alc269_auto_init(struct hda_codec *codec)
14806 struct alc_spec *spec = codec->spec;
14807 alc269_auto_init_multi_out(codec);
14808 alc269_auto_init_hp_out(codec);
14809 alc269_auto_init_analog_input(codec);
14810 alc_auto_init_digital(codec);
14811 if (spec->unsol_event)
14812 alc_inithook(codec);
14815 #ifdef SND_HDA_NEEDS_RESUME
14816 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14818 int val = alc_read_coef_idx(codec, 0x04);
14823 alc_write_coef_idx(codec, 0x04, val);
14826 #ifdef CONFIG_SND_HDA_POWER_SAVE
14827 static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14829 struct alc_spec *spec = codec->spec;
14831 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14832 alc269_toggle_power_output(codec, 0);
14833 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14834 alc269_toggle_power_output(codec, 0);
14839 if (spec && spec->power_hook)
14840 spec->power_hook(codec);
14843 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14845 static int alc269_resume(struct hda_codec *codec)
14847 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14848 alc269_toggle_power_output(codec, 0);
14852 codec->patch_ops.init(codec);
14854 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14855 alc269_toggle_power_output(codec, 1);
14859 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14860 alc269_toggle_power_output(codec, 1);
14862 snd_hda_codec_resume_amp(codec);
14863 snd_hda_codec_resume_cache(codec);
14864 hda_call_check_power_status(codec, 0x01);
14867 #endif /* SND_HDA_NEEDS_RESUME */
14869 static void alc269_fixup_hweq(struct hda_codec *codec,
14870 const struct alc_fixup *fix, int action)
14874 if (action != ALC_FIXUP_ACT_PROBE)
14876 coef = alc_read_coef_idx(codec, 0x1e);
14877 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14881 ALC269_FIXUP_SONY_VAIO,
14882 ALC275_FIXUP_SONY_VAIO_GPIO2,
14883 ALC269_FIXUP_DELL_M101Z,
14884 ALC269_FIXUP_SKU_IGNORE,
14885 ALC269_FIXUP_ASUS_G73JW,
14886 ALC269_FIXUP_LENOVO_EAPD,
14887 ALC275_FIXUP_SONY_HWEQ,
14890 static const struct alc_fixup alc269_fixups[] = {
14891 [ALC269_FIXUP_SONY_VAIO] = {
14892 .type = ALC_FIXUP_VERBS,
14893 .v.verbs = (const struct hda_verb[]) {
14894 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14898 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14899 .type = ALC_FIXUP_VERBS,
14900 .v.verbs = (const struct hda_verb[]) {
14901 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14902 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14903 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14907 .chain_id = ALC269_FIXUP_SONY_VAIO
14909 [ALC269_FIXUP_DELL_M101Z] = {
14910 .type = ALC_FIXUP_VERBS,
14911 .v.verbs = (const struct hda_verb[]) {
14912 /* Enables internal speaker */
14913 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14914 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14918 [ALC269_FIXUP_SKU_IGNORE] = {
14919 .type = ALC_FIXUP_SKU,
14920 .v.sku = ALC_FIXUP_SKU_IGNORE,
14922 [ALC269_FIXUP_ASUS_G73JW] = {
14923 .type = ALC_FIXUP_PINS,
14924 .v.pins = (const struct alc_pincfg[]) {
14925 { 0x17, 0x99130111 }, /* subwoofer */
14929 [ALC269_FIXUP_LENOVO_EAPD] = {
14930 .type = ALC_FIXUP_VERBS,
14931 .v.verbs = (const struct hda_verb[]) {
14932 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14936 [ALC275_FIXUP_SONY_HWEQ] = {
14937 .type = ALC_FIXUP_FUNC,
14938 .v.func = alc269_fixup_hweq,
14940 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14944 static struct snd_pci_quirk alc269_fixup_tbl[] = {
14945 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14946 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14947 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14948 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14949 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14950 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14951 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14952 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14953 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14959 * configuration and preset
14961 static const char *alc269_models[ALC269_MODEL_LAST] = {
14962 [ALC269_BASIC] = "basic",
14963 [ALC269_QUANTA_FL1] = "quanta",
14964 [ALC269_AMIC] = "laptop-amic",
14965 [ALC269_DMIC] = "laptop-dmic",
14966 [ALC269_FUJITSU] = "fujitsu",
14967 [ALC269_LIFEBOOK] = "lifebook",
14968 [ALC269_AUTO] = "auto",
14971 static struct snd_pci_quirk alc269_cfg_tbl[] = {
14972 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14973 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14974 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14976 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14977 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14978 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14979 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14980 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14981 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14982 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14983 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14984 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14985 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14986 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14987 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14988 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14989 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14990 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14991 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14992 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15001 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15002 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15008 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15014 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15016 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15017 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15018 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15019 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15020 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15021 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15022 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15023 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15024 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15025 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15029 static struct alc_config_preset alc269_presets[] = {
15031 .mixers = { alc269_base_mixer },
15032 .init_verbs = { alc269_init_verbs },
15033 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15034 .dac_nids = alc269_dac_nids,
15036 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15037 .channel_mode = alc269_modes,
15038 .input_mux = &alc269_capture_source,
15040 [ALC269_QUANTA_FL1] = {
15041 .mixers = { alc269_quanta_fl1_mixer },
15042 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15043 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15044 .dac_nids = alc269_dac_nids,
15046 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15047 .channel_mode = alc269_modes,
15048 .input_mux = &alc269_capture_source,
15049 .unsol_event = alc269_quanta_fl1_unsol_event,
15050 .setup = alc269_quanta_fl1_setup,
15051 .init_hook = alc269_quanta_fl1_init_hook,
15054 .mixers = { alc269_laptop_mixer },
15055 .cap_mixer = alc269_laptop_analog_capture_mixer,
15056 .init_verbs = { alc269_init_verbs,
15057 alc269_laptop_amic_init_verbs },
15058 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15059 .dac_nids = alc269_dac_nids,
15061 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15062 .channel_mode = alc269_modes,
15063 .unsol_event = alc269_laptop_unsol_event,
15064 .setup = alc269_laptop_amic_setup,
15065 .init_hook = alc269_laptop_inithook,
15068 .mixers = { alc269_laptop_mixer },
15069 .cap_mixer = alc269_laptop_digital_capture_mixer,
15070 .init_verbs = { alc269_init_verbs,
15071 alc269_laptop_dmic_init_verbs },
15072 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15073 .dac_nids = alc269_dac_nids,
15075 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15076 .channel_mode = alc269_modes,
15077 .unsol_event = alc269_laptop_unsol_event,
15078 .setup = alc269_laptop_dmic_setup,
15079 .init_hook = alc269_laptop_inithook,
15081 [ALC269VB_AMIC] = {
15082 .mixers = { alc269vb_laptop_mixer },
15083 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15084 .init_verbs = { alc269vb_init_verbs,
15085 alc269vb_laptop_amic_init_verbs },
15086 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15087 .dac_nids = alc269_dac_nids,
15089 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15090 .channel_mode = alc269_modes,
15091 .unsol_event = alc269_laptop_unsol_event,
15092 .setup = alc269vb_laptop_amic_setup,
15093 .init_hook = alc269_laptop_inithook,
15095 [ALC269VB_DMIC] = {
15096 .mixers = { alc269vb_laptop_mixer },
15097 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15098 .init_verbs = { alc269vb_init_verbs,
15099 alc269vb_laptop_dmic_init_verbs },
15100 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15101 .dac_nids = alc269_dac_nids,
15103 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15104 .channel_mode = alc269_modes,
15105 .unsol_event = alc269_laptop_unsol_event,
15106 .setup = alc269vb_laptop_dmic_setup,
15107 .init_hook = alc269_laptop_inithook,
15109 [ALC269_FUJITSU] = {
15110 .mixers = { alc269_fujitsu_mixer },
15111 .cap_mixer = alc269_laptop_digital_capture_mixer,
15112 .init_verbs = { alc269_init_verbs,
15113 alc269_laptop_dmic_init_verbs },
15114 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15115 .dac_nids = alc269_dac_nids,
15117 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15118 .channel_mode = alc269_modes,
15119 .unsol_event = alc269_laptop_unsol_event,
15120 .setup = alc269_laptop_dmic_setup,
15121 .init_hook = alc269_laptop_inithook,
15123 [ALC269_LIFEBOOK] = {
15124 .mixers = { alc269_lifebook_mixer },
15125 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15126 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15127 .dac_nids = alc269_dac_nids,
15129 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15130 .channel_mode = alc269_modes,
15131 .input_mux = &alc269_capture_source,
15132 .unsol_event = alc269_lifebook_unsol_event,
15133 .init_hook = alc269_lifebook_init_hook,
15136 .mixers = { alc269_asus_mixer },
15137 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15138 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15139 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15140 .dac_nids = alc269_dac_nids,
15141 .adc_nids = alc262_dmic_adc_nids,
15142 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15143 .capsrc_nids = alc262_dmic_capsrc_nids,
15144 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15145 .channel_mode = alc269_modes,
15146 .input_mux = &alc269_capture_source,
15147 .dig_out_nid = ALC880_DIGOUT_NID,
15148 .unsol_event = alc_sku_unsol_event,
15149 .setup = alc269vb_laptop_dmic_setup,
15150 .init_hook = alc_inithook,
15154 static int alc269_fill_coef(struct hda_codec *codec)
15158 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15159 alc_write_coef_idx(codec, 0xf, 0x960b);
15160 alc_write_coef_idx(codec, 0xe, 0x8817);
15163 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15164 alc_write_coef_idx(codec, 0xf, 0x960b);
15165 alc_write_coef_idx(codec, 0xe, 0x8814);
15168 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15169 val = alc_read_coef_idx(codec, 0x04);
15170 /* Power up output pin */
15171 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15174 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15175 val = alc_read_coef_idx(codec, 0xd);
15176 if ((val & 0x0c00) >> 10 != 0x1) {
15177 /* Capless ramp up clock control */
15178 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15180 val = alc_read_coef_idx(codec, 0x17);
15181 if ((val & 0x01c0) >> 6 != 0x4) {
15182 /* Class D power on reset */
15183 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15189 static int patch_alc269(struct hda_codec *codec)
15191 struct alc_spec *spec;
15192 int board_config, coef;
15195 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15199 codec->spec = spec;
15201 alc_auto_parse_customize_define(codec);
15203 if (codec->vendor_id == 0x10ec0269) {
15204 coef = alc_read_coef_idx(codec, 0);
15205 if ((coef & 0x00f0) == 0x0010) {
15206 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15207 spec->cdefine.platform_type == 1) {
15208 alc_codec_rename(codec, "ALC271X");
15209 spec->codec_variant = ALC269_TYPE_ALC271X;
15210 } else if ((coef & 0xf000) == 0x1000) {
15211 spec->codec_variant = ALC269_TYPE_ALC270;
15212 } else if ((coef & 0xf000) == 0x2000) {
15213 alc_codec_rename(codec, "ALC259");
15214 spec->codec_variant = ALC269_TYPE_ALC259;
15215 } else if ((coef & 0xf000) == 0x3000) {
15216 alc_codec_rename(codec, "ALC258");
15217 spec->codec_variant = ALC269_TYPE_ALC258;
15219 alc_codec_rename(codec, "ALC269VB");
15220 spec->codec_variant = ALC269_TYPE_ALC269VB;
15223 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15224 alc269_fill_coef(codec);
15227 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15231 if (board_config < 0) {
15232 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15234 board_config = ALC269_AUTO;
15237 if (board_config == ALC269_AUTO) {
15238 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15239 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15242 if (board_config == ALC269_AUTO) {
15243 /* automatic parse from the BIOS config */
15244 err = alc269_parse_auto_config(codec);
15250 "hda_codec: Cannot set up configuration "
15251 "from BIOS. Using base mode...\n");
15252 board_config = ALC269_BASIC;
15256 if (has_cdefine_beep(codec)) {
15257 err = snd_hda_attach_beep_device(codec, 0x1);
15264 if (board_config != ALC269_AUTO)
15265 setup_preset(codec, &alc269_presets[board_config]);
15267 if (board_config == ALC269_QUANTA_FL1) {
15268 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15269 * fix the sample rate of analog I/O to 44.1kHz
15271 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15272 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15273 } else if (spec->dual_adc_switch) {
15274 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15275 /* switch ADC dynamically */
15276 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15278 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15279 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15281 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15282 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15284 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15285 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15286 spec->adc_nids = alc269_adc_nids;
15287 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15288 spec->capsrc_nids = alc269_capsrc_nids;
15290 spec->adc_nids = alc269vb_adc_nids;
15291 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15292 spec->capsrc_nids = alc269vb_capsrc_nids;
15296 if (!spec->cap_mixer)
15297 set_capture_mixer(codec);
15298 if (has_cdefine_beep(codec))
15299 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15301 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15303 spec->vmaster_nid = 0x02;
15305 codec->patch_ops = alc_patch_ops;
15306 #ifdef CONFIG_SND_HDA_POWER_SAVE
15307 codec->patch_ops.suspend = alc269_suspend;
15309 #ifdef SND_HDA_NEEDS_RESUME
15310 codec->patch_ops.resume = alc269_resume;
15312 if (board_config == ALC269_AUTO)
15313 spec->init_hook = alc269_auto_init;
15315 alc_init_jacks(codec);
15316 #ifdef CONFIG_SND_HDA_POWER_SAVE
15317 if (!spec->loopback.amplist)
15318 spec->loopback.amplist = alc269_loopbacks;
15319 if (alc269_mic2_for_mute_led(codec))
15320 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15327 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15331 * set the path ways for 2 channel output
15332 * need to set the codec line out and mic 1 pin widgets to inputs
15334 static struct hda_verb alc861_threestack_ch2_init[] = {
15335 /* set pin widget 1Ah (line in) for input */
15336 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15337 /* set pin widget 18h (mic1/2) for input, for mic also enable
15340 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15342 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15344 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15345 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15351 * need to set the codec line out and mic 1 pin widgets to outputs
15353 static struct hda_verb alc861_threestack_ch6_init[] = {
15354 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15355 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15356 /* set pin widget 18h (mic1) for output (CLFE)*/
15357 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15359 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15360 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15362 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15364 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15365 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15370 static struct hda_channel_mode alc861_threestack_modes[2] = {
15371 { 2, alc861_threestack_ch2_init },
15372 { 6, alc861_threestack_ch6_init },
15374 /* Set mic1 as input and unmute the mixer */
15375 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15376 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15377 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15380 /* Set mic1 as output and mute mixer */
15381 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15382 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15383 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15387 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15388 { 2, alc861_uniwill_m31_ch2_init },
15389 { 4, alc861_uniwill_m31_ch4_init },
15392 /* Set mic1 and line-in as input and unmute the mixer */
15393 static struct hda_verb alc861_asus_ch2_init[] = {
15394 /* set pin widget 1Ah (line in) for input */
15395 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15396 /* set pin widget 18h (mic1/2) for input, for mic also enable
15399 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15401 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15403 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15404 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15408 /* Set mic1 nad line-in as output and mute mixer */
15409 static struct hda_verb alc861_asus_ch6_init[] = {
15410 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15411 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15412 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15413 /* set pin widget 18h (mic1) for output (CLFE)*/
15414 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15415 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15416 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15417 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15419 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15421 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15422 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15427 static struct hda_channel_mode alc861_asus_modes[2] = {
15428 { 2, alc861_asus_ch2_init },
15429 { 6, alc861_asus_ch6_init },
15434 static struct snd_kcontrol_new alc861_base_mixer[] = {
15435 /* output mixer control */
15436 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15437 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15438 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15439 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15440 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15442 /*Input mixer control */
15443 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15444 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15445 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15446 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15447 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15448 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15449 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15450 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15451 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15452 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15457 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15458 /* output mixer control */
15459 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15463 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15465 /* Input mixer control */
15466 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15467 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15468 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15469 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15470 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15471 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15473 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15474 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15479 .name = "Channel Mode",
15480 .info = alc_ch_mode_info,
15481 .get = alc_ch_mode_get,
15482 .put = alc_ch_mode_put,
15483 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15488 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15489 /* output mixer control */
15490 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15492 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15497 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15498 /* output mixer control */
15499 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15500 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15501 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15502 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15503 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15505 /* Input mixer control */
15506 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15507 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15508 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15509 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15510 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15511 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15513 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15514 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15515 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15519 .name = "Channel Mode",
15520 .info = alc_ch_mode_info,
15521 .get = alc_ch_mode_get,
15522 .put = alc_ch_mode_put,
15523 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15528 static struct snd_kcontrol_new alc861_asus_mixer[] = {
15529 /* output mixer control */
15530 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15531 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15532 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15533 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15534 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15536 /* Input mixer control */
15537 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15538 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15539 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15540 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15541 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15542 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15543 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15544 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15545 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15546 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15549 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15550 .name = "Channel Mode",
15551 .info = alc_ch_mode_info,
15552 .get = alc_ch_mode_get,
15553 .put = alc_ch_mode_put,
15554 .private_value = ARRAY_SIZE(alc861_asus_modes),
15559 /* additional mixer */
15560 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15561 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15562 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15567 * generic initialization of ADC, input mixers and output mixers
15569 static struct hda_verb alc861_base_init_verbs[] = {
15571 * Unmute ADC0 and set the default input to mic-in
15573 /* port-A for surround (rear panel) */
15574 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15575 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15576 /* port-B for mic-in (rear panel) with vref */
15577 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15578 /* port-C for line-in (rear panel) */
15579 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15580 /* port-D for Front */
15581 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15582 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15583 /* port-E for HP out (front panel) */
15584 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15585 /* route front PCM to HP */
15586 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15587 /* port-F for mic-in (front panel) with vref */
15588 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15589 /* port-G for CLFE (rear panel) */
15590 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15591 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15592 /* port-H for side (rear panel) */
15593 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15594 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15596 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15597 /* route front mic to ADC1*/
15598 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15599 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15601 /* Unmute DAC0~3 & spdif out*/
15602 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15603 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15604 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15605 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15606 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15608 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15609 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15610 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15611 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15612 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15614 /* Unmute Stereo Mixer 15 */
15615 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15616 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15617 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15618 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15620 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15621 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15622 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15623 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15624 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15626 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15627 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15628 /* hp used DAC 3 (Front) */
15629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15635 static struct hda_verb alc861_threestack_init_verbs[] = {
15637 * Unmute ADC0 and set the default input to mic-in
15639 /* port-A for surround (rear panel) */
15640 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15641 /* port-B for mic-in (rear panel) with vref */
15642 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15643 /* port-C for line-in (rear panel) */
15644 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15645 /* port-D for Front */
15646 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15647 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15648 /* port-E for HP out (front panel) */
15649 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15650 /* route front PCM to HP */
15651 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15652 /* port-F for mic-in (front panel) with vref */
15653 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15654 /* port-G for CLFE (rear panel) */
15655 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15656 /* port-H for side (rear panel) */
15657 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15659 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15660 /* route front mic to ADC1*/
15661 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15662 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15663 /* Unmute DAC0~3 & spdif out*/
15664 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15665 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15666 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15667 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15668 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15670 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15671 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15672 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15673 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15674 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15676 /* Unmute Stereo Mixer 15 */
15677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15678 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15680 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15682 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15684 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15685 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15686 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15687 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15688 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15689 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15690 /* hp used DAC 3 (Front) */
15691 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15692 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15696 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15698 * Unmute ADC0 and set the default input to mic-in
15700 /* port-A for surround (rear panel) */
15701 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15702 /* port-B for mic-in (rear panel) with vref */
15703 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15704 /* port-C for line-in (rear panel) */
15705 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15706 /* port-D for Front */
15707 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15708 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15709 /* port-E for HP out (front panel) */
15710 /* this has to be set to VREF80 */
15711 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15712 /* route front PCM to HP */
15713 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15714 /* port-F for mic-in (front panel) with vref */
15715 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15716 /* port-G for CLFE (rear panel) */
15717 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15718 /* port-H for side (rear panel) */
15719 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15721 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15722 /* route front mic to ADC1*/
15723 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15724 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15725 /* Unmute DAC0~3 & spdif out*/
15726 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15727 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15728 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15729 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15730 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15732 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15733 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15734 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15735 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15736 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15738 /* Unmute Stereo Mixer 15 */
15739 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15740 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15744 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15745 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15746 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15747 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15749 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15751 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15752 /* hp used DAC 3 (Front) */
15753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15758 static struct hda_verb alc861_asus_init_verbs[] = {
15760 * Unmute ADC0 and set the default input to mic-in
15762 /* port-A for surround (rear panel)
15763 * according to codec#0 this is the HP jack
15765 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15766 /* route front PCM to HP */
15767 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15768 /* port-B for mic-in (rear panel) with vref */
15769 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15770 /* port-C for line-in (rear panel) */
15771 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15772 /* port-D for Front */
15773 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15774 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15775 /* port-E for HP out (front panel) */
15776 /* this has to be set to VREF80 */
15777 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15778 /* route front PCM to HP */
15779 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15780 /* port-F for mic-in (front panel) with vref */
15781 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15782 /* port-G for CLFE (rear panel) */
15783 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15784 /* port-H for side (rear panel) */
15785 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15787 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15788 /* route front mic to ADC1*/
15789 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15791 /* Unmute DAC0~3 & spdif out*/
15792 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15793 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15794 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15795 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15796 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15797 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15798 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15799 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15800 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15801 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15803 /* Unmute Stereo Mixer 15 */
15804 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15806 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15809 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15810 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15811 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15812 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15813 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15814 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15815 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15816 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15817 /* hp used DAC 3 (Front) */
15818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15819 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15823 /* additional init verbs for ASUS laptops */
15824 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15825 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15826 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15831 * generic initialization of ADC, input mixers and output mixers
15833 static struct hda_verb alc861_auto_init_verbs[] = {
15835 * Unmute ADC0 and set the default input to mic-in
15837 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15838 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15840 /* Unmute DAC0~3 & spdif out*/
15841 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15842 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15843 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15844 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15845 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15847 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15848 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15849 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15850 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15851 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15853 /* Unmute Stereo Mixer 15 */
15854 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15857 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15859 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15860 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15861 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15862 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15863 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15864 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15866 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15868 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15869 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15870 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15871 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15872 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15873 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15874 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15875 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15877 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15882 static struct hda_verb alc861_toshiba_init_verbs[] = {
15883 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15888 /* toggle speaker-output according to the hp-jack state */
15889 static void alc861_toshiba_automute(struct hda_codec *codec)
15891 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15893 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15894 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15895 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15896 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15899 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15902 if ((res >> 26) == ALC880_HP_EVENT)
15903 alc861_toshiba_automute(codec);
15906 /* pcm configuration: identical with ALC880 */
15907 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15908 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15909 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15910 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15913 #define ALC861_DIGOUT_NID 0x07
15915 static struct hda_channel_mode alc861_8ch_modes[1] = {
15919 static hda_nid_t alc861_dac_nids[4] = {
15920 /* front, surround, clfe, side */
15921 0x03, 0x06, 0x05, 0x04
15924 static hda_nid_t alc660_dac_nids[3] = {
15925 /* front, clfe, surround */
15929 static hda_nid_t alc861_adc_nids[1] = {
15934 static struct hda_input_mux alc861_capture_source = {
15938 { "Front Mic", 0x3 },
15945 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15947 struct alc_spec *spec = codec->spec;
15948 hda_nid_t mix, srcs[5];
15951 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15953 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15956 for (i = 0; i < num; i++) {
15958 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15959 if (type != AC_WID_AUD_OUT)
15961 for (j = 0; j < spec->multiout.num_dacs; j++)
15962 if (spec->multiout.dac_nids[j] == srcs[i])
15964 if (j >= spec->multiout.num_dacs)
15970 /* fill in the dac_nids table from the parsed pin configuration */
15971 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15972 const struct auto_pin_cfg *cfg)
15974 struct alc_spec *spec = codec->spec;
15976 hda_nid_t nid, dac;
15978 spec->multiout.dac_nids = spec->private_dac_nids;
15979 for (i = 0; i < cfg->line_outs; i++) {
15980 nid = cfg->line_out_pins[i];
15981 dac = alc861_look_for_dac(codec, nid);
15984 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
15989 static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15990 hda_nid_t nid, int idx, unsigned int chs)
15992 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
15993 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15996 #define alc861_create_out_sw(codec, pfx, nid, chs) \
15997 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15999 /* add playback controls from the parsed DAC table */
16000 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16001 const struct auto_pin_cfg *cfg)
16003 struct alc_spec *spec = codec->spec;
16004 static const char *chname[4] = {
16005 "Front", "Surround", NULL /*CLFE*/, "Side"
16007 const char *pfx = alc_get_line_out_pfx(cfg, true);
16011 for (i = 0; i < cfg->line_outs; i++) {
16012 nid = spec->multiout.dac_nids[i];
16015 if (!pfx && i == 2) {
16017 err = alc861_create_out_sw(codec, "Center", nid, 1);
16020 err = alc861_create_out_sw(codec, "LFE", nid, 2);
16024 const char *name = pfx;
16027 err = __alc861_create_out_sw(codec, name, nid, i, 3);
16035 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16037 struct alc_spec *spec = codec->spec;
16044 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16045 nid = alc861_look_for_dac(codec, pin);
16047 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16050 spec->multiout.hp_nid = nid;
16056 /* create playback/capture controls for input pins */
16057 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16058 const struct auto_pin_cfg *cfg)
16060 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16063 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16065 int pin_type, hda_nid_t dac)
16067 hda_nid_t mix, srcs[5];
16070 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16072 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16074 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16076 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16079 for (i = 0; i < num; i++) {
16081 if (srcs[i] == dac || srcs[i] == 0x15)
16082 mute = AMP_IN_UNMUTE(i);
16084 mute = AMP_IN_MUTE(i);
16085 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16090 static void alc861_auto_init_multi_out(struct hda_codec *codec)
16092 struct alc_spec *spec = codec->spec;
16095 for (i = 0; i < spec->autocfg.line_outs; i++) {
16096 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16097 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16099 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16100 spec->multiout.dac_nids[i]);
16104 static void alc861_auto_init_hp_out(struct hda_codec *codec)
16106 struct alc_spec *spec = codec->spec;
16108 if (spec->autocfg.hp_outs)
16109 alc861_auto_set_output_and_unmute(codec,
16110 spec->autocfg.hp_pins[0],
16112 spec->multiout.hp_nid);
16113 if (spec->autocfg.speaker_outs)
16114 alc861_auto_set_output_and_unmute(codec,
16115 spec->autocfg.speaker_pins[0],
16117 spec->multiout.dac_nids[0]);
16120 static void alc861_auto_init_analog_input(struct hda_codec *codec)
16122 struct alc_spec *spec = codec->spec;
16123 struct auto_pin_cfg *cfg = &spec->autocfg;
16126 for (i = 0; i < cfg->num_inputs; i++) {
16127 hda_nid_t nid = cfg->inputs[i].pin;
16128 if (nid >= 0x0c && nid <= 0x11)
16129 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16133 /* parse the BIOS configuration and set up the alc_spec */
16134 /* return 1 if successful, 0 if the proper config is not found,
16135 * or a negative error code
16137 static int alc861_parse_auto_config(struct hda_codec *codec)
16139 struct alc_spec *spec = codec->spec;
16141 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16143 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16147 if (!spec->autocfg.line_outs)
16148 return 0; /* can't find valid BIOS pin config */
16150 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16153 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16156 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16159 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16163 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16165 alc_auto_parse_digital(codec);
16167 if (spec->kctls.list)
16168 add_mixer(spec, spec->kctls.list);
16170 add_verb(spec, alc861_auto_init_verbs);
16172 spec->num_mux_defs = 1;
16173 spec->input_mux = &spec->private_imux[0];
16175 spec->adc_nids = alc861_adc_nids;
16176 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16177 set_capture_mixer(codec);
16179 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16184 /* additional initialization for auto-configuration model */
16185 static void alc861_auto_init(struct hda_codec *codec)
16187 struct alc_spec *spec = codec->spec;
16188 alc861_auto_init_multi_out(codec);
16189 alc861_auto_init_hp_out(codec);
16190 alc861_auto_init_analog_input(codec);
16191 alc_auto_init_digital(codec);
16192 if (spec->unsol_event)
16193 alc_inithook(codec);
16196 #ifdef CONFIG_SND_HDA_POWER_SAVE
16197 static struct hda_amp_list alc861_loopbacks[] = {
16198 { 0x15, HDA_INPUT, 0 },
16199 { 0x15, HDA_INPUT, 1 },
16200 { 0x15, HDA_INPUT, 2 },
16201 { 0x15, HDA_INPUT, 3 },
16208 * configuration and preset
16210 static const char *alc861_models[ALC861_MODEL_LAST] = {
16211 [ALC861_3ST] = "3stack",
16212 [ALC660_3ST] = "3stack-660",
16213 [ALC861_3ST_DIG] = "3stack-dig",
16214 [ALC861_6ST_DIG] = "6stack-dig",
16215 [ALC861_UNIWILL_M31] = "uniwill-m31",
16216 [ALC861_TOSHIBA] = "toshiba",
16217 [ALC861_ASUS] = "asus",
16218 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16219 [ALC861_AUTO] = "auto",
16222 static struct snd_pci_quirk alc861_cfg_tbl[] = {
16223 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16224 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16225 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16226 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16227 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16228 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16229 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16230 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16231 * Any other models that need this preset?
16233 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16234 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16235 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16236 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16237 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16238 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16239 /* FIXME: the below seems conflict */
16240 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16241 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16242 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16246 static struct alc_config_preset alc861_presets[] = {
16248 .mixers = { alc861_3ST_mixer },
16249 .init_verbs = { alc861_threestack_init_verbs },
16250 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16251 .dac_nids = alc861_dac_nids,
16252 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16253 .channel_mode = alc861_threestack_modes,
16255 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16256 .adc_nids = alc861_adc_nids,
16257 .input_mux = &alc861_capture_source,
16259 [ALC861_3ST_DIG] = {
16260 .mixers = { alc861_base_mixer },
16261 .init_verbs = { alc861_threestack_init_verbs },
16262 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16263 .dac_nids = alc861_dac_nids,
16264 .dig_out_nid = ALC861_DIGOUT_NID,
16265 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16266 .channel_mode = alc861_threestack_modes,
16268 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16269 .adc_nids = alc861_adc_nids,
16270 .input_mux = &alc861_capture_source,
16272 [ALC861_6ST_DIG] = {
16273 .mixers = { alc861_base_mixer },
16274 .init_verbs = { alc861_base_init_verbs },
16275 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16276 .dac_nids = alc861_dac_nids,
16277 .dig_out_nid = ALC861_DIGOUT_NID,
16278 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16279 .channel_mode = alc861_8ch_modes,
16280 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16281 .adc_nids = alc861_adc_nids,
16282 .input_mux = &alc861_capture_source,
16285 .mixers = { alc861_3ST_mixer },
16286 .init_verbs = { alc861_threestack_init_verbs },
16287 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16288 .dac_nids = alc660_dac_nids,
16289 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16290 .channel_mode = alc861_threestack_modes,
16292 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16293 .adc_nids = alc861_adc_nids,
16294 .input_mux = &alc861_capture_source,
16296 [ALC861_UNIWILL_M31] = {
16297 .mixers = { alc861_uniwill_m31_mixer },
16298 .init_verbs = { alc861_uniwill_m31_init_verbs },
16299 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16300 .dac_nids = alc861_dac_nids,
16301 .dig_out_nid = ALC861_DIGOUT_NID,
16302 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16303 .channel_mode = alc861_uniwill_m31_modes,
16305 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16306 .adc_nids = alc861_adc_nids,
16307 .input_mux = &alc861_capture_source,
16309 [ALC861_TOSHIBA] = {
16310 .mixers = { alc861_toshiba_mixer },
16311 .init_verbs = { alc861_base_init_verbs,
16312 alc861_toshiba_init_verbs },
16313 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16314 .dac_nids = alc861_dac_nids,
16315 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16316 .channel_mode = alc883_3ST_2ch_modes,
16317 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16318 .adc_nids = alc861_adc_nids,
16319 .input_mux = &alc861_capture_source,
16320 .unsol_event = alc861_toshiba_unsol_event,
16321 .init_hook = alc861_toshiba_automute,
16324 .mixers = { alc861_asus_mixer },
16325 .init_verbs = { alc861_asus_init_verbs },
16326 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16327 .dac_nids = alc861_dac_nids,
16328 .dig_out_nid = ALC861_DIGOUT_NID,
16329 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16330 .channel_mode = alc861_asus_modes,
16333 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16334 .adc_nids = alc861_adc_nids,
16335 .input_mux = &alc861_capture_source,
16337 [ALC861_ASUS_LAPTOP] = {
16338 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16339 .init_verbs = { alc861_asus_init_verbs,
16340 alc861_asus_laptop_init_verbs },
16341 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16342 .dac_nids = alc861_dac_nids,
16343 .dig_out_nid = ALC861_DIGOUT_NID,
16344 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16345 .channel_mode = alc883_3ST_2ch_modes,
16347 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16348 .adc_nids = alc861_adc_nids,
16349 .input_mux = &alc861_capture_source,
16353 /* Pin config fixes */
16355 PINFIX_FSC_AMILO_PI1505,
16358 static const struct alc_fixup alc861_fixups[] = {
16359 [PINFIX_FSC_AMILO_PI1505] = {
16360 .type = ALC_FIXUP_PINS,
16361 .v.pins = (const struct alc_pincfg[]) {
16362 { 0x0b, 0x0221101f }, /* HP */
16363 { 0x0f, 0x90170310 }, /* speaker */
16369 static struct snd_pci_quirk alc861_fixup_tbl[] = {
16370 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16374 static int patch_alc861(struct hda_codec *codec)
16376 struct alc_spec *spec;
16380 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16384 codec->spec = spec;
16386 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16390 if (board_config < 0) {
16391 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16393 board_config = ALC861_AUTO;
16396 if (board_config == ALC861_AUTO) {
16397 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16398 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16401 if (board_config == ALC861_AUTO) {
16402 /* automatic parse from the BIOS config */
16403 err = alc861_parse_auto_config(codec);
16409 "hda_codec: Cannot set up configuration "
16410 "from BIOS. Using base mode...\n");
16411 board_config = ALC861_3ST_DIG;
16415 err = snd_hda_attach_beep_device(codec, 0x23);
16421 if (board_config != ALC861_AUTO)
16422 setup_preset(codec, &alc861_presets[board_config]);
16424 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16425 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16427 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16428 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16430 if (!spec->cap_mixer)
16431 set_capture_mixer(codec);
16432 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16434 spec->vmaster_nid = 0x03;
16436 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16438 codec->patch_ops = alc_patch_ops;
16439 if (board_config == ALC861_AUTO) {
16440 spec->init_hook = alc861_auto_init;
16441 #ifdef CONFIG_SND_HDA_POWER_SAVE
16442 spec->power_hook = alc_power_eapd;
16445 #ifdef CONFIG_SND_HDA_POWER_SAVE
16446 if (!spec->loopback.amplist)
16447 spec->loopback.amplist = alc861_loopbacks;
16454 * ALC861-VD support
16458 * In addition, an independent DAC
16460 #define ALC861VD_DIGOUT_NID 0x06
16462 static hda_nid_t alc861vd_dac_nids[4] = {
16463 /* front, surr, clfe, side surr */
16464 0x02, 0x03, 0x04, 0x05
16467 /* dac_nids for ALC660vd are in a different order - according to
16468 * Realtek's driver.
16469 * This should probably result in a different mixer for 6stack models
16470 * of ALC660vd codecs, but for now there is only 3stack mixer
16471 * - and it is the same as in 861vd.
16472 * adc_nids in ALC660vd are (is) the same as in 861vd
16474 static hda_nid_t alc660vd_dac_nids[3] = {
16475 /* front, rear, clfe, rear_surr */
16479 static hda_nid_t alc861vd_adc_nids[1] = {
16484 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16487 /* FIXME: should be a matrix-type input source selection */
16488 static struct hda_input_mux alc861vd_capture_source = {
16492 { "Front Mic", 0x1 },
16498 static struct hda_input_mux alc861vd_dallas_capture_source = {
16502 { "Internal Mic", 0x1 },
16506 static struct hda_input_mux alc861vd_hp_capture_source = {
16509 { "Front Mic", 0x0 },
16510 { "ATAPI Mic", 0x1 },
16517 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16524 static struct hda_verb alc861vd_6stack_ch6_init[] = {
16525 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16526 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16527 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16528 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16535 static struct hda_verb alc861vd_6stack_ch8_init[] = {
16536 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16537 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16538 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16539 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16543 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16544 { 6, alc861vd_6stack_ch6_init },
16545 { 8, alc861vd_6stack_ch8_init },
16548 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16551 .name = "Channel Mode",
16552 .info = alc_ch_mode_info,
16553 .get = alc_ch_mode_get,
16554 .put = alc_ch_mode_put,
16559 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16560 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16562 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16563 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16564 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16566 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16567 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16569 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16571 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16573 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16574 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16576 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16577 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16581 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16582 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16583 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16585 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16586 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16587 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16589 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16590 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16592 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16593 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16598 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16599 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16600 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16602 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16604 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16605 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16606 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16608 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16609 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16610 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16612 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16613 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16615 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16616 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16621 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16622 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16623 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16624 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16626 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16628 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16632 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16633 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16634 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16642 /* Pin assignment: Speaker=0x14, HP = 0x15,
16643 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16645 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16646 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16647 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16648 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16649 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16650 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16653 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16654 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16655 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16659 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16660 * Front Mic=0x18, ATAPI Mic = 0x19,
16662 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16663 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16664 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16665 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16666 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16667 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16668 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16669 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16670 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16676 * generic initialization of ADC, input mixers and output mixers
16678 static struct hda_verb alc861vd_volume_init_verbs[] = {
16680 * Unmute ADC0 and set the default input to mic-in
16682 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16685 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16686 * the analog-loopback mixer widget
16688 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16695 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16696 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16697 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16702 * Set up output mixers (0x02 - 0x05)
16704 /* set vol=0 to output mixers */
16705 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16706 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16707 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16708 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16710 /* set up input amps for analog loopback */
16711 /* Amp Indices: DAC = 0, mixer = 1 */
16712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16713 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16714 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16715 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16716 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16717 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16718 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16719 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16725 * 3-stack pin configuration:
16726 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16728 static struct hda_verb alc861vd_3stack_init_verbs[] = {
16730 * Set pin mode and muting
16732 /* set front pin widgets 0x14 for output */
16733 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16735 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16737 /* Mic (rear) pin: input vref at 80% */
16738 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16739 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16740 /* Front Mic pin: input vref at 80% */
16741 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16742 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16743 /* Line In pin: input */
16744 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16745 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16746 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16747 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16748 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16749 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16750 /* CD pin widget for input */
16751 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16757 * 6-stack pin configuration:
16759 static struct hda_verb alc861vd_6stack_init_verbs[] = {
16761 * Set pin mode and muting
16763 /* set front pin widgets 0x14 for output */
16764 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16766 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16768 /* Rear Pin: output 1 (0x0d) */
16769 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16771 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16772 /* CLFE Pin: output 2 (0x0e) */
16773 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16775 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16776 /* Side Pin: output 3 (0x0f) */
16777 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16778 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16779 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16781 /* Mic (rear) pin: input vref at 80% */
16782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16784 /* Front Mic pin: input vref at 80% */
16785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16787 /* Line In pin: input */
16788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16790 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16791 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16792 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16793 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16794 /* CD pin widget for input */
16795 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16800 static struct hda_verb alc861vd_eapd_verbs[] = {
16801 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16805 static struct hda_verb alc660vd_eapd_verbs[] = {
16806 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16807 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16811 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16814 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16815 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16816 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16820 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16822 struct alc_spec *spec = codec->spec;
16823 spec->autocfg.hp_pins[0] = 0x1b;
16824 spec->autocfg.speaker_pins[0] = 0x14;
16827 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16829 alc_automute_amp(codec);
16830 alc88x_simple_mic_automute(codec);
16833 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16836 switch (res >> 26) {
16837 case ALC880_MIC_EVENT:
16838 alc88x_simple_mic_automute(codec);
16841 alc_automute_amp_unsol_event(codec, res);
16846 static struct hda_verb alc861vd_dallas_verbs[] = {
16847 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16848 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16849 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16850 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16852 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16853 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16854 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16855 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16856 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16857 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16858 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16859 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16861 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16862 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16864 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16865 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16866 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16867 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16868 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16870 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16871 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16872 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16873 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16874 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16875 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16877 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16880 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16882 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16884 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16885 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16886 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16891 /* toggle speaker-output according to the hp-jack state */
16892 static void alc861vd_dallas_setup(struct hda_codec *codec)
16894 struct alc_spec *spec = codec->spec;
16896 spec->autocfg.hp_pins[0] = 0x15;
16897 spec->autocfg.speaker_pins[0] = 0x14;
16900 #ifdef CONFIG_SND_HDA_POWER_SAVE
16901 #define alc861vd_loopbacks alc880_loopbacks
16904 /* pcm configuration: identical with ALC880 */
16905 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16906 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16907 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16908 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16911 * configuration and preset
16913 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16914 [ALC660VD_3ST] = "3stack-660",
16915 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16916 [ALC660VD_ASUS_V1S] = "asus-v1s",
16917 [ALC861VD_3ST] = "3stack",
16918 [ALC861VD_3ST_DIG] = "3stack-digout",
16919 [ALC861VD_6ST_DIG] = "6stack-digout",
16920 [ALC861VD_LENOVO] = "lenovo",
16921 [ALC861VD_DALLAS] = "dallas",
16922 [ALC861VD_HP] = "hp",
16923 [ALC861VD_AUTO] = "auto",
16926 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16927 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16928 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16929 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16930 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16931 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16932 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16933 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16934 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16935 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16936 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16937 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16938 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16939 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16940 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16941 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16945 static struct alc_config_preset alc861vd_presets[] = {
16947 .mixers = { alc861vd_3st_mixer },
16948 .init_verbs = { alc861vd_volume_init_verbs,
16949 alc861vd_3stack_init_verbs },
16950 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16951 .dac_nids = alc660vd_dac_nids,
16952 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16953 .channel_mode = alc861vd_3stack_2ch_modes,
16954 .input_mux = &alc861vd_capture_source,
16956 [ALC660VD_3ST_DIG] = {
16957 .mixers = { alc861vd_3st_mixer },
16958 .init_verbs = { alc861vd_volume_init_verbs,
16959 alc861vd_3stack_init_verbs },
16960 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16961 .dac_nids = alc660vd_dac_nids,
16962 .dig_out_nid = ALC861VD_DIGOUT_NID,
16963 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16964 .channel_mode = alc861vd_3stack_2ch_modes,
16965 .input_mux = &alc861vd_capture_source,
16968 .mixers = { alc861vd_3st_mixer },
16969 .init_verbs = { alc861vd_volume_init_verbs,
16970 alc861vd_3stack_init_verbs },
16971 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16972 .dac_nids = alc861vd_dac_nids,
16973 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16974 .channel_mode = alc861vd_3stack_2ch_modes,
16975 .input_mux = &alc861vd_capture_source,
16977 [ALC861VD_3ST_DIG] = {
16978 .mixers = { alc861vd_3st_mixer },
16979 .init_verbs = { alc861vd_volume_init_verbs,
16980 alc861vd_3stack_init_verbs },
16981 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16982 .dac_nids = alc861vd_dac_nids,
16983 .dig_out_nid = ALC861VD_DIGOUT_NID,
16984 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16985 .channel_mode = alc861vd_3stack_2ch_modes,
16986 .input_mux = &alc861vd_capture_source,
16988 [ALC861VD_6ST_DIG] = {
16989 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16990 .init_verbs = { alc861vd_volume_init_verbs,
16991 alc861vd_6stack_init_verbs },
16992 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16993 .dac_nids = alc861vd_dac_nids,
16994 .dig_out_nid = ALC861VD_DIGOUT_NID,
16995 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16996 .channel_mode = alc861vd_6stack_modes,
16997 .input_mux = &alc861vd_capture_source,
16999 [ALC861VD_LENOVO] = {
17000 .mixers = { alc861vd_lenovo_mixer },
17001 .init_verbs = { alc861vd_volume_init_verbs,
17002 alc861vd_3stack_init_verbs,
17003 alc861vd_eapd_verbs,
17004 alc861vd_lenovo_unsol_verbs },
17005 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17006 .dac_nids = alc660vd_dac_nids,
17007 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17008 .channel_mode = alc861vd_3stack_2ch_modes,
17009 .input_mux = &alc861vd_capture_source,
17010 .unsol_event = alc861vd_lenovo_unsol_event,
17011 .setup = alc861vd_lenovo_setup,
17012 .init_hook = alc861vd_lenovo_init_hook,
17014 [ALC861VD_DALLAS] = {
17015 .mixers = { alc861vd_dallas_mixer },
17016 .init_verbs = { alc861vd_dallas_verbs },
17017 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17018 .dac_nids = alc861vd_dac_nids,
17019 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17020 .channel_mode = alc861vd_3stack_2ch_modes,
17021 .input_mux = &alc861vd_dallas_capture_source,
17022 .unsol_event = alc_automute_amp_unsol_event,
17023 .setup = alc861vd_dallas_setup,
17024 .init_hook = alc_automute_amp,
17027 .mixers = { alc861vd_hp_mixer },
17028 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17029 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17030 .dac_nids = alc861vd_dac_nids,
17031 .dig_out_nid = ALC861VD_DIGOUT_NID,
17032 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17033 .channel_mode = alc861vd_3stack_2ch_modes,
17034 .input_mux = &alc861vd_hp_capture_source,
17035 .unsol_event = alc_automute_amp_unsol_event,
17036 .setup = alc861vd_dallas_setup,
17037 .init_hook = alc_automute_amp,
17039 [ALC660VD_ASUS_V1S] = {
17040 .mixers = { alc861vd_lenovo_mixer },
17041 .init_verbs = { alc861vd_volume_init_verbs,
17042 alc861vd_3stack_init_verbs,
17043 alc861vd_eapd_verbs,
17044 alc861vd_lenovo_unsol_verbs },
17045 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17046 .dac_nids = alc660vd_dac_nids,
17047 .dig_out_nid = ALC861VD_DIGOUT_NID,
17048 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17049 .channel_mode = alc861vd_3stack_2ch_modes,
17050 .input_mux = &alc861vd_capture_source,
17051 .unsol_event = alc861vd_lenovo_unsol_event,
17052 .setup = alc861vd_lenovo_setup,
17053 .init_hook = alc861vd_lenovo_init_hook,
17058 * BIOS auto configuration
17060 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17061 const struct auto_pin_cfg *cfg)
17063 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17067 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17068 hda_nid_t nid, int pin_type, int dac_idx)
17070 alc_set_pin_output(codec, nid, pin_type);
17073 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17075 struct alc_spec *spec = codec->spec;
17078 for (i = 0; i <= HDA_SIDE; i++) {
17079 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17080 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17082 alc861vd_auto_set_output_and_unmute(codec, nid,
17088 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17090 struct alc_spec *spec = codec->spec;
17093 pin = spec->autocfg.hp_pins[0];
17094 if (pin) /* connect to front and use dac 0 */
17095 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17096 pin = spec->autocfg.speaker_pins[0];
17098 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17101 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17103 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17105 struct alc_spec *spec = codec->spec;
17106 struct auto_pin_cfg *cfg = &spec->autocfg;
17109 for (i = 0; i < cfg->num_inputs; i++) {
17110 hda_nid_t nid = cfg->inputs[i].pin;
17111 if (alc_is_input_pin(codec, nid)) {
17112 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17113 if (nid != ALC861VD_PIN_CD_NID &&
17114 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17115 snd_hda_codec_write(codec, nid, 0,
17116 AC_VERB_SET_AMP_GAIN_MUTE,
17122 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
17124 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17125 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17127 /* add playback controls from the parsed DAC table */
17128 /* Based on ALC880 version. But ALC861VD has separate,
17129 * different NIDs for mute/unmute switch and volume control */
17130 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17131 const struct auto_pin_cfg *cfg)
17133 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
17134 const char *pfx = alc_get_line_out_pfx(cfg, true);
17135 hda_nid_t nid_v, nid_s;
17138 for (i = 0; i < cfg->line_outs; i++) {
17139 if (!spec->multiout.dac_nids[i])
17141 nid_v = alc861vd_idx_to_mixer_vol(
17143 spec->multiout.dac_nids[i]));
17144 nid_s = alc861vd_idx_to_mixer_switch(
17146 spec->multiout.dac_nids[i]));
17148 if (!pfx && i == 2) {
17150 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17152 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17156 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17158 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17162 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17164 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17168 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17170 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17175 const char *name = pfx;
17178 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17180 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17184 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17186 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17195 /* add playback controls for speaker and HP outputs */
17196 /* Based on ALC880 version. But ALC861VD has separate,
17197 * different NIDs for mute/unmute switch and volume control */
17198 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17199 hda_nid_t pin, const char *pfx)
17201 hda_nid_t nid_v, nid_s;
17207 if (alc880_is_fixed_pin(pin)) {
17208 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17209 /* specify the DAC as the extra output */
17210 if (!spec->multiout.hp_nid)
17211 spec->multiout.hp_nid = nid_v;
17213 spec->multiout.extra_out_nid[0] = nid_v;
17214 /* control HP volume/switch on the output mixer amp */
17215 nid_v = alc861vd_idx_to_mixer_vol(
17216 alc880_fixed_pin_idx(pin));
17217 nid_s = alc861vd_idx_to_mixer_switch(
17218 alc880_fixed_pin_idx(pin));
17220 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17221 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17224 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17225 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17228 } else if (alc880_is_multi_pin(pin)) {
17229 /* set manual connection */
17230 /* we have only a switch on HP-out PIN */
17231 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17232 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17239 /* parse the BIOS configuration and set up the alc_spec
17240 * return 1 if successful, 0 if the proper config is not found,
17241 * or a negative error code
17242 * Based on ALC880 version - had to change it to override
17243 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17244 static int alc861vd_parse_auto_config(struct hda_codec *codec)
17246 struct alc_spec *spec = codec->spec;
17248 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17250 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17254 if (!spec->autocfg.line_outs)
17255 return 0; /* can't find valid BIOS pin config */
17257 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17260 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17263 err = alc861vd_auto_create_extra_out(spec,
17264 spec->autocfg.speaker_pins[0],
17268 err = alc861vd_auto_create_extra_out(spec,
17269 spec->autocfg.hp_pins[0],
17273 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17277 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17279 alc_auto_parse_digital(codec);
17281 if (spec->kctls.list)
17282 add_mixer(spec, spec->kctls.list);
17284 add_verb(spec, alc861vd_volume_init_verbs);
17286 spec->num_mux_defs = 1;
17287 spec->input_mux = &spec->private_imux[0];
17289 err = alc_auto_add_mic_boost(codec);
17293 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17298 /* additional initialization for auto-configuration model */
17299 static void alc861vd_auto_init(struct hda_codec *codec)
17301 struct alc_spec *spec = codec->spec;
17302 alc861vd_auto_init_multi_out(codec);
17303 alc861vd_auto_init_hp_out(codec);
17304 alc861vd_auto_init_analog_input(codec);
17305 alc861vd_auto_init_input_src(codec);
17306 alc_auto_init_digital(codec);
17307 if (spec->unsol_event)
17308 alc_inithook(codec);
17312 ALC660VD_FIX_ASUS_GPIO1
17316 static const struct alc_fixup alc861vd_fixups[] = {
17317 [ALC660VD_FIX_ASUS_GPIO1] = {
17318 .type = ALC_FIXUP_VERBS,
17319 .v.verbs = (const struct hda_verb[]) {
17320 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17321 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17322 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17328 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17329 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17333 static int patch_alc861vd(struct hda_codec *codec)
17335 struct alc_spec *spec;
17336 int err, board_config;
17338 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17342 codec->spec = spec;
17344 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17348 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17349 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17351 board_config = ALC861VD_AUTO;
17354 if (board_config == ALC861VD_AUTO) {
17355 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17356 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17359 if (board_config == ALC861VD_AUTO) {
17360 /* automatic parse from the BIOS config */
17361 err = alc861vd_parse_auto_config(codec);
17367 "hda_codec: Cannot set up configuration "
17368 "from BIOS. Using base mode...\n");
17369 board_config = ALC861VD_3ST;
17373 err = snd_hda_attach_beep_device(codec, 0x23);
17379 if (board_config != ALC861VD_AUTO)
17380 setup_preset(codec, &alc861vd_presets[board_config]);
17382 if (codec->vendor_id == 0x10ec0660) {
17383 /* always turn on EAPD */
17384 add_verb(spec, alc660vd_eapd_verbs);
17387 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17388 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17390 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17391 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17393 if (!spec->adc_nids) {
17394 spec->adc_nids = alc861vd_adc_nids;
17395 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17397 if (!spec->capsrc_nids)
17398 spec->capsrc_nids = alc861vd_capsrc_nids;
17400 set_capture_mixer(codec);
17401 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17403 spec->vmaster_nid = 0x02;
17405 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17407 codec->patch_ops = alc_patch_ops;
17409 if (board_config == ALC861VD_AUTO)
17410 spec->init_hook = alc861vd_auto_init;
17411 #ifdef CONFIG_SND_HDA_POWER_SAVE
17412 if (!spec->loopback.amplist)
17413 spec->loopback.amplist = alc861vd_loopbacks;
17422 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17423 * configuration. Each pin widget can choose any input DACs and a mixer.
17424 * Each ADC is connected from a mixer of all inputs. This makes possible
17425 * 6-channel independent captures.
17427 * In addition, an independent DAC for the multi-playback (not used in this
17430 #define ALC662_DIGOUT_NID 0x06
17431 #define ALC662_DIGIN_NID 0x0a
17433 static hda_nid_t alc662_dac_nids[4] = {
17434 /* front, rear, clfe, rear_surr */
17438 static hda_nid_t alc272_dac_nids[2] = {
17442 static hda_nid_t alc662_adc_nids[2] = {
17447 static hda_nid_t alc272_adc_nids[1] = {
17452 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17453 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17457 /* FIXME: should be a matrix-type input source selection */
17458 static struct hda_input_mux alc662_capture_source = {
17462 { "Front Mic", 0x1 },
17468 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17476 static struct hda_input_mux alc663_capture_source = {
17480 { "Front Mic", 0x1 },
17485 #if 0 /* set to 1 for testing other input sources below */
17486 static struct hda_input_mux alc272_nc10_capture_source = {
17489 { "Autoselect Mic", 0x0 },
17490 { "Internal Mic", 0x1 },
17491 { "In-0x02", 0x2 },
17492 { "In-0x03", 0x3 },
17493 { "In-0x04", 0x4 },
17494 { "In-0x05", 0x5 },
17495 { "In-0x06", 0x6 },
17496 { "In-0x07", 0x7 },
17497 { "In-0x08", 0x8 },
17498 { "In-0x09", 0x9 },
17499 { "In-0x0a", 0x0a },
17500 { "In-0x0b", 0x0b },
17501 { "In-0x0c", 0x0c },
17502 { "In-0x0d", 0x0d },
17503 { "In-0x0e", 0x0e },
17504 { "In-0x0f", 0x0f },
17512 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17519 static struct hda_verb alc662_3ST_ch2_init[] = {
17520 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17521 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17522 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17523 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17530 static struct hda_verb alc662_3ST_ch6_init[] = {
17531 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17532 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17533 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17534 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17535 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17536 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17540 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17541 { 2, alc662_3ST_ch2_init },
17542 { 6, alc662_3ST_ch6_init },
17548 static struct hda_verb alc662_sixstack_ch6_init[] = {
17549 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17550 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17551 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17558 static struct hda_verb alc662_sixstack_ch8_init[] = {
17559 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17560 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17561 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17565 static struct hda_channel_mode alc662_5stack_modes[2] = {
17566 { 2, alc662_sixstack_ch6_init },
17567 { 6, alc662_sixstack_ch8_init },
17570 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17571 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17574 static struct snd_kcontrol_new alc662_base_mixer[] = {
17575 /* output mixer control */
17576 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17577 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17578 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17579 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17580 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17581 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17582 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17583 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17586 /*Input mixer control */
17587 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17588 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17589 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17590 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17591 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17592 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17593 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17594 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17598 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17599 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17600 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17601 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17602 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17603 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17604 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17605 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17606 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17607 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17608 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17609 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17613 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17614 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17615 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17616 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17617 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17618 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17619 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17620 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17621 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17622 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17623 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17624 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17625 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17626 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17629 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17630 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17634 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17635 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17636 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17637 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17638 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17639 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17640 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17641 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17643 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17647 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17648 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17649 ALC262_HIPPO_MASTER_SWITCH,
17651 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17655 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17656 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17657 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17661 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17662 ALC262_HIPPO_MASTER_SWITCH,
17663 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17664 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17665 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17666 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17667 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17671 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17675 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17676 .ops = &snd_hda_bind_vol,
17678 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17679 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17684 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17685 .ops = &snd_hda_bind_sw,
17687 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17688 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17693 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
17694 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17695 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17696 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17697 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17701 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17702 .ops = &snd_hda_bind_sw,
17704 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17705 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17706 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17711 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17712 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17713 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17716 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17717 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17722 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17723 .ops = &snd_hda_bind_sw,
17725 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17726 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17727 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17732 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17733 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17734 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17735 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17736 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17737 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17738 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17742 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17743 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17744 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17745 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17748 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17749 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17753 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17754 .ops = &snd_hda_bind_vol,
17756 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17757 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17762 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17763 .ops = &snd_hda_bind_sw,
17765 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17766 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17771 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17772 HDA_BIND_VOL("Master Playback Volume",
17773 &alc663_asus_two_bind_master_vol),
17774 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17775 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17776 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17777 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17778 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17782 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17783 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17784 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17785 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17786 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17788 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17792 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17793 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17794 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17795 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17796 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17797 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17799 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17800 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17801 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17802 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17806 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17807 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17808 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17809 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17813 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17814 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17820 static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17821 .ops = &snd_hda_bind_sw,
17823 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17824 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17825 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17826 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17827 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17832 static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17833 .ops = &snd_hda_bind_sw,
17835 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17836 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17841 static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17842 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17843 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17844 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17845 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17846 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17847 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17848 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17849 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17850 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17854 static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17855 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17856 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17857 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17858 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17859 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17861 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17866 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17868 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17869 .name = "Channel Mode",
17870 .info = alc_ch_mode_info,
17871 .get = alc_ch_mode_get,
17872 .put = alc_ch_mode_put,
17877 static struct hda_verb alc662_init_verbs[] = {
17878 /* ADC: mute amp left and right */
17879 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17880 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17882 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17883 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17884 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17885 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17886 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17887 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17889 /* Front Pin: output 0 (0x0c) */
17890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17893 /* Rear Pin: output 1 (0x0d) */
17894 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17895 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17897 /* CLFE Pin: output 2 (0x0e) */
17898 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17899 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17901 /* Mic (rear) pin: input vref at 80% */
17902 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17903 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17904 /* Front Mic pin: input vref at 80% */
17905 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17906 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17907 /* Line In pin: input */
17908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17909 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17910 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17911 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17912 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17913 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17914 /* CD pin widget for input */
17915 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17917 /* FIXME: use matrix-type input source selection */
17918 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17920 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17921 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17923 /* always trun on EAPD */
17924 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17925 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17930 static struct hda_verb alc663_init_verbs[] = {
17931 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17932 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17933 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17934 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17935 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17936 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17940 static struct hda_verb alc272_init_verbs[] = {
17941 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17942 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17943 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17944 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17946 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17947 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17948 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17952 static struct hda_verb alc662_sue_init_verbs[] = {
17953 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17954 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17958 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17959 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17960 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17964 /* Set Unsolicited Event*/
17965 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17966 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17967 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17971 static struct hda_verb alc663_m51va_init_verbs[] = {
17972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17973 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17974 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17975 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17976 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17977 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17978 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17979 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17980 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17984 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17985 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17986 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17987 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17989 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17990 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17991 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17995 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17996 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17998 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17999 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18001 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18002 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18003 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18007 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
18008 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18009 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18010 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18012 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18013 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18014 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18018 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18019 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18020 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18021 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18022 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18023 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18024 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18025 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18027 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18028 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18029 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18030 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18034 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18035 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18036 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18037 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18038 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18039 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18041 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18043 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18044 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18045 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18046 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18050 static struct hda_verb alc663_g71v_init_verbs[] = {
18051 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18052 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18053 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18055 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18056 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18057 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18059 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18060 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18061 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18065 static struct hda_verb alc663_g50v_init_verbs[] = {
18066 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18067 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18068 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18070 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18071 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18075 static struct hda_verb alc662_ecs_init_verbs[] = {
18076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18077 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18078 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18079 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18083 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18084 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18085 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18086 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18087 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18088 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18089 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18090 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18091 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18092 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18093 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18094 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18098 static struct hda_verb alc272_dell_init_verbs[] = {
18099 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18100 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18101 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18102 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18103 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18104 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18105 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18106 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18107 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18108 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18109 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18113 static struct hda_verb alc663_mode7_init_verbs[] = {
18114 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18115 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18116 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18117 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18118 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18119 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18120 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18121 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18122 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18123 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18126 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18127 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18128 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18132 static struct hda_verb alc663_mode8_init_verbs[] = {
18133 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18134 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18136 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18137 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18138 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18139 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18140 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18141 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18142 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18143 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18146 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18147 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18148 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18152 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18153 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18154 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18158 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18159 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18160 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18164 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18166 unsigned int present;
18167 unsigned char bits;
18169 present = snd_hda_jack_detect(codec, 0x14);
18170 bits = present ? HDA_AMP_MUTE : 0;
18172 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18173 HDA_AMP_MUTE, bits);
18176 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18178 unsigned int present;
18179 unsigned char bits;
18181 present = snd_hda_jack_detect(codec, 0x1b);
18182 bits = present ? HDA_AMP_MUTE : 0;
18184 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18185 HDA_AMP_MUTE, bits);
18186 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18187 HDA_AMP_MUTE, bits);
18190 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18193 if ((res >> 26) == ALC880_HP_EVENT)
18194 alc662_lenovo_101e_all_automute(codec);
18195 if ((res >> 26) == ALC880_FRONT_EVENT)
18196 alc662_lenovo_101e_ispeaker_automute(codec);
18199 /* unsolicited event for HP jack sensing */
18200 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18203 if ((res >> 26) == ALC880_MIC_EVENT)
18204 alc_mic_automute(codec);
18206 alc262_hippo_unsol_event(codec, res);
18209 static void alc662_eeepc_setup(struct hda_codec *codec)
18211 struct alc_spec *spec = codec->spec;
18213 alc262_hippo1_setup(codec);
18214 spec->ext_mic.pin = 0x18;
18215 spec->ext_mic.mux_idx = 0;
18216 spec->int_mic.pin = 0x19;
18217 spec->int_mic.mux_idx = 1;
18218 spec->auto_mic = 1;
18221 static void alc662_eeepc_inithook(struct hda_codec *codec)
18223 alc262_hippo_automute(codec);
18224 alc_mic_automute(codec);
18227 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18229 struct alc_spec *spec = codec->spec;
18231 spec->autocfg.hp_pins[0] = 0x14;
18232 spec->autocfg.speaker_pins[0] = 0x1b;
18235 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18237 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18239 unsigned int present;
18240 unsigned char bits;
18242 present = snd_hda_jack_detect(codec, 0x21);
18243 bits = present ? HDA_AMP_MUTE : 0;
18244 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18245 HDA_AMP_MUTE, bits);
18246 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18247 HDA_AMP_MUTE, bits);
18250 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18252 unsigned int present;
18253 unsigned char bits;
18255 present = snd_hda_jack_detect(codec, 0x21);
18256 bits = present ? HDA_AMP_MUTE : 0;
18257 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18258 HDA_AMP_MUTE, bits);
18259 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18260 HDA_AMP_MUTE, bits);
18261 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18262 HDA_AMP_MUTE, bits);
18263 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18264 HDA_AMP_MUTE, bits);
18267 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18269 unsigned int present;
18270 unsigned char bits;
18272 present = snd_hda_jack_detect(codec, 0x15);
18273 bits = present ? HDA_AMP_MUTE : 0;
18274 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18275 HDA_AMP_MUTE, bits);
18276 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18277 HDA_AMP_MUTE, bits);
18278 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18279 HDA_AMP_MUTE, bits);
18280 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18281 HDA_AMP_MUTE, bits);
18284 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18286 unsigned int present;
18287 unsigned char bits;
18289 present = snd_hda_jack_detect(codec, 0x1b);
18290 bits = present ? 0 : PIN_OUT;
18291 snd_hda_codec_write(codec, 0x14, 0,
18292 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18295 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18297 unsigned int present1, present2;
18299 present1 = snd_hda_jack_detect(codec, 0x21);
18300 present2 = snd_hda_jack_detect(codec, 0x15);
18302 if (present1 || present2) {
18303 snd_hda_codec_write_cache(codec, 0x14, 0,
18304 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18306 snd_hda_codec_write_cache(codec, 0x14, 0,
18307 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18311 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18313 unsigned int present1, present2;
18315 present1 = snd_hda_jack_detect(codec, 0x1b);
18316 present2 = snd_hda_jack_detect(codec, 0x15);
18318 if (present1 || present2) {
18319 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18320 HDA_AMP_MUTE, HDA_AMP_MUTE);
18321 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18322 HDA_AMP_MUTE, HDA_AMP_MUTE);
18324 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18326 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18331 static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18333 unsigned int present1, present2;
18335 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18336 AC_VERB_GET_PIN_SENSE, 0)
18337 & AC_PINSENSE_PRESENCE;
18338 present2 = snd_hda_codec_read(codec, 0x21, 0,
18339 AC_VERB_GET_PIN_SENSE, 0)
18340 & AC_PINSENSE_PRESENCE;
18342 if (present1 || present2) {
18343 snd_hda_codec_write_cache(codec, 0x14, 0,
18344 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18345 snd_hda_codec_write_cache(codec, 0x17, 0,
18346 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18348 snd_hda_codec_write_cache(codec, 0x14, 0,
18349 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18350 snd_hda_codec_write_cache(codec, 0x17, 0,
18351 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18355 static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18357 unsigned int present1, present2;
18359 present1 = snd_hda_codec_read(codec, 0x21, 0,
18360 AC_VERB_GET_PIN_SENSE, 0)
18361 & AC_PINSENSE_PRESENCE;
18362 present2 = snd_hda_codec_read(codec, 0x15, 0,
18363 AC_VERB_GET_PIN_SENSE, 0)
18364 & AC_PINSENSE_PRESENCE;
18366 if (present1 || present2) {
18367 snd_hda_codec_write_cache(codec, 0x14, 0,
18368 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18369 snd_hda_codec_write_cache(codec, 0x17, 0,
18370 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18372 snd_hda_codec_write_cache(codec, 0x14, 0,
18373 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18374 snd_hda_codec_write_cache(codec, 0x17, 0,
18375 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18379 static void alc663_m51va_unsol_event(struct hda_codec *codec,
18382 switch (res >> 26) {
18383 case ALC880_HP_EVENT:
18384 alc663_m51va_speaker_automute(codec);
18386 case ALC880_MIC_EVENT:
18387 alc_mic_automute(codec);
18392 static void alc663_m51va_setup(struct hda_codec *codec)
18394 struct alc_spec *spec = codec->spec;
18395 spec->ext_mic.pin = 0x18;
18396 spec->ext_mic.mux_idx = 0;
18397 spec->int_mic.pin = 0x12;
18398 spec->int_mic.mux_idx = 9;
18399 spec->auto_mic = 1;
18402 static void alc663_m51va_inithook(struct hda_codec *codec)
18404 alc663_m51va_speaker_automute(codec);
18405 alc_mic_automute(codec);
18408 /* ***************** Mode1 ******************************/
18409 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
18411 static void alc663_mode1_setup(struct hda_codec *codec)
18413 struct alc_spec *spec = codec->spec;
18414 spec->ext_mic.pin = 0x18;
18415 spec->ext_mic.mux_idx = 0;
18416 spec->int_mic.pin = 0x19;
18417 spec->int_mic.mux_idx = 1;
18418 spec->auto_mic = 1;
18421 #define alc663_mode1_inithook alc663_m51va_inithook
18423 /* ***************** Mode2 ******************************/
18424 static void alc662_mode2_unsol_event(struct hda_codec *codec,
18427 switch (res >> 26) {
18428 case ALC880_HP_EVENT:
18429 alc662_f5z_speaker_automute(codec);
18431 case ALC880_MIC_EVENT:
18432 alc_mic_automute(codec);
18437 #define alc662_mode2_setup alc663_mode1_setup
18439 static void alc662_mode2_inithook(struct hda_codec *codec)
18441 alc662_f5z_speaker_automute(codec);
18442 alc_mic_automute(codec);
18444 /* ***************** Mode3 ******************************/
18445 static void alc663_mode3_unsol_event(struct hda_codec *codec,
18448 switch (res >> 26) {
18449 case ALC880_HP_EVENT:
18450 alc663_two_hp_m1_speaker_automute(codec);
18452 case ALC880_MIC_EVENT:
18453 alc_mic_automute(codec);
18458 #define alc663_mode3_setup alc663_mode1_setup
18460 static void alc663_mode3_inithook(struct hda_codec *codec)
18462 alc663_two_hp_m1_speaker_automute(codec);
18463 alc_mic_automute(codec);
18465 /* ***************** Mode4 ******************************/
18466 static void alc663_mode4_unsol_event(struct hda_codec *codec,
18469 switch (res >> 26) {
18470 case ALC880_HP_EVENT:
18471 alc663_21jd_two_speaker_automute(codec);
18473 case ALC880_MIC_EVENT:
18474 alc_mic_automute(codec);
18479 #define alc663_mode4_setup alc663_mode1_setup
18481 static void alc663_mode4_inithook(struct hda_codec *codec)
18483 alc663_21jd_two_speaker_automute(codec);
18484 alc_mic_automute(codec);
18486 /* ***************** Mode5 ******************************/
18487 static void alc663_mode5_unsol_event(struct hda_codec *codec,
18490 switch (res >> 26) {
18491 case ALC880_HP_EVENT:
18492 alc663_15jd_two_speaker_automute(codec);
18494 case ALC880_MIC_EVENT:
18495 alc_mic_automute(codec);
18500 #define alc663_mode5_setup alc663_mode1_setup
18502 static void alc663_mode5_inithook(struct hda_codec *codec)
18504 alc663_15jd_two_speaker_automute(codec);
18505 alc_mic_automute(codec);
18507 /* ***************** Mode6 ******************************/
18508 static void alc663_mode6_unsol_event(struct hda_codec *codec,
18511 switch (res >> 26) {
18512 case ALC880_HP_EVENT:
18513 alc663_two_hp_m2_speaker_automute(codec);
18515 case ALC880_MIC_EVENT:
18516 alc_mic_automute(codec);
18521 #define alc663_mode6_setup alc663_mode1_setup
18523 static void alc663_mode6_inithook(struct hda_codec *codec)
18525 alc663_two_hp_m2_speaker_automute(codec);
18526 alc_mic_automute(codec);
18529 /* ***************** Mode7 ******************************/
18530 static void alc663_mode7_unsol_event(struct hda_codec *codec,
18533 switch (res >> 26) {
18534 case ALC880_HP_EVENT:
18535 alc663_two_hp_m7_speaker_automute(codec);
18537 case ALC880_MIC_EVENT:
18538 alc_mic_automute(codec);
18543 #define alc663_mode7_setup alc663_mode1_setup
18545 static void alc663_mode7_inithook(struct hda_codec *codec)
18547 alc663_two_hp_m7_speaker_automute(codec);
18548 alc_mic_automute(codec);
18551 /* ***************** Mode8 ******************************/
18552 static void alc663_mode8_unsol_event(struct hda_codec *codec,
18555 switch (res >> 26) {
18556 case ALC880_HP_EVENT:
18557 alc663_two_hp_m8_speaker_automute(codec);
18559 case ALC880_MIC_EVENT:
18560 alc_mic_automute(codec);
18565 #define alc663_mode8_setup alc663_m51va_setup
18567 static void alc663_mode8_inithook(struct hda_codec *codec)
18569 alc663_two_hp_m8_speaker_automute(codec);
18570 alc_mic_automute(codec);
18573 static void alc663_g71v_hp_automute(struct hda_codec *codec)
18575 unsigned int present;
18576 unsigned char bits;
18578 present = snd_hda_jack_detect(codec, 0x21);
18579 bits = present ? HDA_AMP_MUTE : 0;
18580 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18581 HDA_AMP_MUTE, bits);
18582 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18583 HDA_AMP_MUTE, bits);
18586 static void alc663_g71v_front_automute(struct hda_codec *codec)
18588 unsigned int present;
18589 unsigned char bits;
18591 present = snd_hda_jack_detect(codec, 0x15);
18592 bits = present ? HDA_AMP_MUTE : 0;
18593 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18594 HDA_AMP_MUTE, bits);
18597 static void alc663_g71v_unsol_event(struct hda_codec *codec,
18600 switch (res >> 26) {
18601 case ALC880_HP_EVENT:
18602 alc663_g71v_hp_automute(codec);
18604 case ALC880_FRONT_EVENT:
18605 alc663_g71v_front_automute(codec);
18607 case ALC880_MIC_EVENT:
18608 alc_mic_automute(codec);
18613 #define alc663_g71v_setup alc663_m51va_setup
18615 static void alc663_g71v_inithook(struct hda_codec *codec)
18617 alc663_g71v_front_automute(codec);
18618 alc663_g71v_hp_automute(codec);
18619 alc_mic_automute(codec);
18622 static void alc663_g50v_unsol_event(struct hda_codec *codec,
18625 switch (res >> 26) {
18626 case ALC880_HP_EVENT:
18627 alc663_m51va_speaker_automute(codec);
18629 case ALC880_MIC_EVENT:
18630 alc_mic_automute(codec);
18635 #define alc663_g50v_setup alc663_m51va_setup
18637 static void alc663_g50v_inithook(struct hda_codec *codec)
18639 alc663_m51va_speaker_automute(codec);
18640 alc_mic_automute(codec);
18643 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18644 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18645 ALC262_HIPPO_MASTER_SWITCH,
18647 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18648 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18649 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18651 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18652 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18653 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18657 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18658 /* Master Playback automatically created from Speaker and Headphone */
18659 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18660 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18661 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18662 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18665 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18666 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18668 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18669 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18670 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18674 #ifdef CONFIG_SND_HDA_POWER_SAVE
18675 #define alc662_loopbacks alc880_loopbacks
18679 /* pcm configuration: identical with ALC880 */
18680 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
18681 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
18682 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
18683 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
18686 * configuration and preset
18688 static const char *alc662_models[ALC662_MODEL_LAST] = {
18689 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18690 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18691 [ALC662_3ST_6ch] = "3stack-6ch",
18692 [ALC662_5ST_DIG] = "6stack-dig",
18693 [ALC662_LENOVO_101E] = "lenovo-101e",
18694 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18695 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18696 [ALC662_ECS] = "ecs",
18697 [ALC663_ASUS_M51VA] = "m51va",
18698 [ALC663_ASUS_G71V] = "g71v",
18699 [ALC663_ASUS_H13] = "h13",
18700 [ALC663_ASUS_G50V] = "g50v",
18701 [ALC663_ASUS_MODE1] = "asus-mode1",
18702 [ALC662_ASUS_MODE2] = "asus-mode2",
18703 [ALC663_ASUS_MODE3] = "asus-mode3",
18704 [ALC663_ASUS_MODE4] = "asus-mode4",
18705 [ALC663_ASUS_MODE5] = "asus-mode5",
18706 [ALC663_ASUS_MODE6] = "asus-mode6",
18707 [ALC663_ASUS_MODE7] = "asus-mode7",
18708 [ALC663_ASUS_MODE8] = "asus-mode8",
18709 [ALC272_DELL] = "dell",
18710 [ALC272_DELL_ZM1] = "dell-zm1",
18711 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18712 [ALC662_AUTO] = "auto",
18715 static struct snd_pci_quirk alc662_cfg_tbl[] = {
18716 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18717 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18718 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18719 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18720 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18721 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18722 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18723 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18724 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18725 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18726 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18727 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18728 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18729 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18730 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18731 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18732 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18733 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18734 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18735 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18736 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18737 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18738 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18739 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18740 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18741 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18742 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18743 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18744 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18745 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18746 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18747 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18748 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18749 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18750 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18751 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18752 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18753 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18754 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18755 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18756 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18757 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18758 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18759 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18760 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18761 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18762 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18763 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18764 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18765 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18766 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18767 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18768 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18769 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18770 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18771 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18772 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18773 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18774 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18775 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18776 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18777 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18778 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18779 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18780 ALC662_3ST_6ch_DIG),
18781 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18782 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18783 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18784 ALC662_3ST_6ch_DIG),
18785 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18786 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18787 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18788 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18789 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18790 ALC662_3ST_6ch_DIG),
18791 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18796 static struct alc_config_preset alc662_presets[] = {
18797 [ALC662_3ST_2ch_DIG] = {
18798 .mixers = { alc662_3ST_2ch_mixer },
18799 .init_verbs = { alc662_init_verbs },
18800 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18801 .dac_nids = alc662_dac_nids,
18802 .dig_out_nid = ALC662_DIGOUT_NID,
18803 .dig_in_nid = ALC662_DIGIN_NID,
18804 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18805 .channel_mode = alc662_3ST_2ch_modes,
18806 .input_mux = &alc662_capture_source,
18808 [ALC662_3ST_6ch_DIG] = {
18809 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18810 .init_verbs = { alc662_init_verbs },
18811 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18812 .dac_nids = alc662_dac_nids,
18813 .dig_out_nid = ALC662_DIGOUT_NID,
18814 .dig_in_nid = ALC662_DIGIN_NID,
18815 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18816 .channel_mode = alc662_3ST_6ch_modes,
18818 .input_mux = &alc662_capture_source,
18820 [ALC662_3ST_6ch] = {
18821 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18822 .init_verbs = { alc662_init_verbs },
18823 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18824 .dac_nids = alc662_dac_nids,
18825 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18826 .channel_mode = alc662_3ST_6ch_modes,
18828 .input_mux = &alc662_capture_source,
18830 [ALC662_5ST_DIG] = {
18831 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18832 .init_verbs = { alc662_init_verbs },
18833 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18834 .dac_nids = alc662_dac_nids,
18835 .dig_out_nid = ALC662_DIGOUT_NID,
18836 .dig_in_nid = ALC662_DIGIN_NID,
18837 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18838 .channel_mode = alc662_5stack_modes,
18839 .input_mux = &alc662_capture_source,
18841 [ALC662_LENOVO_101E] = {
18842 .mixers = { alc662_lenovo_101e_mixer },
18843 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18844 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18845 .dac_nids = alc662_dac_nids,
18846 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18847 .channel_mode = alc662_3ST_2ch_modes,
18848 .input_mux = &alc662_lenovo_101e_capture_source,
18849 .unsol_event = alc662_lenovo_101e_unsol_event,
18850 .init_hook = alc662_lenovo_101e_all_automute,
18852 [ALC662_ASUS_EEEPC_P701] = {
18853 .mixers = { alc662_eeepc_p701_mixer },
18854 .init_verbs = { alc662_init_verbs,
18855 alc662_eeepc_sue_init_verbs },
18856 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18857 .dac_nids = alc662_dac_nids,
18858 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18859 .channel_mode = alc662_3ST_2ch_modes,
18860 .unsol_event = alc662_eeepc_unsol_event,
18861 .setup = alc662_eeepc_setup,
18862 .init_hook = alc662_eeepc_inithook,
18864 [ALC662_ASUS_EEEPC_EP20] = {
18865 .mixers = { alc662_eeepc_ep20_mixer,
18866 alc662_chmode_mixer },
18867 .init_verbs = { alc662_init_verbs,
18868 alc662_eeepc_ep20_sue_init_verbs },
18869 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18870 .dac_nids = alc662_dac_nids,
18871 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18872 .channel_mode = alc662_3ST_6ch_modes,
18873 .input_mux = &alc662_lenovo_101e_capture_source,
18874 .unsol_event = alc662_eeepc_unsol_event,
18875 .setup = alc662_eeepc_ep20_setup,
18876 .init_hook = alc662_eeepc_ep20_inithook,
18879 .mixers = { alc662_ecs_mixer },
18880 .init_verbs = { alc662_init_verbs,
18881 alc662_ecs_init_verbs },
18882 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18883 .dac_nids = alc662_dac_nids,
18884 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18885 .channel_mode = alc662_3ST_2ch_modes,
18886 .unsol_event = alc662_eeepc_unsol_event,
18887 .setup = alc662_eeepc_setup,
18888 .init_hook = alc662_eeepc_inithook,
18890 [ALC663_ASUS_M51VA] = {
18891 .mixers = { alc663_m51va_mixer },
18892 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18893 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18894 .dac_nids = alc662_dac_nids,
18895 .dig_out_nid = ALC662_DIGOUT_NID,
18896 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18897 .channel_mode = alc662_3ST_2ch_modes,
18898 .unsol_event = alc663_m51va_unsol_event,
18899 .setup = alc663_m51va_setup,
18900 .init_hook = alc663_m51va_inithook,
18902 [ALC663_ASUS_G71V] = {
18903 .mixers = { alc663_g71v_mixer },
18904 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18905 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18906 .dac_nids = alc662_dac_nids,
18907 .dig_out_nid = ALC662_DIGOUT_NID,
18908 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18909 .channel_mode = alc662_3ST_2ch_modes,
18910 .unsol_event = alc663_g71v_unsol_event,
18911 .setup = alc663_g71v_setup,
18912 .init_hook = alc663_g71v_inithook,
18914 [ALC663_ASUS_H13] = {
18915 .mixers = { alc663_m51va_mixer },
18916 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18917 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18918 .dac_nids = alc662_dac_nids,
18919 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18920 .channel_mode = alc662_3ST_2ch_modes,
18921 .unsol_event = alc663_m51va_unsol_event,
18922 .init_hook = alc663_m51va_inithook,
18924 [ALC663_ASUS_G50V] = {
18925 .mixers = { alc663_g50v_mixer },
18926 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18927 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18928 .dac_nids = alc662_dac_nids,
18929 .dig_out_nid = ALC662_DIGOUT_NID,
18930 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18931 .channel_mode = alc662_3ST_6ch_modes,
18932 .input_mux = &alc663_capture_source,
18933 .unsol_event = alc663_g50v_unsol_event,
18934 .setup = alc663_g50v_setup,
18935 .init_hook = alc663_g50v_inithook,
18937 [ALC663_ASUS_MODE1] = {
18938 .mixers = { alc663_m51va_mixer },
18939 .cap_mixer = alc662_auto_capture_mixer,
18940 .init_verbs = { alc662_init_verbs,
18941 alc663_21jd_amic_init_verbs },
18942 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18944 .dac_nids = alc662_dac_nids,
18945 .dig_out_nid = ALC662_DIGOUT_NID,
18946 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18947 .channel_mode = alc662_3ST_2ch_modes,
18948 .unsol_event = alc663_mode1_unsol_event,
18949 .setup = alc663_mode1_setup,
18950 .init_hook = alc663_mode1_inithook,
18952 [ALC662_ASUS_MODE2] = {
18953 .mixers = { alc662_1bjd_mixer },
18954 .cap_mixer = alc662_auto_capture_mixer,
18955 .init_verbs = { alc662_init_verbs,
18956 alc662_1bjd_amic_init_verbs },
18957 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18958 .dac_nids = alc662_dac_nids,
18959 .dig_out_nid = ALC662_DIGOUT_NID,
18960 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18961 .channel_mode = alc662_3ST_2ch_modes,
18962 .unsol_event = alc662_mode2_unsol_event,
18963 .setup = alc662_mode2_setup,
18964 .init_hook = alc662_mode2_inithook,
18966 [ALC663_ASUS_MODE3] = {
18967 .mixers = { alc663_two_hp_m1_mixer },
18968 .cap_mixer = alc662_auto_capture_mixer,
18969 .init_verbs = { alc662_init_verbs,
18970 alc663_two_hp_amic_m1_init_verbs },
18971 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18973 .dac_nids = alc662_dac_nids,
18974 .dig_out_nid = ALC662_DIGOUT_NID,
18975 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18976 .channel_mode = alc662_3ST_2ch_modes,
18977 .unsol_event = alc663_mode3_unsol_event,
18978 .setup = alc663_mode3_setup,
18979 .init_hook = alc663_mode3_inithook,
18981 [ALC663_ASUS_MODE4] = {
18982 .mixers = { alc663_asus_21jd_clfe_mixer },
18983 .cap_mixer = alc662_auto_capture_mixer,
18984 .init_verbs = { alc662_init_verbs,
18985 alc663_21jd_amic_init_verbs},
18986 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18988 .dac_nids = alc662_dac_nids,
18989 .dig_out_nid = ALC662_DIGOUT_NID,
18990 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18991 .channel_mode = alc662_3ST_2ch_modes,
18992 .unsol_event = alc663_mode4_unsol_event,
18993 .setup = alc663_mode4_setup,
18994 .init_hook = alc663_mode4_inithook,
18996 [ALC663_ASUS_MODE5] = {
18997 .mixers = { alc663_asus_15jd_clfe_mixer },
18998 .cap_mixer = alc662_auto_capture_mixer,
18999 .init_verbs = { alc662_init_verbs,
19000 alc663_15jd_amic_init_verbs },
19001 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19003 .dac_nids = alc662_dac_nids,
19004 .dig_out_nid = ALC662_DIGOUT_NID,
19005 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19006 .channel_mode = alc662_3ST_2ch_modes,
19007 .unsol_event = alc663_mode5_unsol_event,
19008 .setup = alc663_mode5_setup,
19009 .init_hook = alc663_mode5_inithook,
19011 [ALC663_ASUS_MODE6] = {
19012 .mixers = { alc663_two_hp_m2_mixer },
19013 .cap_mixer = alc662_auto_capture_mixer,
19014 .init_verbs = { alc662_init_verbs,
19015 alc663_two_hp_amic_m2_init_verbs },
19016 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19018 .dac_nids = alc662_dac_nids,
19019 .dig_out_nid = ALC662_DIGOUT_NID,
19020 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19021 .channel_mode = alc662_3ST_2ch_modes,
19022 .unsol_event = alc663_mode6_unsol_event,
19023 .setup = alc663_mode6_setup,
19024 .init_hook = alc663_mode6_inithook,
19026 [ALC663_ASUS_MODE7] = {
19027 .mixers = { alc663_mode7_mixer },
19028 .cap_mixer = alc662_auto_capture_mixer,
19029 .init_verbs = { alc662_init_verbs,
19030 alc663_mode7_init_verbs },
19031 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19033 .dac_nids = alc662_dac_nids,
19034 .dig_out_nid = ALC662_DIGOUT_NID,
19035 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19036 .channel_mode = alc662_3ST_2ch_modes,
19037 .unsol_event = alc663_mode7_unsol_event,
19038 .setup = alc663_mode7_setup,
19039 .init_hook = alc663_mode7_inithook,
19041 [ALC663_ASUS_MODE8] = {
19042 .mixers = { alc663_mode8_mixer },
19043 .cap_mixer = alc662_auto_capture_mixer,
19044 .init_verbs = { alc662_init_verbs,
19045 alc663_mode8_init_verbs },
19046 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19048 .dac_nids = alc662_dac_nids,
19049 .dig_out_nid = ALC662_DIGOUT_NID,
19050 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19051 .channel_mode = alc662_3ST_2ch_modes,
19052 .unsol_event = alc663_mode8_unsol_event,
19053 .setup = alc663_mode8_setup,
19054 .init_hook = alc663_mode8_inithook,
19057 .mixers = { alc663_m51va_mixer },
19058 .cap_mixer = alc272_auto_capture_mixer,
19059 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19060 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19061 .dac_nids = alc662_dac_nids,
19062 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19063 .adc_nids = alc272_adc_nids,
19064 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19065 .capsrc_nids = alc272_capsrc_nids,
19066 .channel_mode = alc662_3ST_2ch_modes,
19067 .unsol_event = alc663_m51va_unsol_event,
19068 .setup = alc663_m51va_setup,
19069 .init_hook = alc663_m51va_inithook,
19071 [ALC272_DELL_ZM1] = {
19072 .mixers = { alc663_m51va_mixer },
19073 .cap_mixer = alc662_auto_capture_mixer,
19074 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19075 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19076 .dac_nids = alc662_dac_nids,
19077 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19078 .adc_nids = alc662_adc_nids,
19080 .capsrc_nids = alc662_capsrc_nids,
19081 .channel_mode = alc662_3ST_2ch_modes,
19082 .unsol_event = alc663_m51va_unsol_event,
19083 .setup = alc663_m51va_setup,
19084 .init_hook = alc663_m51va_inithook,
19086 [ALC272_SAMSUNG_NC10] = {
19087 .mixers = { alc272_nc10_mixer },
19088 .init_verbs = { alc662_init_verbs,
19089 alc663_21jd_amic_init_verbs },
19090 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19091 .dac_nids = alc272_dac_nids,
19092 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19093 .channel_mode = alc662_3ST_2ch_modes,
19094 /*.input_mux = &alc272_nc10_capture_source,*/
19095 .unsol_event = alc663_mode4_unsol_event,
19096 .setup = alc663_mode4_setup,
19097 .init_hook = alc663_mode4_inithook,
19103 * BIOS auto configuration
19106 /* convert from MIX nid to DAC */
19107 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19111 else if (nid >= 0x0c && nid <= 0x0e)
19112 return nid - 0x0c + 0x02;
19113 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19119 /* get MIX nid connected to the given pin targeted to DAC */
19120 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19126 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19127 for (i = 0; i < num; i++) {
19128 if (alc662_mix_to_dac(mix[i]) == dac)
19134 /* look for an empty DAC slot */
19135 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19137 struct alc_spec *spec = codec->spec;
19141 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19144 for (i = 0; i < num; i++) {
19145 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19148 for (j = 0; j < spec->multiout.num_dacs; j++)
19149 if (spec->multiout.dac_nids[j] == nid)
19151 if (j >= spec->multiout.num_dacs)
19157 /* fill in the dac_nids table from the parsed pin configuration */
19158 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19159 const struct auto_pin_cfg *cfg)
19161 struct alc_spec *spec = codec->spec;
19165 spec->multiout.dac_nids = spec->private_dac_nids;
19166 for (i = 0; i < cfg->line_outs; i++) {
19167 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19170 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19175 static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19176 hda_nid_t nid, int idx, unsigned int chs)
19178 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19179 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19182 static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19183 hda_nid_t nid, int idx, unsigned int chs)
19185 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19186 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19189 #define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19190 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19191 #define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19192 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19193 #define alc662_add_stereo_vol(spec, pfx, nid) \
19194 alc662_add_vol_ctl(spec, pfx, nid, 3)
19195 #define alc662_add_stereo_sw(spec, pfx, nid) \
19196 alc662_add_sw_ctl(spec, pfx, nid, 3)
19198 /* add playback controls from the parsed DAC table */
19199 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19200 const struct auto_pin_cfg *cfg)
19202 struct alc_spec *spec = codec->spec;
19203 static const char *chname[4] = {
19204 "Front", "Surround", NULL /*CLFE*/, "Side"
19206 const char *pfx = alc_get_line_out_pfx(cfg, true);
19207 hda_nid_t nid, mix;
19210 for (i = 0; i < cfg->line_outs; i++) {
19211 nid = spec->multiout.dac_nids[i];
19214 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19217 if (!pfx && i == 2) {
19219 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19222 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19225 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19228 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19232 const char *name = pfx;
19235 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
19238 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
19246 /* add playback controls for speaker and HP outputs */
19247 /* return DAC nid if any new DAC is assigned */
19248 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19251 struct alc_spec *spec = codec->spec;
19252 hda_nid_t nid, mix;
19257 nid = alc662_look_for_dac(codec, pin);
19259 /* the corresponding DAC is already occupied */
19260 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19261 return 0; /* no way */
19262 /* create a switch only */
19263 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19264 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19267 mix = alc662_dac_to_mix(codec, pin, nid);
19270 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19273 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19279 /* create playback/capture controls for input pins */
19280 #define alc662_auto_create_input_ctls \
19281 alc882_auto_create_input_ctls
19283 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19284 hda_nid_t nid, int pin_type,
19288 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19290 alc_set_pin_output(codec, nid, pin_type);
19291 /* need the manual connection? */
19292 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19295 for (i = 0; i < num; i++) {
19296 if (alc662_mix_to_dac(srcs[i]) != dac)
19298 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19303 static void alc662_auto_init_multi_out(struct hda_codec *codec)
19305 struct alc_spec *spec = codec->spec;
19306 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19309 for (i = 0; i <= HDA_SIDE; i++) {
19310 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19312 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19313 spec->multiout.dac_nids[i]);
19317 static void alc662_auto_init_hp_out(struct hda_codec *codec)
19319 struct alc_spec *spec = codec->spec;
19322 pin = spec->autocfg.hp_pins[0];
19324 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19325 spec->multiout.hp_nid);
19326 pin = spec->autocfg.speaker_pins[0];
19328 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19329 spec->multiout.extra_out_nid[0]);
19332 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19334 static void alc662_auto_init_analog_input(struct hda_codec *codec)
19336 struct alc_spec *spec = codec->spec;
19337 struct auto_pin_cfg *cfg = &spec->autocfg;
19340 for (i = 0; i < cfg->num_inputs; i++) {
19341 hda_nid_t nid = cfg->inputs[i].pin;
19342 if (alc_is_input_pin(codec, nid)) {
19343 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19344 if (nid != ALC662_PIN_CD_NID &&
19345 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19346 snd_hda_codec_write(codec, nid, 0,
19347 AC_VERB_SET_AMP_GAIN_MUTE,
19353 #define alc662_auto_init_input_src alc882_auto_init_input_src
19355 static int alc662_parse_auto_config(struct hda_codec *codec)
19357 struct alc_spec *spec = codec->spec;
19359 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19361 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19365 if (!spec->autocfg.line_outs)
19366 return 0; /* can't find valid BIOS pin config */
19368 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19371 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19374 err = alc662_auto_create_extra_out(codec,
19375 spec->autocfg.speaker_pins[0],
19380 spec->multiout.extra_out_nid[0] = err;
19381 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19386 spec->multiout.hp_nid = err;
19387 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19391 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19393 alc_auto_parse_digital(codec);
19395 if (spec->kctls.list)
19396 add_mixer(spec, spec->kctls.list);
19398 spec->num_mux_defs = 1;
19399 spec->input_mux = &spec->private_imux[0];
19401 add_verb(spec, alc662_init_verbs);
19402 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19403 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19404 add_verb(spec, alc663_init_verbs);
19406 if (codec->vendor_id == 0x10ec0272)
19407 add_verb(spec, alc272_init_verbs);
19409 err = alc_auto_add_mic_boost(codec);
19413 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19414 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19415 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19417 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19422 /* additional initialization for auto-configuration model */
19423 static void alc662_auto_init(struct hda_codec *codec)
19425 struct alc_spec *spec = codec->spec;
19426 alc662_auto_init_multi_out(codec);
19427 alc662_auto_init_hp_out(codec);
19428 alc662_auto_init_analog_input(codec);
19429 alc662_auto_init_input_src(codec);
19430 alc_auto_init_digital(codec);
19431 if (spec->unsol_event)
19432 alc_inithook(codec);
19435 static void alc272_fixup_mario(struct hda_codec *codec,
19436 const struct alc_fixup *fix, int action)
19438 if (action != ALC_FIXUP_ACT_PROBE)
19440 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19441 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19442 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19443 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19444 (0 << AC_AMPCAP_MUTE_SHIFT)))
19445 printk(KERN_WARNING
19446 "hda_codec: failed to override amp caps for NID 0x2\n");
19450 ALC662_FIXUP_ASPIRE,
19451 ALC662_FIXUP_IDEAPAD,
19452 ALC272_FIXUP_MARIO,
19455 static const struct alc_fixup alc662_fixups[] = {
19456 [ALC662_FIXUP_ASPIRE] = {
19457 .type = ALC_FIXUP_PINS,
19458 .v.pins = (const struct alc_pincfg[]) {
19459 { 0x15, 0x99130112 }, /* subwoofer */
19463 [ALC662_FIXUP_IDEAPAD] = {
19464 .type = ALC_FIXUP_PINS,
19465 .v.pins = (const struct alc_pincfg[]) {
19466 { 0x17, 0x99130112 }, /* subwoofer */
19470 [ALC272_FIXUP_MARIO] = {
19471 .type = ALC_FIXUP_FUNC,
19472 .v.func = alc272_fixup_mario,
19476 static struct snd_pci_quirk alc662_fixup_tbl[] = {
19477 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19478 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19479 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19480 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19484 static const struct alc_model_fixup alc662_fixup_models[] = {
19485 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19490 static int patch_alc662(struct hda_codec *codec)
19492 struct alc_spec *spec;
19493 int err, board_config;
19496 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19500 codec->spec = spec;
19502 alc_auto_parse_customize_define(codec);
19504 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19506 coef = alc_read_coef_idx(codec, 0);
19507 if (coef == 0x8020 || coef == 0x8011)
19508 alc_codec_rename(codec, "ALC661");
19509 else if (coef & (1 << 14) &&
19510 codec->bus->pci->subsystem_vendor == 0x1025 &&
19511 spec->cdefine.platform_type == 1)
19512 alc_codec_rename(codec, "ALC272X");
19513 else if (coef == 0x4011)
19514 alc_codec_rename(codec, "ALC656");
19516 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19519 if (board_config < 0) {
19520 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19522 board_config = ALC662_AUTO;
19525 if (board_config == ALC662_AUTO) {
19526 alc_pick_fixup(codec, alc662_fixup_models,
19527 alc662_fixup_tbl, alc662_fixups);
19528 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19529 /* automatic parse from the BIOS config */
19530 err = alc662_parse_auto_config(codec);
19536 "hda_codec: Cannot set up configuration "
19537 "from BIOS. Using base mode...\n");
19538 board_config = ALC662_3ST_2ch_DIG;
19542 if (has_cdefine_beep(codec)) {
19543 err = snd_hda_attach_beep_device(codec, 0x1);
19550 if (board_config != ALC662_AUTO)
19551 setup_preset(codec, &alc662_presets[board_config]);
19553 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19554 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19556 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19557 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19559 if (!spec->adc_nids) {
19560 spec->adc_nids = alc662_adc_nids;
19561 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19563 if (!spec->capsrc_nids)
19564 spec->capsrc_nids = alc662_capsrc_nids;
19566 if (!spec->cap_mixer)
19567 set_capture_mixer(codec);
19569 if (has_cdefine_beep(codec)) {
19570 switch (codec->vendor_id) {
19572 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19577 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19580 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19584 spec->vmaster_nid = 0x02;
19586 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19588 codec->patch_ops = alc_patch_ops;
19589 if (board_config == ALC662_AUTO)
19590 spec->init_hook = alc662_auto_init;
19592 alc_init_jacks(codec);
19594 #ifdef CONFIG_SND_HDA_POWER_SAVE
19595 if (!spec->loopback.amplist)
19596 spec->loopback.amplist = alc662_loopbacks;
19602 static int patch_alc888(struct hda_codec *codec)
19604 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19605 kfree(codec->chip_name);
19606 if (codec->vendor_id == 0x10ec0887)
19607 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19609 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19610 if (!codec->chip_name) {
19614 return patch_alc662(codec);
19616 return patch_alc882(codec);
19622 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19623 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19624 #define alc680_modes alc260_modes
19626 static hda_nid_t alc680_dac_nids[3] = {
19627 /* Lout1, Lout2, hp */
19631 static hda_nid_t alc680_adc_nids[3] = {
19633 /* DMIC, MIC, Line-in*/
19638 * Analog capture ADC cgange
19640 static void alc680_rec_autoswitch(struct hda_codec *codec)
19642 struct alc_spec *spec = codec->spec;
19643 struct auto_pin_cfg *cfg = &spec->autocfg;
19645 int type_found = AUTO_PIN_LAST;
19649 for (i = 0; i < cfg->num_inputs; i++) {
19650 nid = cfg->inputs[i].pin;
19651 if (!(snd_hda_query_pin_caps(codec, nid) &
19652 AC_PINCAP_PRES_DETECT))
19654 if (snd_hda_jack_detect(codec, nid)) {
19655 if (cfg->inputs[i].type < type_found) {
19656 type_found = cfg->inputs[i].type;
19664 snd_hda_get_connections(codec, pin_found, &nid, 1);
19666 if (nid != spec->cur_adc)
19667 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19668 spec->cur_adc = nid;
19669 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19670 spec->cur_adc_format);
19673 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19674 struct hda_codec *codec,
19675 unsigned int stream_tag,
19676 unsigned int format,
19677 struct snd_pcm_substream *substream)
19679 struct alc_spec *spec = codec->spec;
19681 spec->cur_adc = 0x07;
19682 spec->cur_adc_stream_tag = stream_tag;
19683 spec->cur_adc_format = format;
19685 alc680_rec_autoswitch(codec);
19689 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19690 struct hda_codec *codec,
19691 struct snd_pcm_substream *substream)
19693 snd_hda_codec_cleanup_stream(codec, 0x07);
19694 snd_hda_codec_cleanup_stream(codec, 0x08);
19695 snd_hda_codec_cleanup_stream(codec, 0x09);
19699 static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19700 .substreams = 1, /* can be overridden */
19703 /* NID is set in alc_build_pcms */
19705 .prepare = alc680_capture_pcm_prepare,
19706 .cleanup = alc680_capture_pcm_cleanup
19710 static struct snd_kcontrol_new alc680_base_mixer[] = {
19711 /* output mixer control */
19712 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19713 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19714 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19715 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19716 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19717 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19718 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19722 static struct hda_bind_ctls alc680_bind_cap_vol = {
19723 .ops = &snd_hda_bind_vol,
19725 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19726 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19727 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19732 static struct hda_bind_ctls alc680_bind_cap_switch = {
19733 .ops = &snd_hda_bind_sw,
19735 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19736 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19737 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19742 static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19743 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19744 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19749 * generic initialization of ADC, input mixers and output mixers
19751 static struct hda_verb alc680_init_verbs[] = {
19752 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19753 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19754 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19756 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19757 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19758 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19759 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19760 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19761 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19765 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19766 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19767 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19769 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19770 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19771 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19776 /* toggle speaker-output according to the hp-jack state */
19777 static void alc680_base_setup(struct hda_codec *codec)
19779 struct alc_spec *spec = codec->spec;
19781 spec->autocfg.hp_pins[0] = 0x16;
19782 spec->autocfg.speaker_pins[0] = 0x14;
19783 spec->autocfg.speaker_pins[1] = 0x15;
19784 spec->autocfg.num_inputs = 2;
19785 spec->autocfg.inputs[0].pin = 0x18;
19786 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19787 spec->autocfg.inputs[1].pin = 0x19;
19788 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19791 static void alc680_unsol_event(struct hda_codec *codec,
19794 if ((res >> 26) == ALC880_HP_EVENT)
19795 alc_automute_amp(codec);
19796 if ((res >> 26) == ALC880_MIC_EVENT)
19797 alc680_rec_autoswitch(codec);
19800 static void alc680_inithook(struct hda_codec *codec)
19802 alc_automute_amp(codec);
19803 alc680_rec_autoswitch(codec);
19806 /* create input playback/capture controls for the given pin */
19807 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19808 const char *ctlname, int idx)
19826 if (spec->multiout.dac_nids[0] != dac &&
19827 spec->multiout.dac_nids[1] != dac) {
19828 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19829 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19834 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19835 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19839 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19845 /* add playback controls from the parsed DAC table */
19846 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19847 const struct auto_pin_cfg *cfg)
19852 spec->multiout.dac_nids = spec->private_dac_nids;
19854 nid = cfg->line_out_pins[0];
19857 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19861 err = alc680_new_analog_output(spec, nid, name, 0);
19866 nid = cfg->speaker_pins[0];
19868 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19872 nid = cfg->hp_pins[0];
19874 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19882 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19883 hda_nid_t nid, int pin_type)
19885 alc_set_pin_output(codec, nid, pin_type);
19888 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19890 struct alc_spec *spec = codec->spec;
19891 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19893 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19894 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19898 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19900 struct alc_spec *spec = codec->spec;
19903 pin = spec->autocfg.hp_pins[0];
19905 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19906 pin = spec->autocfg.speaker_pins[0];
19908 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19911 /* pcm configuration: identical with ALC880 */
19912 #define alc680_pcm_analog_playback alc880_pcm_analog_playback
19913 #define alc680_pcm_analog_capture alc880_pcm_analog_capture
19914 #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19915 #define alc680_pcm_digital_playback alc880_pcm_digital_playback
19916 #define alc680_pcm_digital_capture alc880_pcm_digital_capture
19919 * BIOS auto configuration
19921 static int alc680_parse_auto_config(struct hda_codec *codec)
19923 struct alc_spec *spec = codec->spec;
19925 static hda_nid_t alc680_ignore[] = { 0 };
19927 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19932 if (!spec->autocfg.line_outs) {
19933 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19934 spec->multiout.max_channels = 2;
19935 spec->no_analog = 1;
19938 return 0; /* can't find valid BIOS pin config */
19940 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19944 spec->multiout.max_channels = 2;
19947 /* digital only support output */
19948 alc_auto_parse_digital(codec);
19949 if (spec->kctls.list)
19950 add_mixer(spec, spec->kctls.list);
19952 add_verb(spec, alc680_init_verbs);
19954 err = alc_auto_add_mic_boost(codec);
19961 #define alc680_auto_init_analog_input alc882_auto_init_analog_input
19963 /* init callback for auto-configuration model -- overriding the default init */
19964 static void alc680_auto_init(struct hda_codec *codec)
19966 struct alc_spec *spec = codec->spec;
19967 alc680_auto_init_multi_out(codec);
19968 alc680_auto_init_hp_out(codec);
19969 alc680_auto_init_analog_input(codec);
19970 alc_auto_init_digital(codec);
19971 if (spec->unsol_event)
19972 alc_inithook(codec);
19976 * configuration and preset
19978 static const char *alc680_models[ALC680_MODEL_LAST] = {
19979 [ALC680_BASE] = "base",
19980 [ALC680_AUTO] = "auto",
19983 static struct snd_pci_quirk alc680_cfg_tbl[] = {
19984 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19988 static struct alc_config_preset alc680_presets[] = {
19990 .mixers = { alc680_base_mixer },
19991 .cap_mixer = alc680_master_capture_mixer,
19992 .init_verbs = { alc680_init_verbs },
19993 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19994 .dac_nids = alc680_dac_nids,
19995 .dig_out_nid = ALC680_DIGOUT_NID,
19996 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19997 .channel_mode = alc680_modes,
19998 .unsol_event = alc680_unsol_event,
19999 .setup = alc680_base_setup,
20000 .init_hook = alc680_inithook,
20005 static int patch_alc680(struct hda_codec *codec)
20007 struct alc_spec *spec;
20011 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20015 codec->spec = spec;
20017 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20021 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20022 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20024 board_config = ALC680_AUTO;
20027 if (board_config == ALC680_AUTO) {
20028 /* automatic parse from the BIOS config */
20029 err = alc680_parse_auto_config(codec);
20035 "hda_codec: Cannot set up configuration "
20036 "from BIOS. Using base mode...\n");
20037 board_config = ALC680_BASE;
20041 if (board_config != ALC680_AUTO)
20042 setup_preset(codec, &alc680_presets[board_config]);
20044 spec->stream_analog_playback = &alc680_pcm_analog_playback;
20045 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
20046 spec->stream_digital_playback = &alc680_pcm_digital_playback;
20047 spec->stream_digital_capture = &alc680_pcm_digital_capture;
20049 if (!spec->adc_nids) {
20050 spec->adc_nids = alc680_adc_nids;
20051 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20054 if (!spec->cap_mixer)
20055 set_capture_mixer(codec);
20057 spec->vmaster_nid = 0x02;
20059 codec->patch_ops = alc_patch_ops;
20060 if (board_config == ALC680_AUTO)
20061 spec->init_hook = alc680_auto_init;
20069 static struct hda_codec_preset snd_hda_preset_realtek[] = {
20070 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20071 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20072 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
20073 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
20074 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
20075 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20076 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20077 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20078 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20079 .patch = patch_alc861 },
20080 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20081 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20082 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
20083 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
20084 .patch = patch_alc882 },
20085 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20086 .patch = patch_alc662 },
20087 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20088 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20089 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
20090 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
20091 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
20092 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
20093 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
20094 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
20095 .patch = patch_alc882 },
20096 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
20097 .patch = patch_alc882 },
20098 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
20099 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
20100 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
20101 .patch = patch_alc882 },
20102 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20103 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20104 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20105 {} /* terminator */
20108 MODULE_ALIAS("snd-hda-codec-id:10ec*");
20110 MODULE_LICENSE("GPL");
20111 MODULE_DESCRIPTION("Realtek HD-audio codec");
20113 static struct hda_codec_preset_list realtek_list = {
20114 .preset = snd_hda_preset_realtek,
20115 .owner = THIS_MODULE,
20118 static int __init patch_realtek_init(void)
20120 return snd_hda_add_codec_preset(&realtek_list);
20123 static void __exit patch_realtek_exit(void)
20125 snd_hda_delete_codec_preset(&realtek_list);
20128 module_init(patch_realtek_init)
20129 module_exit(patch_realtek_exit)