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;
285 #define MUX_IDX_UNDEF ((unsigned char)-1)
287 struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
296 unsigned int override:1;
297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
302 struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
315 /* codec parameterization */
316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
317 unsigned int num_mixers;
318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
321 const struct hda_verb *init_verbs[10]; /* initialization verbs
325 unsigned int num_init_verbs;
327 char stream_name_analog[32]; /* analog PCM stream */
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
333 char stream_name_digital[32]; /* digital PCM stream */
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
342 hda_nid_t alt_dac_nid;
343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
347 unsigned int num_adc_nids;
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
351 hda_nid_t mixer_nid; /* analog-mixer NID */
353 /* capture setup for dynamic dual-adc switch */
354 unsigned int cur_adc_idx;
356 unsigned int cur_adc_stream_tag;
357 unsigned int cur_adc_format;
360 unsigned int num_mux_defs;
361 const struct hda_input_mux *input_mux;
362 unsigned int cur_mux[3];
363 struct alc_mic_route ext_mic;
364 struct alc_mic_route dock_mic;
365 struct alc_mic_route int_mic;
368 const struct hda_channel_mode *channel_mode;
369 int num_channel_mode;
371 int const_channel_count;
372 int ext_channel_count;
374 /* PCM information */
375 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
377 /* dynamic controls, init_verbs and input_mux */
378 struct auto_pin_cfg autocfg;
379 struct alc_customize_define cdefine;
380 struct snd_array kctls;
381 struct hda_input_mux private_imux[3];
382 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
383 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
384 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
387 void (*init_hook)(struct hda_codec *codec);
388 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
389 #ifdef CONFIG_SND_HDA_POWER_SAVE
390 void (*power_hook)(struct hda_codec *codec);
392 void (*shutup)(struct hda_codec *codec);
394 /* for pin sensing */
395 unsigned int jack_present: 1;
396 unsigned int line_jack_present:1;
397 unsigned int master_mute:1;
398 unsigned int auto_mic:1;
399 unsigned int automute:1; /* HP automute enabled */
400 unsigned int detect_line:1; /* Line-out detection enabled */
401 unsigned int automute_lines:1; /* automute line-out as well */
402 unsigned int automute_hp_lo:1; /* both HP and LO available */
405 unsigned int no_analog :1; /* digital I/O only */
406 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
407 unsigned int single_input_src:1;
408 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
410 /* auto-mute control */
412 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
415 int codec_variant; /* flag for other variants */
417 /* for virtual master */
418 hda_nid_t vmaster_nid;
419 #ifdef CONFIG_SND_HDA_POWER_SAVE
420 struct hda_loopback_check loopback;
425 unsigned int pll_coef_idx, pll_coef_bit;
429 const struct alc_fixup *fixup_list;
430 const char *fixup_name;
434 struct alc_multi_io multi_io[4];
438 * configuration template - to be copied to the spec instance
440 struct alc_config_preset {
441 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
444 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
445 const struct hda_verb *init_verbs[5];
446 unsigned int num_dacs;
447 const hda_nid_t *dac_nids;
448 hda_nid_t dig_out_nid; /* optional */
449 hda_nid_t hp_nid; /* optional */
450 const hda_nid_t *slave_dig_outs;
451 unsigned int num_adc_nids;
452 const hda_nid_t *adc_nids;
453 const hda_nid_t *capsrc_nids;
454 hda_nid_t dig_in_nid;
455 unsigned int num_channel_mode;
456 const struct hda_channel_mode *channel_mode;
458 int const_channel_count;
459 unsigned int num_mux_defs;
460 const struct hda_input_mux *input_mux;
461 void (*unsol_event)(struct hda_codec *, unsigned int);
462 void (*setup)(struct hda_codec *);
463 void (*init_hook)(struct hda_codec *);
464 #ifdef CONFIG_SND_HDA_POWER_SAVE
465 const struct hda_amp_list *loopbacks;
466 void (*power_hook)(struct hda_codec *codec);
474 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
475 struct snd_ctl_elem_info *uinfo)
477 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
478 struct alc_spec *spec = codec->spec;
479 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
480 if (mux_idx >= spec->num_mux_defs)
482 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
484 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
487 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
488 struct snd_ctl_elem_value *ucontrol)
490 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
491 struct alc_spec *spec = codec->spec;
492 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
494 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
498 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
502 struct alc_spec *spec = codec->spec;
503 const struct hda_input_mux *imux;
504 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
505 unsigned int mux_idx;
506 hda_nid_t nid = spec->capsrc_nids ?
507 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
510 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
511 imux = &spec->input_mux[mux_idx];
512 if (!imux->num_items && mux_idx > 0)
513 imux = &spec->input_mux[0];
515 type = get_wcaps_type(get_wcaps(codec, nid));
516 if (type == AC_WID_AUD_MIX) {
517 /* Matrix-mixer style (e.g. ALC882) */
518 unsigned int *cur_val = &spec->cur_mux[adc_idx];
521 idx = ucontrol->value.enumerated.item[0];
522 if (idx >= imux->num_items)
523 idx = imux->num_items - 1;
526 for (i = 0; i < imux->num_items; i++) {
527 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
528 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
529 imux->items[i].index,
535 /* MUX style (e.g. ALC880) */
536 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
537 &spec->cur_mux[adc_idx]);
542 * channel mode setting
544 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_info *uinfo)
547 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548 struct alc_spec *spec = codec->spec;
549 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
550 spec->num_channel_mode);
553 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
554 struct snd_ctl_elem_value *ucontrol)
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 struct alc_spec *spec = codec->spec;
558 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
559 spec->num_channel_mode,
560 spec->ext_channel_count);
563 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
564 struct snd_ctl_elem_value *ucontrol)
566 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
567 struct alc_spec *spec = codec->spec;
568 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
569 spec->num_channel_mode,
570 &spec->ext_channel_count);
571 if (err >= 0 && !spec->const_channel_count) {
572 spec->multiout.max_channels = spec->ext_channel_count;
573 if (spec->need_dac_fix)
574 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
580 * Control the mode of pin widget settings via the mixer. "pc" is used
581 * instead of "%" to avoid consequences of accidentally treating the % as
582 * being part of a format specifier. Maximum allowed length of a value is
583 * 63 characters plus NULL terminator.
585 * Note: some retasking pin complexes seem to ignore requests for input
586 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
587 * are requested. Therefore order this list so that this behaviour will not
588 * cause problems when mixer clients move through the enum sequentially.
589 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
592 static const char * const alc_pin_mode_names[] = {
593 "Mic 50pc bias", "Mic 80pc bias",
594 "Line in", "Line out", "Headphone out",
596 static const unsigned char alc_pin_mode_values[] = {
597 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
599 /* The control can present all 5 options, or it can limit the options based
600 * in the pin being assumed to be exclusively an input or an output pin. In
601 * addition, "input" pins may or may not process the mic bias option
602 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
603 * accept requests for bias as of chip versions up to March 2006) and/or
604 * wiring in the computer.
606 #define ALC_PIN_DIR_IN 0x00
607 #define ALC_PIN_DIR_OUT 0x01
608 #define ALC_PIN_DIR_INOUT 0x02
609 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
610 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
612 /* Info about the pin modes supported by the different pin direction modes.
613 * For each direction the minimum and maximum values are given.
615 static const signed char alc_pin_mode_dir_info[5][2] = {
616 { 0, 2 }, /* ALC_PIN_DIR_IN */
617 { 3, 4 }, /* ALC_PIN_DIR_OUT */
618 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
619 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
620 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
622 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
623 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
624 #define alc_pin_mode_n_items(_dir) \
625 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
627 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_info *uinfo)
630 unsigned int item_num = uinfo->value.enumerated.item;
631 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
633 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
635 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
637 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
638 item_num = alc_pin_mode_min(dir);
639 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
643 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol)
647 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
648 hda_nid_t nid = kcontrol->private_value & 0xffff;
649 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
650 long *valp = ucontrol->value.integer.value;
651 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
652 AC_VERB_GET_PIN_WIDGET_CONTROL,
655 /* Find enumerated value for current pinctl setting */
656 i = alc_pin_mode_min(dir);
657 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
659 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
663 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
664 struct snd_ctl_elem_value *ucontrol)
667 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
668 hda_nid_t nid = kcontrol->private_value & 0xffff;
669 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
670 long val = *ucontrol->value.integer.value;
671 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
672 AC_VERB_GET_PIN_WIDGET_CONTROL,
675 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
676 val = alc_pin_mode_min(dir);
678 change = pinctl != alc_pin_mode_values[val];
680 /* Set pin mode to that requested */
681 snd_hda_codec_write_cache(codec, nid, 0,
682 AC_VERB_SET_PIN_WIDGET_CONTROL,
683 alc_pin_mode_values[val]);
685 /* Also enable the retasking pin's input/output as required
686 * for the requested pin mode. Enum values of 2 or less are
689 * Dynamically switching the input/output buffers probably
690 * reduces noise slightly (particularly on input) so we'll
691 * do it. However, having both input and output buffers
692 * enabled simultaneously doesn't seem to be problematic if
693 * this turns out to be necessary in the future.
696 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
697 HDA_AMP_MUTE, HDA_AMP_MUTE);
698 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
701 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
702 HDA_AMP_MUTE, HDA_AMP_MUTE);
703 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
710 #define ALC_PIN_MODE(xname, nid, dir) \
711 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
712 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
713 .info = alc_pin_mode_info, \
714 .get = alc_pin_mode_get, \
715 .put = alc_pin_mode_put, \
716 .private_value = nid | (dir<<16) }
718 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
719 * together using a mask with more than one bit set. This control is
720 * currently used only by the ALC260 test model. At this stage they are not
721 * needed for any "production" models.
723 #ifdef CONFIG_SND_DEBUG
724 #define alc_gpio_data_info snd_ctl_boolean_mono_info
726 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *ucontrol)
729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
730 hda_nid_t nid = kcontrol->private_value & 0xffff;
731 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
732 long *valp = ucontrol->value.integer.value;
733 unsigned int val = snd_hda_codec_read(codec, nid, 0,
734 AC_VERB_GET_GPIO_DATA, 0x00);
736 *valp = (val & mask) != 0;
739 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
740 struct snd_ctl_elem_value *ucontrol)
743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
744 hda_nid_t nid = kcontrol->private_value & 0xffff;
745 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
746 long val = *ucontrol->value.integer.value;
747 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
748 AC_VERB_GET_GPIO_DATA,
751 /* Set/unset the masked GPIO bit(s) as needed */
752 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
757 snd_hda_codec_write_cache(codec, nid, 0,
758 AC_VERB_SET_GPIO_DATA, gpio_data);
762 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
764 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
765 .info = alc_gpio_data_info, \
766 .get = alc_gpio_data_get, \
767 .put = alc_gpio_data_put, \
768 .private_value = nid | (mask<<16) }
769 #endif /* CONFIG_SND_DEBUG */
771 /* A switch control to allow the enabling of the digital IO pins on the
772 * ALC260. This is incredibly simplistic; the intention of this control is
773 * to provide something in the test model allowing digital outputs to be
774 * identified if present. If models are found which can utilise these
775 * outputs a more complete mixer control can be devised for those models if
778 #ifdef CONFIG_SND_DEBUG
779 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
781 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
782 struct snd_ctl_elem_value *ucontrol)
784 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
785 hda_nid_t nid = kcontrol->private_value & 0xffff;
786 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
787 long *valp = ucontrol->value.integer.value;
788 unsigned int val = snd_hda_codec_read(codec, nid, 0,
789 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
791 *valp = (val & mask) != 0;
794 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
795 struct snd_ctl_elem_value *ucontrol)
798 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
799 hda_nid_t nid = kcontrol->private_value & 0xffff;
800 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
801 long val = *ucontrol->value.integer.value;
802 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
803 AC_VERB_GET_DIGI_CONVERT_1,
806 /* Set/unset the masked control bit(s) as needed */
807 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
812 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
817 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
818 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
819 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
820 .info = alc_spdif_ctrl_info, \
821 .get = alc_spdif_ctrl_get, \
822 .put = alc_spdif_ctrl_put, \
823 .private_value = nid | (mask<<16) }
824 #endif /* CONFIG_SND_DEBUG */
826 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
827 * Again, this is only used in the ALC26x test models to help identify when
828 * the EAPD line must be asserted for features to work.
830 #ifdef CONFIG_SND_DEBUG
831 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
833 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
834 struct snd_ctl_elem_value *ucontrol)
836 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
837 hda_nid_t nid = kcontrol->private_value & 0xffff;
838 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
839 long *valp = ucontrol->value.integer.value;
840 unsigned int val = snd_hda_codec_read(codec, nid, 0,
841 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
843 *valp = (val & mask) != 0;
847 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
848 struct snd_ctl_elem_value *ucontrol)
851 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
852 hda_nid_t nid = kcontrol->private_value & 0xffff;
853 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
854 long val = *ucontrol->value.integer.value;
855 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
856 AC_VERB_GET_EAPD_BTLENABLE,
859 /* Set/unset the masked control bit(s) as needed */
860 change = (!val ? 0 : mask) != (ctrl_data & mask);
865 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
871 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
872 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
873 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
874 .info = alc_eapd_ctrl_info, \
875 .get = alc_eapd_ctrl_get, \
876 .put = alc_eapd_ctrl_put, \
877 .private_value = nid | (mask<<16) }
878 #endif /* CONFIG_SND_DEBUG */
881 * set up the input pin config (depending on the given auto-pin type)
883 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
886 unsigned int val = PIN_IN;
888 if (auto_pin_type == AUTO_PIN_MIC) {
891 oldval = snd_hda_codec_read(codec, nid, 0,
892 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
893 pincap = snd_hda_query_pin_caps(codec, nid);
894 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
895 /* if the default pin setup is vref50, we give it priority */
896 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
898 else if (pincap & AC_PINCAP_VREF_50)
900 else if (pincap & AC_PINCAP_VREF_100)
902 else if (pincap & AC_PINCAP_VREF_GRD)
905 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
908 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
910 struct alc_spec *spec = codec->spec;
911 struct auto_pin_cfg *cfg = &spec->autocfg;
913 if (!cfg->line_outs) {
914 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
915 cfg->line_out_pins[cfg->line_outs])
918 if (!cfg->speaker_outs) {
919 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
920 cfg->speaker_pins[cfg->speaker_outs])
924 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
925 cfg->hp_pins[cfg->hp_outs])
932 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
934 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
936 spec->mixers[spec->num_mixers++] = mix;
939 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
941 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
943 spec->init_verbs[spec->num_init_verbs++] = verb;
947 * set up from the preset table
949 static void setup_preset(struct hda_codec *codec,
950 const struct alc_config_preset *preset)
952 struct alc_spec *spec = codec->spec;
955 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
956 add_mixer(spec, preset->mixers[i]);
957 spec->cap_mixer = preset->cap_mixer;
958 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
960 add_verb(spec, preset->init_verbs[i]);
962 spec->channel_mode = preset->channel_mode;
963 spec->num_channel_mode = preset->num_channel_mode;
964 spec->need_dac_fix = preset->need_dac_fix;
965 spec->const_channel_count = preset->const_channel_count;
967 if (preset->const_channel_count)
968 spec->multiout.max_channels = preset->const_channel_count;
970 spec->multiout.max_channels = spec->channel_mode[0].channels;
971 spec->ext_channel_count = spec->channel_mode[0].channels;
973 spec->multiout.num_dacs = preset->num_dacs;
974 spec->multiout.dac_nids = preset->dac_nids;
975 spec->multiout.dig_out_nid = preset->dig_out_nid;
976 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
977 spec->multiout.hp_nid = preset->hp_nid;
979 spec->num_mux_defs = preset->num_mux_defs;
980 if (!spec->num_mux_defs)
981 spec->num_mux_defs = 1;
982 spec->input_mux = preset->input_mux;
984 spec->num_adc_nids = preset->num_adc_nids;
985 spec->adc_nids = preset->adc_nids;
986 spec->capsrc_nids = preset->capsrc_nids;
987 spec->dig_in_nid = preset->dig_in_nid;
989 spec->unsol_event = preset->unsol_event;
990 spec->init_hook = preset->init_hook;
991 #ifdef CONFIG_SND_HDA_POWER_SAVE
992 spec->power_hook = preset->power_hook;
993 spec->loopback.amplist = preset->loopbacks;
997 preset->setup(codec);
999 alc_fixup_autocfg_pin_nums(codec);
1002 /* Enable GPIO mask and set output */
1003 static const struct hda_verb alc_gpio1_init_verbs[] = {
1004 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1005 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1006 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1010 static const struct hda_verb alc_gpio2_init_verbs[] = {
1011 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1012 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1013 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1017 static const struct hda_verb alc_gpio3_init_verbs[] = {
1018 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1019 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1020 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1025 * Fix hardware PLL issue
1026 * On some codecs, the analog PLL gating control must be off while
1027 * the default value is 1.
1029 static void alc_fix_pll(struct hda_codec *codec)
1031 struct alc_spec *spec = codec->spec;
1036 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1037 spec->pll_coef_idx);
1038 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1039 AC_VERB_GET_PROC_COEF, 0);
1040 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1041 spec->pll_coef_idx);
1042 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1043 val & ~(1 << spec->pll_coef_bit));
1046 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1047 unsigned int coef_idx, unsigned int coef_bit)
1049 struct alc_spec *spec = codec->spec;
1050 spec->pll_nid = nid;
1051 spec->pll_coef_idx = coef_idx;
1052 spec->pll_coef_bit = coef_bit;
1056 static int alc_init_jacks(struct hda_codec *codec)
1058 #ifdef CONFIG_SND_HDA_INPUT_JACK
1059 struct alc_spec *spec = codec->spec;
1061 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1062 unsigned int mic_nid = spec->ext_mic.pin;
1063 unsigned int dock_nid = spec->dock_mic.pin;
1066 err = snd_hda_input_jack_add(codec, hp_nid,
1067 SND_JACK_HEADPHONE, NULL);
1070 snd_hda_input_jack_report(codec, hp_nid);
1074 err = snd_hda_input_jack_add(codec, mic_nid,
1075 SND_JACK_MICROPHONE, NULL);
1078 snd_hda_input_jack_report(codec, mic_nid);
1081 err = snd_hda_input_jack_add(codec, dock_nid,
1082 SND_JACK_MICROPHONE, NULL);
1085 snd_hda_input_jack_report(codec, dock_nid);
1087 #endif /* CONFIG_SND_HDA_INPUT_JACK */
1091 static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1095 for (i = 0; i < num_pins; i++) {
1096 hda_nid_t nid = pins[i];
1099 snd_hda_input_jack_report(codec, nid);
1100 present |= snd_hda_jack_detect(codec, nid);
1105 static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1106 bool mute, bool hp_out)
1108 struct alc_spec *spec = codec->spec;
1109 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1110 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1113 for (i = 0; i < num_pins; i++) {
1114 hda_nid_t nid = pins[i];
1117 switch (spec->automute_mode) {
1118 case ALC_AUTOMUTE_PIN:
1119 snd_hda_codec_write(codec, nid, 0,
1120 AC_VERB_SET_PIN_WIDGET_CONTROL,
1123 case ALC_AUTOMUTE_AMP:
1124 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1125 HDA_AMP_MUTE, mute_bits);
1127 case ALC_AUTOMUTE_MIXER:
1128 nid = spec->automute_mixer_nid[i];
1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1132 HDA_AMP_MUTE, mute_bits);
1133 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1134 HDA_AMP_MUTE, mute_bits);
1140 /* Toggle internal speakers muting */
1141 static void update_speakers(struct hda_codec *codec)
1143 struct alc_spec *spec = codec->spec;
1146 /* Control HP pins/amps depending on master_mute state;
1147 * in general, HP pins/amps control should be enabled in all cases,
1148 * but currently set only for master_mute, just to be safe
1150 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1151 spec->autocfg.hp_pins, spec->master_mute, true);
1153 if (!spec->automute)
1156 on = spec->jack_present | spec->line_jack_present;
1157 on |= spec->master_mute;
1158 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1159 spec->autocfg.speaker_pins, on, false);
1161 /* toggle line-out mutes if needed, too */
1162 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1163 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1164 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1166 if (!spec->automute_lines || !spec->automute)
1169 on = spec->jack_present;
1170 on |= spec->master_mute;
1171 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1172 spec->autocfg.line_out_pins, on, false);
1175 static void alc_hp_automute(struct hda_codec *codec)
1177 struct alc_spec *spec = codec->spec;
1179 if (!spec->automute)
1181 spec->jack_present =
1182 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1183 spec->autocfg.hp_pins);
1184 update_speakers(codec);
1187 static void alc_line_automute(struct hda_codec *codec)
1189 struct alc_spec *spec = codec->spec;
1191 if (!spec->automute || !spec->detect_line)
1193 spec->line_jack_present =
1194 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1195 spec->autocfg.line_out_pins);
1196 update_speakers(codec);
1199 #define get_connection_index(codec, mux, nid) \
1200 snd_hda_get_conn_index(codec, mux, nid, 0)
1202 /* switch the current ADC according to the jack state */
1203 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1205 struct alc_spec *spec = codec->spec;
1206 unsigned int present;
1209 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1211 spec->cur_adc_idx = 1;
1213 spec->cur_adc_idx = 0;
1214 new_adc = spec->adc_nids[spec->cur_adc_idx];
1215 if (spec->cur_adc && spec->cur_adc != new_adc) {
1216 /* stream is running, let's swap the current ADC */
1217 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1218 spec->cur_adc = new_adc;
1219 snd_hda_codec_setup_stream(codec, new_adc,
1220 spec->cur_adc_stream_tag, 0,
1221 spec->cur_adc_format);
1225 static void alc_mic_automute(struct hda_codec *codec)
1227 struct alc_spec *spec = codec->spec;
1228 struct alc_mic_route *dead1, *dead2, *alive;
1229 unsigned int present, type;
1232 if (!spec->auto_mic)
1234 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1236 if (snd_BUG_ON(!spec->adc_nids))
1239 if (spec->dual_adc_switch) {
1240 alc_dual_mic_adc_auto_switch(codec);
1244 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1246 alive = &spec->int_mic;
1247 dead1 = &spec->ext_mic;
1248 dead2 = &spec->dock_mic;
1250 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1252 alive = &spec->ext_mic;
1253 dead1 = &spec->int_mic;
1254 dead2 = &spec->dock_mic;
1256 if (!present && spec->dock_mic.pin > 0) {
1257 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1259 alive = &spec->dock_mic;
1260 dead1 = &spec->int_mic;
1261 dead2 = &spec->ext_mic;
1263 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1266 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1267 if (type == AC_WID_AUD_MIX) {
1268 /* Matrix-mixer style (e.g. ALC882) */
1269 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1273 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1275 HDA_AMP_MUTE, HDA_AMP_MUTE);
1277 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1279 HDA_AMP_MUTE, HDA_AMP_MUTE);
1281 /* MUX style (e.g. ALC880) */
1282 snd_hda_codec_write_cache(codec, cap_nid, 0,
1283 AC_VERB_SET_CONNECT_SEL,
1286 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1288 /* FIXME: analog mixer */
1291 /* unsolicited event for HP jack sensing */
1292 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1294 if (codec->vendor_id == 0x10ec0880)
1299 case ALC880_HP_EVENT:
1300 alc_hp_automute(codec);
1302 case ALC880_FRONT_EVENT:
1303 alc_line_automute(codec);
1305 case ALC880_MIC_EVENT:
1306 alc_mic_automute(codec);
1311 static void alc_inithook(struct hda_codec *codec)
1313 alc_hp_automute(codec);
1314 alc_line_automute(codec);
1315 alc_mic_automute(codec);
1318 /* additional initialization for ALC888 variants */
1319 static void alc888_coef_init(struct hda_codec *codec)
1323 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1324 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1325 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1326 if ((tmp & 0xf0) == 0x20)
1328 snd_hda_codec_read(codec, 0x20, 0,
1329 AC_VERB_SET_PROC_COEF, 0x830);
1332 snd_hda_codec_read(codec, 0x20, 0,
1333 AC_VERB_SET_PROC_COEF, 0x3030);
1336 static void alc889_coef_init(struct hda_codec *codec)
1340 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1341 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1342 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1343 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1346 /* turn on/off EAPD control (only if available) */
1347 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1349 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1351 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1352 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1356 /* turn on/off EAPD controls of the codec */
1357 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1359 /* We currently only handle front, HP */
1360 static hda_nid_t pins[] = {
1361 0x0f, 0x10, 0x14, 0x15, 0
1364 for (p = pins; *p; p++)
1365 set_eapd(codec, *p, on);
1368 /* generic shutup callback;
1369 * just turning off EPAD and a little pause for avoiding pop-noise
1371 static void alc_eapd_shutup(struct hda_codec *codec)
1373 alc_auto_setup_eapd(codec, false);
1377 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1381 alc_auto_setup_eapd(codec, true);
1383 case ALC_INIT_GPIO1:
1384 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1386 case ALC_INIT_GPIO2:
1387 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1389 case ALC_INIT_GPIO3:
1390 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1392 case ALC_INIT_DEFAULT:
1393 switch (codec->vendor_id) {
1395 snd_hda_codec_write(codec, 0x1a, 0,
1396 AC_VERB_SET_COEF_INDEX, 7);
1397 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1398 AC_VERB_GET_PROC_COEF, 0);
1399 snd_hda_codec_write(codec, 0x1a, 0,
1400 AC_VERB_SET_COEF_INDEX, 7);
1401 snd_hda_codec_write(codec, 0x1a, 0,
1402 AC_VERB_SET_PROC_COEF,
1411 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1412 alc889_coef_init(codec);
1415 alc888_coef_init(codec);
1417 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1420 snd_hda_codec_write(codec, 0x20, 0,
1421 AC_VERB_SET_COEF_INDEX, 7);
1422 tmp = snd_hda_codec_read(codec, 0x20, 0,
1423 AC_VERB_GET_PROC_COEF, 0);
1424 snd_hda_codec_write(codec, 0x20, 0,
1425 AC_VERB_SET_COEF_INDEX, 7);
1426 snd_hda_codec_write(codec, 0x20, 0,
1427 AC_VERB_SET_PROC_COEF,
1436 static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1437 struct snd_ctl_elem_info *uinfo)
1439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1440 struct alc_spec *spec = codec->spec;
1441 static const char * const texts2[] = {
1442 "Disabled", "Enabled"
1444 static const char * const texts3[] = {
1445 "Disabled", "Speaker Only", "Line-Out+Speaker"
1447 const char * const *texts;
1449 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1451 if (spec->automute_hp_lo) {
1452 uinfo->value.enumerated.items = 3;
1455 uinfo->value.enumerated.items = 2;
1458 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1459 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1460 strcpy(uinfo->value.enumerated.name,
1461 texts[uinfo->value.enumerated.item]);
1465 static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1466 struct snd_ctl_elem_value *ucontrol)
1468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1469 struct alc_spec *spec = codec->spec;
1471 if (!spec->automute)
1473 else if (!spec->automute_lines)
1477 ucontrol->value.enumerated.item[0] = val;
1481 static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1482 struct snd_ctl_elem_value *ucontrol)
1484 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1485 struct alc_spec *spec = codec->spec;
1487 switch (ucontrol->value.enumerated.item[0]) {
1489 if (!spec->automute)
1494 if (spec->automute && !spec->automute_lines)
1497 spec->automute_lines = 0;
1500 if (!spec->automute_hp_lo)
1502 if (spec->automute && spec->automute_lines)
1505 spec->automute_lines = 1;
1510 update_speakers(codec);
1514 static const struct snd_kcontrol_new alc_automute_mode_enum = {
1515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 .name = "Auto-Mute Mode",
1517 .info = alc_automute_mode_info,
1518 .get = alc_automute_mode_get,
1519 .put = alc_automute_mode_put,
1522 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1524 static int alc_add_automute_mode_enum(struct hda_codec *codec)
1526 struct alc_spec *spec = codec->spec;
1527 struct snd_kcontrol_new *knew;
1529 knew = alc_kcontrol_new(spec);
1532 *knew = alc_automute_mode_enum;
1533 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1539 static void alc_init_auto_hp(struct hda_codec *codec)
1541 struct alc_spec *spec = codec->spec;
1542 struct auto_pin_cfg *cfg = &spec->autocfg;
1546 if (cfg->hp_pins[0])
1548 if (cfg->line_out_pins[0])
1550 if (cfg->speaker_pins[0])
1552 if (present < 2) /* need two different output types */
1555 spec->automute_hp_lo = 1; /* both HP and LO automute */
1557 if (!cfg->speaker_pins[0]) {
1558 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1559 sizeof(cfg->speaker_pins));
1560 cfg->speaker_outs = cfg->line_outs;
1563 if (!cfg->hp_pins[0]) {
1564 memcpy(cfg->hp_pins, cfg->line_out_pins,
1565 sizeof(cfg->hp_pins));
1566 cfg->hp_outs = cfg->line_outs;
1569 for (i = 0; i < cfg->hp_outs; i++) {
1570 hda_nid_t nid = cfg->hp_pins[i];
1571 if (!is_jack_detectable(codec, nid))
1573 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1575 snd_hda_codec_write_cache(codec, nid, 0,
1576 AC_VERB_SET_UNSOLICITED_ENABLE,
1577 AC_USRSP_EN | ALC880_HP_EVENT);
1579 spec->automute_mode = ALC_AUTOMUTE_PIN;
1581 if (spec->automute && cfg->line_out_pins[0] &&
1582 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1583 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1584 for (i = 0; i < cfg->line_outs; i++) {
1585 hda_nid_t nid = cfg->line_out_pins[i];
1586 if (!is_jack_detectable(codec, nid))
1588 snd_printdd("realtek: Enable Line-Out auto-muting "
1589 "on NID 0x%x\n", nid);
1590 snd_hda_codec_write_cache(codec, nid, 0,
1591 AC_VERB_SET_UNSOLICITED_ENABLE,
1592 AC_USRSP_EN | ALC880_FRONT_EVENT);
1593 spec->detect_line = 1;
1595 spec->automute_lines = spec->detect_line;
1598 if (spec->automute) {
1599 /* create a control for automute mode */
1600 alc_add_automute_mode_enum(codec);
1601 spec->unsol_event = alc_sku_unsol_event;
1605 static void alc_init_auto_mic(struct hda_codec *codec)
1607 struct alc_spec *spec = codec->spec;
1608 struct auto_pin_cfg *cfg = &spec->autocfg;
1609 hda_nid_t fixed, ext, dock;
1612 fixed = ext = dock = 0;
1613 for (i = 0; i < cfg->num_inputs; i++) {
1614 hda_nid_t nid = cfg->inputs[i].pin;
1615 unsigned int defcfg;
1616 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1617 switch (snd_hda_get_input_pin_attr(defcfg)) {
1618 case INPUT_PIN_ATTR_INT:
1620 return; /* already occupied */
1621 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1622 return; /* invalid type */
1625 case INPUT_PIN_ATTR_UNUSED:
1626 return; /* invalid entry */
1627 case INPUT_PIN_ATTR_DOCK:
1629 return; /* already occupied */
1630 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1631 return; /* invalid type */
1636 return; /* already occupied */
1637 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1638 return; /* invalid type */
1649 if (!is_jack_detectable(codec, ext))
1650 return; /* no unsol support */
1651 if (dock && !is_jack_detectable(codec, dock))
1652 return; /* no unsol support */
1653 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1655 spec->ext_mic.pin = ext;
1656 spec->dock_mic.pin = dock;
1657 spec->int_mic.pin = fixed;
1658 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1659 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1660 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1662 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1663 AC_VERB_SET_UNSOLICITED_ENABLE,
1664 AC_USRSP_EN | ALC880_MIC_EVENT);
1665 spec->unsol_event = alc_sku_unsol_event;
1668 /* Could be any non-zero and even value. When used as fixup, tells
1669 * the driver to ignore any present sku defines.
1671 #define ALC_FIXUP_SKU_IGNORE (2)
1673 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1675 unsigned int ass, tmp, i;
1677 struct alc_spec *spec = codec->spec;
1679 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1681 if (spec->cdefine.fixup) {
1682 ass = spec->cdefine.sku_cfg;
1683 if (ass == ALC_FIXUP_SKU_IGNORE)
1688 ass = codec->subsystem_id & 0xffff;
1689 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1693 if (codec->vendor_id == 0x10ec0260)
1695 ass = snd_hda_codec_get_pincfg(codec, nid);
1698 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1699 codec->chip_name, ass);
1705 for (i = 1; i < 16; i++) {
1709 if (((ass >> 16) & 0xf) != tmp)
1712 spec->cdefine.port_connectivity = ass >> 30;
1713 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1714 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1715 spec->cdefine.customization = ass >> 8;
1717 spec->cdefine.sku_cfg = ass;
1718 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1719 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1720 spec->cdefine.swap = (ass & 0x2) >> 1;
1721 spec->cdefine.override = ass & 0x1;
1723 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1724 nid, spec->cdefine.sku_cfg);
1725 snd_printd("SKU: port_connectivity=0x%x\n",
1726 spec->cdefine.port_connectivity);
1727 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1728 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1729 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1730 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1731 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1732 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1733 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1738 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1741 for (i = 0; i < nums; i++)
1747 /* check subsystem ID and set up device-specific initialization;
1748 * return 1 if initialized, 0 if invalid SSID
1750 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1751 * 31 ~ 16 : Manufacture ID
1753 * 7 ~ 0 : Assembly ID
1754 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1756 static int alc_subsystem_id(struct hda_codec *codec,
1757 hda_nid_t porta, hda_nid_t porte,
1758 hda_nid_t portd, hda_nid_t porti)
1760 unsigned int ass, tmp, i;
1762 struct alc_spec *spec = codec->spec;
1764 if (spec->cdefine.fixup) {
1765 ass = spec->cdefine.sku_cfg;
1766 if (ass == ALC_FIXUP_SKU_IGNORE)
1771 ass = codec->subsystem_id & 0xffff;
1772 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1775 /* invalid SSID, check the special NID pin defcfg instead */
1777 * 31~30 : port connectivity
1780 * 19~16 : Check sum (15:1)
1785 if (codec->vendor_id == 0x10ec0260)
1787 ass = snd_hda_codec_get_pincfg(codec, nid);
1788 snd_printd("realtek: No valid SSID, "
1789 "checking pincfg 0x%08x for NID 0x%x\n",
1793 if ((ass >> 30) != 1) /* no physical connection */
1798 for (i = 1; i < 16; i++) {
1802 if (((ass >> 16) & 0xf) != tmp)
1805 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1806 ass & 0xffff, codec->vendor_id);
1810 * 2 : 0 --> Desktop, 1 --> Laptop
1811 * 3~5 : External Amplifier control
1814 tmp = (ass & 0x38) >> 3; /* external Amp control */
1817 spec->init_amp = ALC_INIT_GPIO1;
1820 spec->init_amp = ALC_INIT_GPIO2;
1823 spec->init_amp = ALC_INIT_GPIO3;
1827 spec->init_amp = ALC_INIT_DEFAULT;
1831 /* is laptop or Desktop and enable the function "Mute internal speaker
1832 * when the external headphone out jack is plugged"
1834 if (!(ass & 0x8000))
1837 * 10~8 : Jack location
1838 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1840 * 15 : 1 --> enable the function "Mute internal speaker
1841 * when the external headphone out jack is plugged"
1843 if (!spec->autocfg.hp_pins[0]) {
1845 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1856 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1857 spec->autocfg.line_outs))
1859 spec->autocfg.hp_pins[0] = nid;
1864 static void alc_ssid_check(struct hda_codec *codec,
1865 hda_nid_t porta, hda_nid_t porte,
1866 hda_nid_t portd, hda_nid_t porti)
1868 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1869 struct alc_spec *spec = codec->spec;
1870 snd_printd("realtek: "
1871 "Enable default setup for auto mode as fallback\n");
1872 spec->init_amp = ALC_INIT_DEFAULT;
1875 alc_init_auto_hp(codec);
1876 alc_init_auto_mic(codec);
1880 * Fix-up pin default configurations and add default verbs
1888 struct alc_model_fixup {
1899 const struct alc_pincfg *pins;
1900 const struct hda_verb *verbs;
1901 void (*func)(struct hda_codec *codec,
1902 const struct alc_fixup *fix,
1916 ALC_FIXUP_ACT_PRE_PROBE,
1917 ALC_FIXUP_ACT_PROBE,
1921 static void alc_apply_fixup(struct hda_codec *codec, int action)
1923 struct alc_spec *spec = codec->spec;
1924 int id = spec->fixup_id;
1925 #ifdef CONFIG_SND_DEBUG_VERBOSE
1926 const char *modelname = spec->fixup_name;
1930 if (!spec->fixup_list)
1934 const struct alc_fixup *fix = spec->fixup_list + id;
1935 const struct alc_pincfg *cfg;
1937 switch (fix->type) {
1939 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1941 snd_printdd(KERN_INFO "hda_codec: %s: "
1942 "Apply sku override for %s\n",
1943 codec->chip_name, modelname);
1944 spec->cdefine.sku_cfg = fix->v.sku;
1945 spec->cdefine.fixup = 1;
1947 case ALC_FIXUP_PINS:
1949 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1951 snd_printdd(KERN_INFO "hda_codec: %s: "
1952 "Apply pincfg for %s\n",
1953 codec->chip_name, modelname);
1954 for (; cfg->nid; cfg++)
1955 snd_hda_codec_set_pincfg(codec, cfg->nid,
1958 case ALC_FIXUP_VERBS:
1959 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1961 snd_printdd(KERN_INFO "hda_codec: %s: "
1962 "Apply fix-verbs for %s\n",
1963 codec->chip_name, modelname);
1964 add_verb(codec->spec, fix->v.verbs);
1966 case ALC_FIXUP_FUNC:
1969 snd_printdd(KERN_INFO "hda_codec: %s: "
1970 "Apply fix-func for %s\n",
1971 codec->chip_name, modelname);
1972 fix->v.func(codec, fix, action);
1975 snd_printk(KERN_ERR "hda_codec: %s: "
1976 "Invalid fixup type %d\n",
1977 codec->chip_name, fix->type);
1988 static void alc_pick_fixup(struct hda_codec *codec,
1989 const struct alc_model_fixup *models,
1990 const struct snd_pci_quirk *quirk,
1991 const struct alc_fixup *fixlist)
1993 struct alc_spec *spec = codec->spec;
1995 const char *name = NULL;
1997 if (codec->modelname && models) {
1998 while (models->name) {
1999 if (!strcmp(codec->modelname, models->name)) {
2001 name = models->name;
2008 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2011 #ifdef CONFIG_SND_DEBUG_VERBOSE
2017 spec->fixup_id = id;
2019 spec->fixup_list = fixlist;
2020 spec->fixup_name = name;
2024 static int alc_read_coef_idx(struct hda_codec *codec,
2025 unsigned int coef_idx)
2028 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2030 val = snd_hda_codec_read(codec, 0x20, 0,
2031 AC_VERB_GET_PROC_COEF, 0);
2035 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2036 unsigned int coef_val)
2038 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2040 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2044 /* set right pin controls for digital I/O */
2045 static void alc_auto_init_digital(struct hda_codec *codec)
2047 struct alc_spec *spec = codec->spec;
2051 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2052 pin = spec->autocfg.dig_out_pins[i];
2055 snd_hda_codec_write(codec, pin, 0,
2056 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2058 dac = spec->multiout.dig_out_nid;
2060 dac = spec->slave_dig_outs[i - 1];
2061 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
2063 snd_hda_codec_write(codec, dac, 0,
2064 AC_VERB_SET_AMP_GAIN_MUTE,
2067 pin = spec->autocfg.dig_in_pin;
2069 snd_hda_codec_write(codec, pin, 0,
2070 AC_VERB_SET_PIN_WIDGET_CONTROL,
2074 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2075 static void alc_auto_parse_digital(struct hda_codec *codec)
2077 struct alc_spec *spec = codec->spec;
2081 /* support multiple SPDIFs; the secondary is set up as a slave */
2082 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2084 err = snd_hda_get_connections(codec,
2085 spec->autocfg.dig_out_pins[i],
2086 conn, ARRAY_SIZE(conn));
2089 dig_nid = conn[0]; /* assume the first element is audio-out */
2091 spec->multiout.dig_out_nid = dig_nid;
2092 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2094 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2095 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2097 spec->slave_dig_outs[i - 1] = dig_nid;
2101 if (spec->autocfg.dig_in_pin) {
2102 dig_nid = codec->start_nid;
2103 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2104 unsigned int wcaps = get_wcaps(codec, dig_nid);
2105 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2107 if (!(wcaps & AC_WCAP_DIGITAL))
2109 if (!(wcaps & AC_WCAP_CONN_LIST))
2111 err = get_connection_index(codec, dig_nid,
2112 spec->autocfg.dig_in_pin);
2114 spec->dig_in_nid = dig_nid;
2128 static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2129 /* Mic-in jack as mic in */
2130 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2131 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2132 /* Line-in jack as Line in */
2133 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2134 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2135 /* Line-Out as Front */
2136 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2143 static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2144 /* Mic-in jack as mic in */
2145 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2146 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2147 /* Line-in jack as Surround */
2148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2150 /* Line-Out as Front */
2151 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2158 static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2159 /* Mic-in jack as CLFE */
2160 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2161 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2162 /* Line-in jack as Surround */
2163 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2164 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2165 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2166 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2173 static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2174 /* Mic-in jack as CLFE */
2175 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2176 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2177 /* Line-in jack as Surround */
2178 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2179 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2180 /* Line-Out as Side */
2181 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2185 static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2186 { 2, alc888_4ST_ch2_intel_init },
2187 { 4, alc888_4ST_ch4_intel_init },
2188 { 6, alc888_4ST_ch6_intel_init },
2189 { 8, alc888_4ST_ch8_intel_init },
2193 * ALC888 Fujitsu Siemens Amillo xa3530
2196 static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2197 /* Front Mic: set to PIN_IN (empty by default) */
2198 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2199 /* Connect Internal HP to Front */
2200 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2201 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2202 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2203 /* Connect Bass HP to Front */
2204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2206 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2207 /* Connect Line-Out side jack (SPDIF) to Side */
2208 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2209 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2210 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2211 /* Connect Mic jack to CLFE */
2212 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2214 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2215 /* Connect Line-in jack to Surround */
2216 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2217 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2218 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2219 /* Connect HP out jack to Front */
2220 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2221 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2222 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2223 /* Enable unsolicited event for HP jack and Line-out jack */
2224 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2225 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2229 static void alc889_automute_setup(struct hda_codec *codec)
2231 struct alc_spec *spec = codec->spec;
2233 spec->autocfg.hp_pins[0] = 0x15;
2234 spec->autocfg.speaker_pins[0] = 0x14;
2235 spec->autocfg.speaker_pins[1] = 0x16;
2236 spec->autocfg.speaker_pins[2] = 0x17;
2237 spec->autocfg.speaker_pins[3] = 0x19;
2238 spec->autocfg.speaker_pins[4] = 0x1a;
2240 spec->automute_mode = ALC_AUTOMUTE_AMP;
2243 static void alc889_intel_init_hook(struct hda_codec *codec)
2245 alc889_coef_init(codec);
2246 alc_hp_automute(codec);
2249 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2251 struct alc_spec *spec = codec->spec;
2253 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2254 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2255 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2256 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2258 spec->automute_mode = ALC_AUTOMUTE_AMP;
2262 * ALC888 Acer Aspire 4930G model
2265 static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2266 /* Front Mic: set to PIN_IN (empty by default) */
2267 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2268 /* Unselect Front Mic by default in input mixer 3 */
2269 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2270 /* Enable unsolicited event for HP jack */
2271 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2272 /* Connect Internal HP to front */
2273 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2274 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2276 /* Connect HP out to front */
2277 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2278 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2279 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2280 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2285 * ALC888 Acer Aspire 6530G model
2288 static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2289 /* Route to built-in subwoofer as well as speakers */
2290 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2291 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2292 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2293 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2294 /* Bias voltage on for external mic port */
2295 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2296 /* Front Mic: set to PIN_IN (empty by default) */
2297 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2298 /* Unselect Front Mic by default in input mixer 3 */
2299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2300 /* Enable unsolicited event for HP jack */
2301 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2302 /* Enable speaker output */
2303 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2304 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2305 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2306 /* Enable headphone output */
2307 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2309 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2310 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2315 *ALC888 Acer Aspire 7730G model
2318 static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2319 /* Bias voltage on for external mic port */
2320 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2321 /* Front Mic: set to PIN_IN (empty by default) */
2322 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2323 /* Unselect Front Mic by default in input mixer 3 */
2324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2325 /* Enable unsolicited event for HP jack */
2326 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2327 /* Enable speaker output */
2328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2329 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2330 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2331 /* Enable headphone output */
2332 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2333 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2334 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2335 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2336 /*Enable internal subwoofer */
2337 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2338 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2339 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2340 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2345 * ALC889 Acer Aspire 8930G model
2348 static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2349 /* Front Mic: set to PIN_IN (empty by default) */
2350 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2351 /* Unselect Front Mic by default in input mixer 3 */
2352 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2353 /* Enable unsolicited event for HP jack */
2354 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2355 /* Connect Internal Front to Front */
2356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2358 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2359 /* Connect Internal Rear to Rear */
2360 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2361 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2362 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2363 /* Connect Internal CLFE to CLFE */
2364 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2365 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2366 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2367 /* Connect HP out to Front */
2368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2370 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2371 /* Enable all DACs */
2372 /* DAC DISABLE/MUTE 1? */
2373 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2374 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2375 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2376 /* DAC DISABLE/MUTE 2? */
2377 /* some bit here disables the other DACs. Init=0x4900 */
2378 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2379 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2381 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2382 * which makes the stereo useless. However, either the mic or the ALC889
2383 * makes the signal become a difference/sum signal instead of standard
2384 * stereo, which is annoying. So instead we flip this bit which makes the
2385 * codec replicate the sum signal to both channels, turning it into a
2388 /* DMIC_CONTROL? Init value = 0x0001 */
2389 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2390 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2394 static const struct hda_input_mux alc888_2_capture_sources[2] = {
2395 /* Front mic only available on one ADC */
2402 { "Front Mic", 0xb },
2415 static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2416 /* Interal mic only available on one ADC */
2423 { "Input Mix", 0xa },
2424 { "Internal Mic", 0xb },
2433 { "Input Mix", 0xa },
2438 static const struct hda_input_mux alc889_capture_sources[3] = {
2439 /* Digital mic only available on first "ADC" */
2446 { "Front Mic", 0xb },
2447 { "Input Mix", 0xa },
2456 { "Input Mix", 0xa },
2465 { "Input Mix", 0xa },
2470 static const struct snd_kcontrol_new alc888_base_mixer[] = {
2471 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2472 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2473 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2474 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2475 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2477 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2478 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2479 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2481 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2482 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2483 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2484 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2485 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2486 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2487 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2488 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2492 static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2493 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2494 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2495 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2496 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2497 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2499 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2503 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2504 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2505 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2509 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2514 static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2515 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2516 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2517 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2518 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2519 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2521 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2522 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2523 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2525 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2527 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2528 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2533 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2535 struct alc_spec *spec = codec->spec;
2537 spec->autocfg.hp_pins[0] = 0x15;
2538 spec->autocfg.speaker_pins[0] = 0x14;
2539 spec->autocfg.speaker_pins[1] = 0x16;
2540 spec->autocfg.speaker_pins[2] = 0x17;
2542 spec->automute_mode = ALC_AUTOMUTE_AMP;
2545 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2547 struct alc_spec *spec = codec->spec;
2549 spec->autocfg.hp_pins[0] = 0x15;
2550 spec->autocfg.speaker_pins[0] = 0x14;
2551 spec->autocfg.speaker_pins[1] = 0x16;
2552 spec->autocfg.speaker_pins[2] = 0x17;
2554 spec->automute_mode = ALC_AUTOMUTE_AMP;
2557 static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2559 struct alc_spec *spec = codec->spec;
2561 spec->autocfg.hp_pins[0] = 0x15;
2562 spec->autocfg.speaker_pins[0] = 0x14;
2563 spec->autocfg.speaker_pins[1] = 0x16;
2564 spec->autocfg.speaker_pins[2] = 0x17;
2566 spec->automute_mode = ALC_AUTOMUTE_AMP;
2569 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2571 struct alc_spec *spec = codec->spec;
2573 spec->autocfg.hp_pins[0] = 0x15;
2574 spec->autocfg.speaker_pins[0] = 0x14;
2575 spec->autocfg.speaker_pins[1] = 0x16;
2576 spec->autocfg.speaker_pins[2] = 0x1b;
2578 spec->automute_mode = ALC_AUTOMUTE_AMP;
2582 * ALC880 3-stack model
2584 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2585 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2586 * F-Mic = 0x1b, HP = 0x19
2589 static const hda_nid_t alc880_dac_nids[4] = {
2590 /* front, rear, clfe, rear_surr */
2591 0x02, 0x05, 0x04, 0x03
2594 static const hda_nid_t alc880_adc_nids[3] = {
2599 /* The datasheet says the node 0x07 is connected from inputs,
2600 * but it shows zero connection in the real implementation on some devices.
2601 * Note: this is a 915GAV bug, fixed on 915GLV
2603 static const hda_nid_t alc880_adc_nids_alt[2] = {
2608 #define ALC880_DIGOUT_NID 0x06
2609 #define ALC880_DIGIN_NID 0x0a
2611 static const struct hda_input_mux alc880_capture_source = {
2615 { "Front Mic", 0x3 },
2621 /* channel source setting (2/6 channel selection for 3-stack) */
2623 static const struct hda_verb alc880_threestack_ch2_init[] = {
2624 /* set line-in to input, mute it */
2625 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2626 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2627 /* set mic-in to input vref 80%, mute it */
2628 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2629 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2634 static const struct hda_verb alc880_threestack_ch6_init[] = {
2635 /* set line-in to output, unmute it */
2636 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2637 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2638 /* set mic-in to output, unmute it */
2639 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2640 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2644 static const struct hda_channel_mode alc880_threestack_modes[2] = {
2645 { 2, alc880_threestack_ch2_init },
2646 { 6, alc880_threestack_ch6_init },
2649 static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2650 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2651 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2652 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2653 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2654 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2655 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2656 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2657 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2658 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2659 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2660 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2661 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2663 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2664 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2665 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2666 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2668 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2669 .name = "Channel Mode",
2670 .info = alc_ch_mode_info,
2671 .get = alc_ch_mode_get,
2672 .put = alc_ch_mode_put,
2677 /* capture mixer elements */
2678 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2679 struct snd_ctl_elem_info *uinfo)
2681 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2682 struct alc_spec *spec = codec->spec;
2686 mutex_lock(&codec->control_mutex);
2687 if (spec->vol_in_capsrc)
2688 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
2690 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
2691 kcontrol->private_value = val;
2692 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2693 mutex_unlock(&codec->control_mutex);
2697 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2698 unsigned int size, unsigned int __user *tlv)
2700 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2701 struct alc_spec *spec = codec->spec;
2705 mutex_lock(&codec->control_mutex);
2706 if (spec->vol_in_capsrc)
2707 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
2709 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
2710 kcontrol->private_value = val;
2711 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2712 mutex_unlock(&codec->control_mutex);
2716 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2717 struct snd_ctl_elem_value *ucontrol);
2719 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2720 struct snd_ctl_elem_value *ucontrol,
2721 getput_call_t func, bool check_adc_switch)
2723 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2724 struct alc_spec *spec = codec->spec;
2727 mutex_lock(&codec->control_mutex);
2728 if (check_adc_switch && spec->dual_adc_switch) {
2729 for (i = 0; i < spec->num_adc_nids; i++) {
2730 kcontrol->private_value =
2731 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2733 err = func(kcontrol, ucontrol);
2738 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2739 if (spec->vol_in_capsrc)
2740 kcontrol->private_value =
2741 HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
2744 kcontrol->private_value =
2745 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2747 err = func(kcontrol, ucontrol);
2750 mutex_unlock(&codec->control_mutex);
2754 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2755 struct snd_ctl_elem_value *ucontrol)
2757 return alc_cap_getput_caller(kcontrol, ucontrol,
2758 snd_hda_mixer_amp_volume_get, false);
2761 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2762 struct snd_ctl_elem_value *ucontrol)
2764 return alc_cap_getput_caller(kcontrol, ucontrol,
2765 snd_hda_mixer_amp_volume_put, true);
2768 /* capture mixer elements */
2769 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2771 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2772 struct snd_ctl_elem_value *ucontrol)
2774 return alc_cap_getput_caller(kcontrol, ucontrol,
2775 snd_hda_mixer_amp_switch_get, false);
2778 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2779 struct snd_ctl_elem_value *ucontrol)
2781 return alc_cap_getput_caller(kcontrol, ucontrol,
2782 snd_hda_mixer_amp_switch_put, true);
2785 #define _DEFINE_CAPMIX(num) \
2787 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2788 .name = "Capture Switch", \
2789 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2791 .info = alc_cap_sw_info, \
2792 .get = alc_cap_sw_get, \
2793 .put = alc_cap_sw_put, \
2796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2797 .name = "Capture Volume", \
2798 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2799 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2800 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2802 .info = alc_cap_vol_info, \
2803 .get = alc_cap_vol_get, \
2804 .put = alc_cap_vol_put, \
2805 .tlv = { .c = alc_cap_vol_tlv }, \
2808 #define _DEFINE_CAPSRC(num) \
2810 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2811 /* .name = "Capture Source", */ \
2812 .name = "Input Source", \
2814 .info = alc_mux_enum_info, \
2815 .get = alc_mux_enum_get, \
2816 .put = alc_mux_enum_put, \
2819 #define DEFINE_CAPMIX(num) \
2820 static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2821 _DEFINE_CAPMIX(num), \
2822 _DEFINE_CAPSRC(num), \
2826 #define DEFINE_CAPMIX_NOSRC(num) \
2827 static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2828 _DEFINE_CAPMIX(num), \
2832 /* up to three ADCs */
2836 DEFINE_CAPMIX_NOSRC(1);
2837 DEFINE_CAPMIX_NOSRC(2);
2838 DEFINE_CAPMIX_NOSRC(3);
2841 * ALC880 5-stack model
2843 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2845 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2846 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2849 /* additional mixers to alc880_three_stack_mixer */
2850 static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2851 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2852 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2856 /* channel source setting (6/8 channel selection for 5-stack) */
2858 static const struct hda_verb alc880_fivestack_ch6_init[] = {
2859 /* set line-in to input, mute it */
2860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2866 static const struct hda_verb alc880_fivestack_ch8_init[] = {
2867 /* set line-in to output, unmute it */
2868 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2869 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2873 static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2874 { 6, alc880_fivestack_ch6_init },
2875 { 8, alc880_fivestack_ch8_init },
2880 * ALC880 6-stack model
2882 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2883 * Side = 0x05 (0x0f)
2884 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2885 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2888 static const hda_nid_t alc880_6st_dac_nids[4] = {
2889 /* front, rear, clfe, rear_surr */
2890 0x02, 0x03, 0x04, 0x05
2893 static const struct hda_input_mux alc880_6stack_capture_source = {
2897 { "Front Mic", 0x1 },
2903 /* fixed 8-channels */
2904 static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2908 static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2909 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2910 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2911 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2912 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2913 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2914 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2915 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2916 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2917 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2918 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2919 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2920 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2921 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2922 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2923 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2924 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2925 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2926 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2928 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2929 .name = "Channel Mode",
2930 .info = alc_ch_mode_info,
2931 .get = alc_ch_mode_get,
2932 .put = alc_ch_mode_put,
2941 * W810 has rear IO for:
2944 * Center/LFE (DAC 04)
2947 * The system also has a pair of internal speakers, and a headphone jack.
2948 * These are both connected to Line2 on the codec, hence to DAC 02.
2950 * There is a variable resistor to control the speaker or headphone
2951 * volume. This is a hardware-only device without a software API.
2953 * Plugging headphones in will disable the internal speakers. This is
2954 * implemented in hardware, not via the driver using jack sense. In
2955 * a similar fashion, plugging into the rear socket marked "front" will
2956 * disable both the speakers and headphones.
2958 * For input, there's a microphone jack, and an "audio in" jack.
2959 * These may not do anything useful with this driver yet, because I
2960 * haven't setup any initialization verbs for these yet...
2963 static const hda_nid_t alc880_w810_dac_nids[3] = {
2964 /* front, rear/surround, clfe */
2968 /* fixed 6 channels */
2969 static const struct hda_channel_mode alc880_w810_modes[1] = {
2973 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2974 static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2975 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2976 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2977 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2978 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2979 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2980 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2981 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2982 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2991 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2992 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2996 static const hda_nid_t alc880_z71v_dac_nids[1] = {
2999 #define ALC880_Z71V_HP_DAC 0x03
3001 /* fixed 2 channels */
3002 static const struct hda_channel_mode alc880_2_jack_modes[1] = {
3006 static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
3007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3009 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3010 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
3011 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3012 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3013 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3014 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3020 * ALC880 F1734 model
3022 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3023 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3026 static const hda_nid_t alc880_f1734_dac_nids[1] = {
3029 #define ALC880_F1734_HP_DAC 0x02
3031 static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3032 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3033 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3034 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3035 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3036 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3037 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3039 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3043 static const struct hda_input_mux alc880_f1734_capture_source = {
3055 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3056 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3057 * Mic = 0x18, Line = 0x1a
3060 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3061 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3063 static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3064 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3065 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3066 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3067 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3068 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3069 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3070 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3071 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3080 .name = "Channel Mode",
3081 .info = alc_ch_mode_info,
3082 .get = alc_ch_mode_get,
3083 .put = alc_ch_mode_put,
3089 * ALC880 ASUS W1V model
3091 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3092 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3093 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3096 /* additional mixers to alc880_asus_mixer */
3097 static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3098 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3099 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3104 static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3105 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3106 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3107 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3109 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3111 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3112 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3113 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3118 static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3119 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3120 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3121 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3122 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3123 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3124 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3125 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3126 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3133 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3136 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3137 .name = "Channel Mode",
3138 .info = alc_ch_mode_info,
3139 .get = alc_ch_mode_get,
3140 .put = alc_ch_mode_put,
3145 static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3146 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3147 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3148 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3149 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3150 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3151 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3152 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3153 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3154 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3155 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3159 static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3160 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3161 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3162 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3163 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3165 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3170 * virtual master controls
3174 * slave controls for virtual master
3176 static const char * const alc_slave_vols[] = {
3177 "Front Playback Volume",
3178 "Surround Playback Volume",
3179 "Center Playback Volume",
3180 "LFE Playback Volume",
3181 "Side Playback Volume",
3182 "Headphone Playback Volume",
3183 "Speaker Playback Volume",
3184 "Mono Playback Volume",
3185 "Line-Out Playback Volume",
3189 static const char * const alc_slave_sws[] = {
3190 "Front Playback Switch",
3191 "Surround Playback Switch",
3192 "Center Playback Switch",
3193 "LFE Playback Switch",
3194 "Side Playback Switch",
3195 "Headphone Playback Switch",
3196 "Speaker Playback Switch",
3197 "Mono Playback Switch",
3198 "IEC958 Playback Switch",
3199 "Line-Out Playback Switch",
3204 * build control elements
3207 #define NID_MAPPING (-1)
3209 #define SUBDEV_SPEAKER_ (0 << 6)
3210 #define SUBDEV_HP_ (1 << 6)
3211 #define SUBDEV_LINE_ (2 << 6)
3212 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3213 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3214 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3216 static void alc_free_kctls(struct hda_codec *codec);
3218 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3219 /* additional beep mixers; the actual parameters are overwritten at build */
3220 static const struct snd_kcontrol_new alc_beep_mixer[] = {
3221 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
3222 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
3227 static int alc_build_controls(struct hda_codec *codec)
3229 struct alc_spec *spec = codec->spec;
3230 struct snd_kcontrol *kctl = NULL;
3231 const struct snd_kcontrol_new *knew;
3236 for (i = 0; i < spec->num_mixers; i++) {
3237 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3241 if (spec->cap_mixer) {
3242 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3246 if (spec->multiout.dig_out_nid) {
3247 err = snd_hda_create_spdif_out_ctls(codec,
3248 spec->multiout.dig_out_nid,
3249 spec->multiout.dig_out_nid);
3252 if (!spec->no_analog) {
3253 err = snd_hda_create_spdif_share_sw(codec,
3257 spec->multiout.share_spdif = 1;
3260 if (spec->dig_in_nid) {
3261 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3266 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3267 /* create beep controls if needed */
3268 if (spec->beep_amp) {
3269 const struct snd_kcontrol_new *knew;
3270 for (knew = alc_beep_mixer; knew->name; knew++) {
3271 struct snd_kcontrol *kctl;
3272 kctl = snd_ctl_new1(knew, codec);
3275 kctl->private_value = spec->beep_amp;
3276 err = snd_hda_ctl_add(codec, 0, kctl);
3283 /* if we have no master control, let's create it */
3284 if (!spec->no_analog &&
3285 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3286 unsigned int vmaster_tlv[4];
3287 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3288 HDA_OUTPUT, vmaster_tlv);
3289 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3290 vmaster_tlv, alc_slave_vols);
3294 if (!spec->no_analog &&
3295 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3296 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3297 NULL, alc_slave_sws);
3302 /* assign Capture Source enums to NID */
3303 if (spec->capsrc_nids || spec->adc_nids) {
3304 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3306 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3307 for (i = 0; kctl && i < kctl->count; i++) {
3308 const hda_nid_t *nids = spec->capsrc_nids;
3310 nids = spec->adc_nids;
3311 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3316 if (spec->cap_mixer) {
3317 const char *kname = kctl ? kctl->id.name : NULL;
3318 for (knew = spec->cap_mixer; knew->name; knew++) {
3319 if (kname && strcmp(knew->name, kname) == 0)
3321 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3322 for (i = 0; kctl && i < kctl->count; i++) {
3323 err = snd_hda_add_nid(codec, kctl, i,
3331 /* other nid->control mapping */
3332 for (i = 0; i < spec->num_mixers; i++) {
3333 for (knew = spec->mixers[i]; knew->name; knew++) {
3334 if (knew->iface != NID_MAPPING)
3336 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3339 u = knew->subdevice;
3340 for (j = 0; j < 4; j++, u >>= 8) {
3345 case SUBDEV_SPEAKER_:
3346 nid = spec->autocfg.speaker_pins[nid];
3349 nid = spec->autocfg.line_out_pins[nid];
3352 nid = spec->autocfg.hp_pins[nid];
3357 err = snd_hda_add_nid(codec, kctl, 0, nid);
3361 u = knew->private_value;
3362 for (j = 0; j < 4; j++, u >>= 8) {
3366 err = snd_hda_add_nid(codec, kctl, 0, nid);
3373 alc_free_kctls(codec); /* no longer needed */
3380 * initialize the codec volumes, etc
3384 * generic initialization of ADC, input mixers and output mixers
3386 static const struct hda_verb alc880_volume_init_verbs[] = {
3388 * Unmute ADC0-2 and set the default input to mic-in
3390 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3391 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3392 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3393 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3394 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3395 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3397 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3399 * Note: PASD motherboards uses the Line In 2 as the input for front
3402 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3412 * Set up output mixers (0x0c - 0x0f)
3414 /* set vol=0 to output mixers */
3415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3417 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3418 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3419 /* set up input amps for analog loopback */
3420 /* Amp Indices: DAC = 0, mixer = 1 */
3421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3423 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3425 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3427 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3428 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3434 * 3-stack pin configuration:
3435 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3437 static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3439 * preset connection lists of input pins
3440 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3442 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3443 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3444 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3447 * Set pin mode and muting
3449 /* set front pin widgets 0x14 for output */
3450 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3451 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3452 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3453 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3454 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3455 /* Mic2 (as headphone out) for HP output */
3456 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3457 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3458 /* Line In pin widget for input */
3459 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3460 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3461 /* Line2 (as front mic) pin widget for input and vref at 80% */
3462 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3463 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3464 /* CD pin widget for input */
3465 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3471 * 5-stack pin configuration:
3472 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3473 * line-in/side = 0x1a, f-mic = 0x1b
3475 static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3477 * preset connection lists of input pins
3478 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3480 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3481 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3484 * Set pin mode and muting
3486 /* set pin widgets 0x14-0x17 for output */
3487 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3489 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3490 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3491 /* unmute pins for output (no gain on this amp) */
3492 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3494 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3495 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3497 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3499 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3500 /* Mic2 (as headphone out) for HP output */
3501 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3502 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3503 /* Line In pin widget for input */
3504 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3505 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3506 /* Line2 (as front mic) pin widget for input and vref at 80% */
3507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3508 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3509 /* CD pin widget for input */
3510 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3516 * W810 pin configuration:
3517 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3519 static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3520 /* hphone/speaker input selector: front DAC */
3521 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3524 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3525 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3526 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3528 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3531 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3537 * Z71V pin configuration:
3538 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3540 static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3541 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3542 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3543 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3544 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3555 * 6-stack pin configuration:
3556 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3557 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3559 static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3560 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3562 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3563 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3566 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3567 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3568 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3569 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3571 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3572 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3573 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3574 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3575 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3576 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3577 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3578 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3579 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3585 * Uniwill pin configuration:
3586 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3589 static const struct hda_verb alc880_uniwill_init_verbs[] = {
3590 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3592 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3593 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3594 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3595 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3596 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3597 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3598 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3599 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3600 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3602 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3603 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3604 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3605 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3607 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3608 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3609 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3610 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3611 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3612 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3613 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3614 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3615 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3617 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3618 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3625 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3627 static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3628 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3631 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3632 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3634 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3635 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3636 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3637 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3638 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3639 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3640 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3641 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3643 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3644 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3645 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3646 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3647 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3648 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3650 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3651 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3656 static const struct hda_verb alc880_beep_init_verbs[] = {
3657 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3661 /* auto-toggle front mic */
3662 static void alc88x_simple_mic_automute(struct hda_codec *codec)
3664 unsigned int present;
3667 present = snd_hda_jack_detect(codec, 0x18);
3668 bits = present ? HDA_AMP_MUTE : 0;
3669 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3672 static void alc880_uniwill_setup(struct hda_codec *codec)
3674 struct alc_spec *spec = codec->spec;
3676 spec->autocfg.hp_pins[0] = 0x14;
3677 spec->autocfg.speaker_pins[0] = 0x15;
3678 spec->autocfg.speaker_pins[0] = 0x16;
3680 spec->automute_mode = ALC_AUTOMUTE_AMP;
3683 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3685 alc_hp_automute(codec);
3686 alc88x_simple_mic_automute(codec);
3689 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3692 /* Looks like the unsol event is incompatible with the standard
3693 * definition. 4bit tag is placed at 28 bit!
3695 switch (res >> 28) {
3696 case ALC880_MIC_EVENT:
3697 alc88x_simple_mic_automute(codec);
3700 alc_sku_unsol_event(codec, res);
3705 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3707 struct alc_spec *spec = codec->spec;
3709 spec->autocfg.hp_pins[0] = 0x14;
3710 spec->autocfg.speaker_pins[0] = 0x15;
3712 spec->automute_mode = ALC_AUTOMUTE_AMP;
3715 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3717 unsigned int present;
3719 present = snd_hda_codec_read(codec, 0x21, 0,
3720 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3721 present &= HDA_AMP_VOLMASK;
3722 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3723 HDA_AMP_VOLMASK, present);
3724 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3725 HDA_AMP_VOLMASK, present);
3728 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3731 /* Looks like the unsol event is incompatible with the standard
3732 * definition. 4bit tag is placed at 28 bit!
3734 if ((res >> 28) == ALC880_DCVOL_EVENT)
3735 alc880_uniwill_p53_dcvol_automute(codec);
3737 alc_sku_unsol_event(codec, res);
3741 * F1734 pin configuration:
3742 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3744 static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3745 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3746 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3747 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3748 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3749 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3751 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3752 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3753 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3754 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3756 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3757 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3758 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3760 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3761 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3762 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3763 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3764 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3766 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3767 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3773 * ASUS pin configuration:
3774 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3776 static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3777 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3778 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3779 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3780 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3782 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3784 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3786 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3787 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3788 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3789 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3791 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3795 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3798 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3799 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3804 /* Enable GPIO mask and set output */
3805 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3806 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3807 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3809 /* Clevo m520g init */
3810 static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3811 /* headphone output */
3812 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3815 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3817 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3820 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3821 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3822 /* Mic1 (rear panel) */
3823 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3824 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3825 /* Mic2 (front panel) */
3826 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3827 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3830 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3831 /* change to EAPD mode */
3832 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3833 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3838 static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3839 /* change to EAPD mode */
3840 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3841 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3843 /* Headphone output */
3844 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3846 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3847 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3849 /* Line In pin widget for input */
3850 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3851 /* CD pin widget for input */
3852 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3853 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3856 /* change to EAPD mode */
3857 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3858 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3864 * LG m1 express dual
3867 * Rear Line-In/Out (blue): 0x14
3868 * Build-in Mic-In: 0x15
3870 * HP-Out (green): 0x1b
3871 * Mic-In/Out (red): 0x19
3875 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3876 static const hda_nid_t alc880_lg_dac_nids[3] = {
3880 /* seems analog CD is not working */
3881 static const struct hda_input_mux alc880_lg_capture_source = {
3886 { "Internal Mic", 0x6 },
3890 /* 2,4,6 channel modes */
3891 static const struct hda_verb alc880_lg_ch2_init[] = {
3892 /* set line-in and mic-in to input */
3893 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3894 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3898 static const struct hda_verb alc880_lg_ch4_init[] = {
3899 /* set line-in to out and mic-in to input */
3900 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3901 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3905 static const struct hda_verb alc880_lg_ch6_init[] = {
3906 /* set line-in and mic-in to output */
3907 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3908 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3912 static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3913 { 2, alc880_lg_ch2_init },
3914 { 4, alc880_lg_ch4_init },
3915 { 6, alc880_lg_ch6_init },
3918 static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3919 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3920 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3921 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3922 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3923 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3924 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3925 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3926 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3927 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3928 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3929 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3930 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3931 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3932 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3934 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3935 .name = "Channel Mode",
3936 .info = alc_ch_mode_info,
3937 .get = alc_ch_mode_get,
3938 .put = alc_ch_mode_put,
3943 static const struct hda_verb alc880_lg_init_verbs[] = {
3944 /* set capture source to mic-in */
3945 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3946 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3947 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3948 /* mute all amp mixer inputs */
3949 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3950 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3951 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3952 /* line-in to input */
3953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3954 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3956 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3959 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3960 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3961 /* mic-in to input */
3962 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3963 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3964 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3966 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3967 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3968 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3970 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3974 /* toggle speaker-output according to the hp-jack state */
3975 static void alc880_lg_setup(struct hda_codec *codec)
3977 struct alc_spec *spec = codec->spec;
3979 spec->autocfg.hp_pins[0] = 0x1b;
3980 spec->autocfg.speaker_pins[0] = 0x17;
3982 spec->automute_mode = ALC_AUTOMUTE_AMP;
3991 * Built-in Mic-In: 0x19
3997 static const struct hda_input_mux alc880_lg_lw_capture_source = {
4001 { "Internal Mic", 0x1 },
4006 #define alc880_lg_lw_modes alc880_threestack_modes
4008 static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
4009 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4010 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4011 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4012 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4013 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4014 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4015 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4016 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4021 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4022 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4024 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4025 .name = "Channel Mode",
4026 .info = alc_ch_mode_info,
4027 .get = alc_ch_mode_get,
4028 .put = alc_ch_mode_put,
4033 static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4034 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4035 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4036 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4038 /* set capture source to mic-in */
4039 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4041 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4042 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4045 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4047 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4048 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4049 /* mic-in to input */
4050 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4051 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4053 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4054 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4056 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4060 /* toggle speaker-output according to the hp-jack state */
4061 static void alc880_lg_lw_setup(struct hda_codec *codec)
4063 struct alc_spec *spec = codec->spec;
4065 spec->autocfg.hp_pins[0] = 0x1b;
4066 spec->autocfg.speaker_pins[0] = 0x14;
4068 spec->automute_mode = ALC_AUTOMUTE_AMP;
4071 static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4072 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4073 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4075 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4076 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4077 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4081 static const struct hda_input_mux alc880_medion_rim_capture_source = {
4085 { "Internal Mic", 0x1 },
4089 static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4090 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4092 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4093 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4095 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4096 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4097 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4098 /* Mic2 (as headphone out) for HP output */
4099 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4100 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4101 /* Internal Speaker */
4102 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4103 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4105 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4106 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4108 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4112 /* toggle speaker-output according to the hp-jack state */
4113 static void alc880_medion_rim_automute(struct hda_codec *codec)
4115 struct alc_spec *spec = codec->spec;
4116 alc_hp_automute(codec);
4118 if (spec->jack_present)
4119 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4121 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4124 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4127 /* Looks like the unsol event is incompatible with the standard
4128 * definition. 4bit tag is placed at 28 bit!
4130 if ((res >> 28) == ALC880_HP_EVENT)
4131 alc880_medion_rim_automute(codec);
4134 static void alc880_medion_rim_setup(struct hda_codec *codec)
4136 struct alc_spec *spec = codec->spec;
4138 spec->autocfg.hp_pins[0] = 0x14;
4139 spec->autocfg.speaker_pins[0] = 0x1b;
4141 spec->automute_mode = ALC_AUTOMUTE_AMP;
4144 #ifdef CONFIG_SND_HDA_POWER_SAVE
4145 static const struct hda_amp_list alc880_loopbacks[] = {
4146 { 0x0b, HDA_INPUT, 0 },
4147 { 0x0b, HDA_INPUT, 1 },
4148 { 0x0b, HDA_INPUT, 2 },
4149 { 0x0b, HDA_INPUT, 3 },
4150 { 0x0b, HDA_INPUT, 4 },
4154 static const struct hda_amp_list alc880_lg_loopbacks[] = {
4155 { 0x0b, HDA_INPUT, 1 },
4156 { 0x0b, HDA_INPUT, 6 },
4157 { 0x0b, HDA_INPUT, 7 },
4166 static void alc_init_special_input_src(struct hda_codec *codec);
4168 static int alc_init(struct hda_codec *codec)
4170 struct alc_spec *spec = codec->spec;
4174 alc_auto_init_amp(codec, spec->init_amp);
4176 for (i = 0; i < spec->num_init_verbs; i++)
4177 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4178 alc_init_special_input_src(codec);
4180 if (spec->init_hook)
4181 spec->init_hook(codec);
4183 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4185 hda_call_check_power_status(codec, 0x01);
4189 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4191 struct alc_spec *spec = codec->spec;
4193 if (spec->unsol_event)
4194 spec->unsol_event(codec, res);
4197 #ifdef CONFIG_SND_HDA_POWER_SAVE
4198 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4200 struct alc_spec *spec = codec->spec;
4201 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4206 * Analog playback callbacks
4208 static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo,
4209 struct hda_codec *codec,
4210 struct snd_pcm_substream *substream)
4212 struct alc_spec *spec = codec->spec;
4213 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4217 static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4218 struct hda_codec *codec,
4219 unsigned int stream_tag,
4220 unsigned int format,
4221 struct snd_pcm_substream *substream)
4223 struct alc_spec *spec = codec->spec;
4224 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4225 stream_tag, format, substream);
4228 static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4229 struct hda_codec *codec,
4230 struct snd_pcm_substream *substream)
4232 struct alc_spec *spec = codec->spec;
4233 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4239 static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4240 struct hda_codec *codec,
4241 struct snd_pcm_substream *substream)
4243 struct alc_spec *spec = codec->spec;
4244 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4247 static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4248 struct hda_codec *codec,
4249 unsigned int stream_tag,
4250 unsigned int format,
4251 struct snd_pcm_substream *substream)
4253 struct alc_spec *spec = codec->spec;
4254 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4255 stream_tag, format, substream);
4258 static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4259 struct hda_codec *codec,
4260 struct snd_pcm_substream *substream)
4262 struct alc_spec *spec = codec->spec;
4263 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4266 static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4267 struct hda_codec *codec,
4268 struct snd_pcm_substream *substream)
4270 struct alc_spec *spec = codec->spec;
4271 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4277 static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4278 struct hda_codec *codec,
4279 unsigned int stream_tag,
4280 unsigned int format,
4281 struct snd_pcm_substream *substream)
4283 struct alc_spec *spec = codec->spec;
4285 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4286 stream_tag, 0, format);
4290 static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4291 struct hda_codec *codec,
4292 struct snd_pcm_substream *substream)
4294 struct alc_spec *spec = codec->spec;
4296 snd_hda_codec_cleanup_stream(codec,
4297 spec->adc_nids[substream->number + 1]);
4301 /* analog capture with dynamic dual-adc changes */
4302 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4303 struct hda_codec *codec,
4304 unsigned int stream_tag,
4305 unsigned int format,
4306 struct snd_pcm_substream *substream)
4308 struct alc_spec *spec = codec->spec;
4309 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4310 spec->cur_adc_stream_tag = stream_tag;
4311 spec->cur_adc_format = format;
4312 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4316 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4317 struct hda_codec *codec,
4318 struct snd_pcm_substream *substream)
4320 struct alc_spec *spec = codec->spec;
4321 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4326 static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4330 .nid = 0, /* fill later */
4332 .prepare = dualmic_capture_pcm_prepare,
4333 .cleanup = dualmic_capture_pcm_cleanup
4339 static const struct hda_pcm_stream alc_pcm_analog_playback = {
4343 /* NID is set in alc_build_pcms */
4345 .open = alc_playback_pcm_open,
4346 .prepare = alc_playback_pcm_prepare,
4347 .cleanup = alc_playback_pcm_cleanup
4351 static const struct hda_pcm_stream alc_pcm_analog_capture = {
4355 /* NID is set in alc_build_pcms */
4358 static const struct hda_pcm_stream alc_pcm_analog_alt_playback = {
4362 /* NID is set in alc_build_pcms */
4365 static const struct hda_pcm_stream alc_pcm_analog_alt_capture = {
4366 .substreams = 2, /* can be overridden */
4369 /* NID is set in alc_build_pcms */
4371 .prepare = alc_alt_capture_pcm_prepare,
4372 .cleanup = alc_alt_capture_pcm_cleanup
4376 static const struct hda_pcm_stream alc_pcm_digital_playback = {
4380 /* NID is set in alc_build_pcms */
4382 .open = alc_dig_playback_pcm_open,
4383 .close = alc_dig_playback_pcm_close,
4384 .prepare = alc_dig_playback_pcm_prepare,
4385 .cleanup = alc_dig_playback_pcm_cleanup
4389 static const struct hda_pcm_stream alc_pcm_digital_capture = {
4393 /* NID is set in alc_build_pcms */
4396 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
4397 static const struct hda_pcm_stream alc_pcm_null_stream = {
4403 static int alc_build_pcms(struct hda_codec *codec)
4405 struct alc_spec *spec = codec->spec;
4406 struct hda_pcm *info = spec->pcm_rec;
4407 const struct hda_pcm_stream *p;
4410 codec->num_pcms = 1;
4411 codec->pcm_info = info;
4413 if (spec->no_analog)
4416 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4417 "%s Analog", codec->chip_name);
4418 info->name = spec->stream_name_analog;
4420 if (spec->multiout.dac_nids > 0) {
4421 p = spec->stream_analog_playback;
4423 p = &alc_pcm_analog_playback;
4424 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4425 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4427 if (spec->adc_nids) {
4428 p = spec->stream_analog_capture;
4430 p = &alc_pcm_analog_capture;
4431 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4432 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4435 if (spec->channel_mode) {
4436 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4437 for (i = 0; i < spec->num_channel_mode; i++) {
4438 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4439 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4445 /* SPDIF for stream index #1 */
4446 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4447 snprintf(spec->stream_name_digital,
4448 sizeof(spec->stream_name_digital),
4449 "%s Digital", codec->chip_name);
4450 codec->num_pcms = 2;
4451 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4452 info = spec->pcm_rec + 1;
4453 info->name = spec->stream_name_digital;
4454 if (spec->dig_out_type)
4455 info->pcm_type = spec->dig_out_type;
4457 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4458 if (spec->multiout.dig_out_nid) {
4459 p = spec->stream_digital_playback;
4461 p = &alc_pcm_digital_playback;
4462 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4463 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4465 if (spec->dig_in_nid) {
4466 p = spec->stream_digital_capture;
4468 p = &alc_pcm_digital_capture;
4469 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4470 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4472 /* FIXME: do we need this for all Realtek codec models? */
4473 codec->spdif_status_reset = 1;
4476 if (spec->no_analog)
4479 /* If the use of more than one ADC is requested for the current
4480 * model, configure a second analog capture-only PCM.
4482 /* Additional Analaog capture for index #2 */
4483 if (spec->alt_dac_nid || spec->num_adc_nids > 1) {
4484 codec->num_pcms = 3;
4485 info = spec->pcm_rec + 2;
4486 info->name = spec->stream_name_analog;
4487 if (spec->alt_dac_nid) {
4488 p = spec->stream_analog_alt_playback;
4490 p = &alc_pcm_analog_alt_playback;
4491 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4492 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4495 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4496 alc_pcm_null_stream;
4497 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4499 if (spec->num_adc_nids > 1) {
4500 p = spec->stream_analog_alt_capture;
4502 p = &alc_pcm_analog_alt_capture;
4503 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4504 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4506 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4507 spec->num_adc_nids - 1;
4509 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4510 alc_pcm_null_stream;
4511 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4518 static inline void alc_shutup(struct hda_codec *codec)
4520 struct alc_spec *spec = codec->spec;
4522 if (spec && spec->shutup)
4523 spec->shutup(codec);
4524 snd_hda_shutup_pins(codec);
4527 static void alc_free_kctls(struct hda_codec *codec)
4529 struct alc_spec *spec = codec->spec;
4531 if (spec->kctls.list) {
4532 struct snd_kcontrol_new *kctl = spec->kctls.list;
4534 for (i = 0; i < spec->kctls.used; i++)
4535 kfree(kctl[i].name);
4537 snd_array_free(&spec->kctls);
4540 static void alc_free(struct hda_codec *codec)
4542 struct alc_spec *spec = codec->spec;
4548 snd_hda_input_jack_free(codec);
4549 alc_free_kctls(codec);
4551 snd_hda_detach_beep_device(codec);
4554 #ifdef CONFIG_SND_HDA_POWER_SAVE
4555 static void alc_power_eapd(struct hda_codec *codec)
4557 alc_auto_setup_eapd(codec, false);
4560 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4562 struct alc_spec *spec = codec->spec;
4564 if (spec && spec->power_hook)
4565 spec->power_hook(codec);
4570 #ifdef SND_HDA_NEEDS_RESUME
4571 static int alc_resume(struct hda_codec *codec)
4573 msleep(150); /* to avoid pop noise */
4574 codec->patch_ops.init(codec);
4575 snd_hda_codec_resume_amp(codec);
4576 snd_hda_codec_resume_cache(codec);
4577 hda_call_check_power_status(codec, 0x01);
4584 static const struct hda_codec_ops alc_patch_ops = {
4585 .build_controls = alc_build_controls,
4586 .build_pcms = alc_build_pcms,
4589 .unsol_event = alc_unsol_event,
4590 #ifdef SND_HDA_NEEDS_RESUME
4591 .resume = alc_resume,
4593 #ifdef CONFIG_SND_HDA_POWER_SAVE
4594 .suspend = alc_suspend,
4595 .check_power_status = alc_check_power_status,
4597 .reboot_notify = alc_shutup,
4600 /* replace the codec chip_name with the given string */
4601 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4603 kfree(codec->chip_name);
4604 codec->chip_name = kstrdup(name, GFP_KERNEL);
4605 if (!codec->chip_name) {
4613 * Test configuration for debugging
4615 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4618 #ifdef CONFIG_SND_DEBUG
4619 static const hda_nid_t alc880_test_dac_nids[4] = {
4620 0x02, 0x03, 0x04, 0x05
4623 static const struct hda_input_mux alc880_test_capture_source = {
4632 { "Surround", 0x6 },
4636 static const struct hda_channel_mode alc880_test_modes[4] = {
4643 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4644 struct snd_ctl_elem_info *uinfo)
4646 static const char * const texts[] = {
4647 "N/A", "Line Out", "HP Out",
4648 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4650 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4652 uinfo->value.enumerated.items = 8;
4653 if (uinfo->value.enumerated.item >= 8)
4654 uinfo->value.enumerated.item = 7;
4655 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4659 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4660 struct snd_ctl_elem_value *ucontrol)
4662 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4663 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4664 unsigned int pin_ctl, item = 0;
4666 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4667 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4668 if (pin_ctl & AC_PINCTL_OUT_EN) {
4669 if (pin_ctl & AC_PINCTL_HP_EN)
4673 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4674 switch (pin_ctl & AC_PINCTL_VREFEN) {
4675 case AC_PINCTL_VREF_HIZ: item = 3; break;
4676 case AC_PINCTL_VREF_50: item = 4; break;
4677 case AC_PINCTL_VREF_GRD: item = 5; break;
4678 case AC_PINCTL_VREF_80: item = 6; break;
4679 case AC_PINCTL_VREF_100: item = 7; break;
4682 ucontrol->value.enumerated.item[0] = item;
4686 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4687 struct snd_ctl_elem_value *ucontrol)
4689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4690 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4691 static const unsigned int ctls[] = {
4692 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4693 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4694 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4695 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4696 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4697 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4699 unsigned int old_ctl, new_ctl;
4701 old_ctl = snd_hda_codec_read(codec, nid, 0,
4702 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4703 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4704 if (old_ctl != new_ctl) {
4706 snd_hda_codec_write_cache(codec, nid, 0,
4707 AC_VERB_SET_PIN_WIDGET_CONTROL,
4709 val = ucontrol->value.enumerated.item[0] >= 3 ?
4711 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4718 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4719 struct snd_ctl_elem_info *uinfo)
4721 static const char * const texts[] = {
4722 "Front", "Surround", "CLFE", "Side"
4724 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4726 uinfo->value.enumerated.items = 4;
4727 if (uinfo->value.enumerated.item >= 4)
4728 uinfo->value.enumerated.item = 3;
4729 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4733 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4734 struct snd_ctl_elem_value *ucontrol)
4736 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4737 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4740 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4741 ucontrol->value.enumerated.item[0] = sel & 3;
4745 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4746 struct snd_ctl_elem_value *ucontrol)
4748 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4749 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4752 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4753 if (ucontrol->value.enumerated.item[0] != sel) {
4754 sel = ucontrol->value.enumerated.item[0] & 3;
4755 snd_hda_codec_write_cache(codec, nid, 0,
4756 AC_VERB_SET_CONNECT_SEL, sel);
4762 #define PIN_CTL_TEST(xname,nid) { \
4763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4765 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4766 .info = alc_test_pin_ctl_info, \
4767 .get = alc_test_pin_ctl_get, \
4768 .put = alc_test_pin_ctl_put, \
4769 .private_value = nid \
4772 #define PIN_SRC_TEST(xname,nid) { \
4773 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4775 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4776 .info = alc_test_pin_src_info, \
4777 .get = alc_test_pin_src_get, \
4778 .put = alc_test_pin_src_put, \
4779 .private_value = nid \
4782 static const struct snd_kcontrol_new alc880_test_mixer[] = {
4783 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4784 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4785 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4786 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4787 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4788 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4789 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4790 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4791 PIN_CTL_TEST("Front Pin Mode", 0x14),
4792 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4793 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4794 PIN_CTL_TEST("Side Pin Mode", 0x17),
4795 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4796 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4797 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4798 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4799 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4800 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4801 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4802 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4803 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4804 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4805 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4806 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4807 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4808 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4809 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4810 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4811 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4812 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4815 .name = "Channel Mode",
4816 .info = alc_ch_mode_info,
4817 .get = alc_ch_mode_get,
4818 .put = alc_ch_mode_put,
4823 static const struct hda_verb alc880_test_init_verbs[] = {
4824 /* Unmute inputs of 0x0c - 0x0f */
4825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4827 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4828 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4829 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4830 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4831 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4832 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4833 /* Vol output for 0x0c-0x0f */
4834 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4835 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4836 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4837 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4838 /* Set output pins 0x14-0x17 */
4839 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4840 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4841 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4842 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4843 /* Unmute output pins 0x14-0x17 */
4844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4845 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4846 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4847 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4848 /* Set input pins 0x18-0x1c */
4849 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4850 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4851 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4852 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4853 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4854 /* Mute input pins 0x18-0x1b */
4855 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4856 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4857 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4858 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4861 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4862 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4863 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4864 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4865 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4866 /* Analog input/passthru */
4867 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4868 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4869 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4870 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4871 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4879 static const char * const alc880_models[ALC880_MODEL_LAST] = {
4880 [ALC880_3ST] = "3stack",
4881 [ALC880_TCL_S700] = "tcl",
4882 [ALC880_3ST_DIG] = "3stack-digout",
4883 [ALC880_CLEVO] = "clevo",
4884 [ALC880_5ST] = "5stack",
4885 [ALC880_5ST_DIG] = "5stack-digout",
4886 [ALC880_W810] = "w810",
4887 [ALC880_Z71V] = "z71v",
4888 [ALC880_6ST] = "6stack",
4889 [ALC880_6ST_DIG] = "6stack-digout",
4890 [ALC880_ASUS] = "asus",
4891 [ALC880_ASUS_W1V] = "asus-w1v",
4892 [ALC880_ASUS_DIG] = "asus-dig",
4893 [ALC880_ASUS_DIG2] = "asus-dig2",
4894 [ALC880_UNIWILL_DIG] = "uniwill",
4895 [ALC880_UNIWILL_P53] = "uniwill-p53",
4896 [ALC880_FUJITSU] = "fujitsu",
4897 [ALC880_F1734] = "F1734",
4899 [ALC880_LG_LW] = "lg-lw",
4900 [ALC880_MEDION_RIM] = "medion",
4901 #ifdef CONFIG_SND_DEBUG
4902 [ALC880_TEST] = "test",
4904 [ALC880_AUTO] = "auto",
4907 static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4908 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4909 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4910 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4911 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4912 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4913 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4914 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4915 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4916 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4917 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4918 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4919 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4920 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4921 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4922 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4923 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4924 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4925 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4926 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4927 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4928 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4929 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4930 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4931 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4932 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4933 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4934 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4935 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4936 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4937 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4938 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4939 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4940 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4941 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4942 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4943 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4944 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4945 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4946 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4947 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4948 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4949 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4950 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4951 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4952 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4953 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4954 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4955 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4956 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4957 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4958 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4959 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4960 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4961 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4962 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4963 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4964 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4965 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4966 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4967 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4968 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4969 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4970 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4971 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4972 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4973 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4974 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4975 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4977 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4978 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4979 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4984 * ALC880 codec presets
4986 static const struct alc_config_preset alc880_presets[] = {
4988 .mixers = { alc880_three_stack_mixer },
4989 .init_verbs = { alc880_volume_init_verbs,
4990 alc880_pin_3stack_init_verbs },
4991 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4992 .dac_nids = alc880_dac_nids,
4993 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4994 .channel_mode = alc880_threestack_modes,
4996 .input_mux = &alc880_capture_source,
4998 [ALC880_3ST_DIG] = {
4999 .mixers = { alc880_three_stack_mixer },
5000 .init_verbs = { alc880_volume_init_verbs,
5001 alc880_pin_3stack_init_verbs },
5002 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5003 .dac_nids = alc880_dac_nids,
5004 .dig_out_nid = ALC880_DIGOUT_NID,
5005 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5006 .channel_mode = alc880_threestack_modes,
5008 .input_mux = &alc880_capture_source,
5010 [ALC880_TCL_S700] = {
5011 .mixers = { alc880_tcl_s700_mixer },
5012 .init_verbs = { alc880_volume_init_verbs,
5013 alc880_pin_tcl_S700_init_verbs,
5014 alc880_gpio2_init_verbs },
5015 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5016 .dac_nids = alc880_dac_nids,
5017 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
5018 .num_adc_nids = 1, /* single ADC */
5020 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5021 .channel_mode = alc880_2_jack_modes,
5022 .input_mux = &alc880_capture_source,
5025 .mixers = { alc880_three_stack_mixer,
5026 alc880_five_stack_mixer},
5027 .init_verbs = { alc880_volume_init_verbs,
5028 alc880_pin_5stack_init_verbs },
5029 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5030 .dac_nids = alc880_dac_nids,
5031 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5032 .channel_mode = alc880_fivestack_modes,
5033 .input_mux = &alc880_capture_source,
5035 [ALC880_5ST_DIG] = {
5036 .mixers = { alc880_three_stack_mixer,
5037 alc880_five_stack_mixer },
5038 .init_verbs = { alc880_volume_init_verbs,
5039 alc880_pin_5stack_init_verbs },
5040 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5041 .dac_nids = alc880_dac_nids,
5042 .dig_out_nid = ALC880_DIGOUT_NID,
5043 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5044 .channel_mode = alc880_fivestack_modes,
5045 .input_mux = &alc880_capture_source,
5048 .mixers = { alc880_six_stack_mixer },
5049 .init_verbs = { alc880_volume_init_verbs,
5050 alc880_pin_6stack_init_verbs },
5051 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5052 .dac_nids = alc880_6st_dac_nids,
5053 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5054 .channel_mode = alc880_sixstack_modes,
5055 .input_mux = &alc880_6stack_capture_source,
5057 [ALC880_6ST_DIG] = {
5058 .mixers = { alc880_six_stack_mixer },
5059 .init_verbs = { alc880_volume_init_verbs,
5060 alc880_pin_6stack_init_verbs },
5061 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5062 .dac_nids = alc880_6st_dac_nids,
5063 .dig_out_nid = ALC880_DIGOUT_NID,
5064 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5065 .channel_mode = alc880_sixstack_modes,
5066 .input_mux = &alc880_6stack_capture_source,
5069 .mixers = { alc880_w810_base_mixer },
5070 .init_verbs = { alc880_volume_init_verbs,
5071 alc880_pin_w810_init_verbs,
5072 alc880_gpio2_init_verbs },
5073 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5074 .dac_nids = alc880_w810_dac_nids,
5075 .dig_out_nid = ALC880_DIGOUT_NID,
5076 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5077 .channel_mode = alc880_w810_modes,
5078 .input_mux = &alc880_capture_source,
5081 .mixers = { alc880_z71v_mixer },
5082 .init_verbs = { alc880_volume_init_verbs,
5083 alc880_pin_z71v_init_verbs },
5084 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5085 .dac_nids = alc880_z71v_dac_nids,
5086 .dig_out_nid = ALC880_DIGOUT_NID,
5088 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5089 .channel_mode = alc880_2_jack_modes,
5090 .input_mux = &alc880_capture_source,
5093 .mixers = { alc880_f1734_mixer },
5094 .init_verbs = { alc880_volume_init_verbs,
5095 alc880_pin_f1734_init_verbs },
5096 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5097 .dac_nids = alc880_f1734_dac_nids,
5099 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5100 .channel_mode = alc880_2_jack_modes,
5101 .input_mux = &alc880_f1734_capture_source,
5102 .unsol_event = alc880_uniwill_p53_unsol_event,
5103 .setup = alc880_uniwill_p53_setup,
5104 .init_hook = alc_hp_automute,
5107 .mixers = { alc880_asus_mixer },
5108 .init_verbs = { alc880_volume_init_verbs,
5109 alc880_pin_asus_init_verbs,
5110 alc880_gpio1_init_verbs },
5111 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5112 .dac_nids = alc880_asus_dac_nids,
5113 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5114 .channel_mode = alc880_asus_modes,
5116 .input_mux = &alc880_capture_source,
5118 [ALC880_ASUS_DIG] = {
5119 .mixers = { alc880_asus_mixer },
5120 .init_verbs = { alc880_volume_init_verbs,
5121 alc880_pin_asus_init_verbs,
5122 alc880_gpio1_init_verbs },
5123 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5124 .dac_nids = alc880_asus_dac_nids,
5125 .dig_out_nid = ALC880_DIGOUT_NID,
5126 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5127 .channel_mode = alc880_asus_modes,
5129 .input_mux = &alc880_capture_source,
5131 [ALC880_ASUS_DIG2] = {
5132 .mixers = { alc880_asus_mixer },
5133 .init_verbs = { alc880_volume_init_verbs,
5134 alc880_pin_asus_init_verbs,
5135 alc880_gpio2_init_verbs }, /* use GPIO2 */
5136 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5137 .dac_nids = alc880_asus_dac_nids,
5138 .dig_out_nid = ALC880_DIGOUT_NID,
5139 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5140 .channel_mode = alc880_asus_modes,
5142 .input_mux = &alc880_capture_source,
5144 [ALC880_ASUS_W1V] = {
5145 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5146 .init_verbs = { alc880_volume_init_verbs,
5147 alc880_pin_asus_init_verbs,
5148 alc880_gpio1_init_verbs },
5149 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5150 .dac_nids = alc880_asus_dac_nids,
5151 .dig_out_nid = ALC880_DIGOUT_NID,
5152 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5153 .channel_mode = alc880_asus_modes,
5155 .input_mux = &alc880_capture_source,
5157 [ALC880_UNIWILL_DIG] = {
5158 .mixers = { alc880_asus_mixer },
5159 .init_verbs = { alc880_volume_init_verbs,
5160 alc880_pin_asus_init_verbs },
5161 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5162 .dac_nids = alc880_asus_dac_nids,
5163 .dig_out_nid = ALC880_DIGOUT_NID,
5164 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5165 .channel_mode = alc880_asus_modes,
5167 .input_mux = &alc880_capture_source,
5169 [ALC880_UNIWILL] = {
5170 .mixers = { alc880_uniwill_mixer },
5171 .init_verbs = { alc880_volume_init_verbs,
5172 alc880_uniwill_init_verbs },
5173 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5174 .dac_nids = alc880_asus_dac_nids,
5175 .dig_out_nid = ALC880_DIGOUT_NID,
5176 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5177 .channel_mode = alc880_threestack_modes,
5179 .input_mux = &alc880_capture_source,
5180 .unsol_event = alc880_uniwill_unsol_event,
5181 .setup = alc880_uniwill_setup,
5182 .init_hook = alc880_uniwill_init_hook,
5184 [ALC880_UNIWILL_P53] = {
5185 .mixers = { alc880_uniwill_p53_mixer },
5186 .init_verbs = { alc880_volume_init_verbs,
5187 alc880_uniwill_p53_init_verbs },
5188 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5189 .dac_nids = alc880_asus_dac_nids,
5190 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5191 .channel_mode = alc880_threestack_modes,
5192 .input_mux = &alc880_capture_source,
5193 .unsol_event = alc880_uniwill_p53_unsol_event,
5194 .setup = alc880_uniwill_p53_setup,
5195 .init_hook = alc_hp_automute,
5197 [ALC880_FUJITSU] = {
5198 .mixers = { alc880_fujitsu_mixer },
5199 .init_verbs = { alc880_volume_init_verbs,
5200 alc880_uniwill_p53_init_verbs,
5201 alc880_beep_init_verbs },
5202 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5203 .dac_nids = alc880_dac_nids,
5204 .dig_out_nid = ALC880_DIGOUT_NID,
5205 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5206 .channel_mode = alc880_2_jack_modes,
5207 .input_mux = &alc880_capture_source,
5208 .unsol_event = alc880_uniwill_p53_unsol_event,
5209 .setup = alc880_uniwill_p53_setup,
5210 .init_hook = alc_hp_automute,
5213 .mixers = { alc880_three_stack_mixer },
5214 .init_verbs = { alc880_volume_init_verbs,
5215 alc880_pin_clevo_init_verbs },
5216 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5217 .dac_nids = alc880_dac_nids,
5219 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5220 .channel_mode = alc880_threestack_modes,
5222 .input_mux = &alc880_capture_source,
5225 .mixers = { alc880_lg_mixer },
5226 .init_verbs = { alc880_volume_init_verbs,
5227 alc880_lg_init_verbs },
5228 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5229 .dac_nids = alc880_lg_dac_nids,
5230 .dig_out_nid = ALC880_DIGOUT_NID,
5231 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5232 .channel_mode = alc880_lg_ch_modes,
5234 .input_mux = &alc880_lg_capture_source,
5235 .unsol_event = alc_sku_unsol_event,
5236 .setup = alc880_lg_setup,
5237 .init_hook = alc_hp_automute,
5238 #ifdef CONFIG_SND_HDA_POWER_SAVE
5239 .loopbacks = alc880_lg_loopbacks,
5243 .mixers = { alc880_lg_lw_mixer },
5244 .init_verbs = { alc880_volume_init_verbs,
5245 alc880_lg_lw_init_verbs },
5246 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5247 .dac_nids = alc880_dac_nids,
5248 .dig_out_nid = ALC880_DIGOUT_NID,
5249 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5250 .channel_mode = alc880_lg_lw_modes,
5251 .input_mux = &alc880_lg_lw_capture_source,
5252 .unsol_event = alc_sku_unsol_event,
5253 .setup = alc880_lg_lw_setup,
5254 .init_hook = alc_hp_automute,
5256 [ALC880_MEDION_RIM] = {
5257 .mixers = { alc880_medion_rim_mixer },
5258 .init_verbs = { alc880_volume_init_verbs,
5259 alc880_medion_rim_init_verbs,
5260 alc_gpio2_init_verbs },
5261 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5262 .dac_nids = alc880_dac_nids,
5263 .dig_out_nid = ALC880_DIGOUT_NID,
5264 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5265 .channel_mode = alc880_2_jack_modes,
5266 .input_mux = &alc880_medion_rim_capture_source,
5267 .unsol_event = alc880_medion_rim_unsol_event,
5268 .setup = alc880_medion_rim_setup,
5269 .init_hook = alc880_medion_rim_automute,
5271 #ifdef CONFIG_SND_DEBUG
5273 .mixers = { alc880_test_mixer },
5274 .init_verbs = { alc880_test_init_verbs },
5275 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5276 .dac_nids = alc880_test_dac_nids,
5277 .dig_out_nid = ALC880_DIGOUT_NID,
5278 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5279 .channel_mode = alc880_test_modes,
5280 .input_mux = &alc880_test_capture_source,
5286 * Automatic parse of I/O pins from the BIOS configuration
5291 ALC_CTL_WIDGET_MUTE,
5294 static const struct snd_kcontrol_new alc880_control_templates[] = {
5295 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5296 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5297 HDA_BIND_MUTE(NULL, 0, 0, 0),
5300 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5302 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5303 return snd_array_new(&spec->kctls);
5306 /* add dynamic controls */
5307 static int add_control(struct alc_spec *spec, int type, const char *name,
5308 int cidx, unsigned long val)
5310 struct snd_kcontrol_new *knew;
5312 knew = alc_kcontrol_new(spec);
5315 *knew = alc880_control_templates[type];
5316 knew->name = kstrdup(name, GFP_KERNEL);
5320 if (get_amp_nid_(val))
5321 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5322 knew->private_value = val;
5326 static int add_control_with_pfx(struct alc_spec *spec, int type,
5327 const char *pfx, const char *dir,
5328 const char *sfx, int cidx, unsigned long val)
5331 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5332 return add_control(spec, type, name, cidx, val);
5335 #define add_pb_vol_ctrl(spec, type, pfx, val) \
5336 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5337 #define add_pb_sw_ctrl(spec, type, pfx, val) \
5338 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5339 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5340 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5341 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5342 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5344 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5345 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5346 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5347 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5348 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
5349 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
5350 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5351 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
5352 #define ALC880_PIN_CD_NID 0x1c
5354 static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5355 bool can_be_master, int *index)
5357 struct auto_pin_cfg *cfg = &spec->autocfg;
5358 static const char * const chname[4] = {
5359 "Front", "Surround", NULL /*CLFE*/, "Side"
5363 if (cfg->line_outs == 1 && !spec->multi_ios &&
5364 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5367 switch (cfg->line_out_type) {
5368 case AUTO_PIN_SPEAKER_OUT:
5369 if (cfg->line_outs == 1)
5372 case AUTO_PIN_HP_OUT:
5373 /* for multi-io case, only the primary out */
5374 if (ch && spec->multi_ios)
5379 if (cfg->line_outs == 1 && !spec->multi_ios)
5386 /* create input playback/capture controls for the given pin */
5387 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5388 const char *ctlname, int ctlidx,
5389 int idx, hda_nid_t mix_nid)
5393 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5394 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5397 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5398 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5404 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5406 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5407 return (pincap & AC_PINCAP_IN) != 0;
5410 static int alc_auto_fill_adc_caps(struct hda_codec *codec)
5412 struct alc_spec *spec = codec->spec;
5414 hda_nid_t *adc_nids = spec->private_adc_nids;
5415 hda_nid_t *cap_nids = spec->private_capsrc_nids;
5416 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
5417 bool indep_capsrc = false;
5420 nid = codec->start_nid;
5421 for (i = 0; i < codec->num_nodes; i++, nid++) {
5423 const hda_nid_t *list;
5424 unsigned int caps = get_wcaps(codec, nid);
5425 int type = get_wcaps_type(caps);
5427 if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
5429 adc_nids[nums] = nid;
5430 cap_nids[nums] = nid;
5434 type = get_wcaps_type(get_wcaps(codec, src));
5435 if (type == AC_WID_PIN)
5437 if (type == AC_WID_AUD_SEL) {
5438 cap_nids[nums] = src;
5439 indep_capsrc = true;
5442 n = snd_hda_get_conn_list(codec, src, &list);
5444 cap_nids[nums] = src;
5445 indep_capsrc = true;
5451 if (++nums >= max_nums)
5454 spec->adc_nids = spec->private_adc_nids;
5456 spec->capsrc_nids = spec->private_capsrc_nids;
5457 spec->num_adc_nids = nums;
5461 /* create playback/capture controls for input pins */
5462 static int alc_auto_create_input_ctls(struct hda_codec *codec)
5464 struct alc_spec *spec = codec->spec;
5465 const struct auto_pin_cfg *cfg = &spec->autocfg;
5466 hda_nid_t mixer = spec->mixer_nid;
5467 struct hda_input_mux *imux = &spec->private_imux[0];
5469 int i, c, err, idx, type_idx = 0;
5470 const char *prev_label = NULL;
5472 num_adcs = alc_auto_fill_adc_caps(codec);
5476 for (i = 0; i < cfg->num_inputs; i++) {
5480 pin = cfg->inputs[i].pin;
5481 if (!alc_is_input_pin(codec, pin))
5484 label = hda_get_autocfg_input_label(codec, cfg, i);
5485 if (prev_label && !strcmp(label, prev_label))
5492 idx = get_connection_index(codec, mixer, pin);
5494 err = new_analog_input(spec, pin,
5502 for (c = 0; c < num_adcs; c++) {
5503 hda_nid_t cap = spec->capsrc_nids ?
5504 spec->capsrc_nids[c] : spec->adc_nids[c];
5505 idx = get_connection_index(codec, cap, pin);
5507 snd_hda_add_imux_item(imux, label, idx, NULL);
5515 static int alc_auto_fill_dac_nids(struct hda_codec *codec);
5516 static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
5517 const struct auto_pin_cfg *cfg);
5518 static int alc_auto_create_hp_out(struct hda_codec *codec);
5519 static int alc_auto_create_speaker_out(struct hda_codec *codec);
5520 static void alc_auto_init_multi_out(struct hda_codec *codec);
5521 static void alc_auto_init_extra_out(struct hda_codec *codec);
5523 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5524 unsigned int pin_type)
5526 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5529 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5533 static int get_pin_type(int line_out_type)
5535 if (line_out_type == AUTO_PIN_HP_OUT)
5541 static void alc_auto_init_analog_input(struct hda_codec *codec)
5543 struct alc_spec *spec = codec->spec;
5544 struct auto_pin_cfg *cfg = &spec->autocfg;
5547 for (i = 0; i < cfg->num_inputs; i++) {
5548 hda_nid_t nid = cfg->inputs[i].pin;
5549 if (alc_is_input_pin(codec, nid)) {
5550 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5551 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
5552 snd_hda_codec_write(codec, nid, 0,
5553 AC_VERB_SET_AMP_GAIN_MUTE,
5558 /* mute all loopback inputs */
5559 if (spec->mixer_nid) {
5560 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
5561 for (i = 0; i < nums; i++)
5562 snd_hda_codec_write(codec, spec->mixer_nid, 0,
5563 AC_VERB_SET_AMP_GAIN_MUTE,
5568 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
5569 int (*fill_dac)(struct hda_codec *));
5570 static void alc_remove_invalid_adc_nids(struct hda_codec *codec);
5571 static void alc_auto_init_input_src(struct hda_codec *codec);
5573 /* parse the BIOS configuration and set up the alc_spec */
5574 /* return 1 if successful, 0 if the proper config is not found,
5575 * or a negative error code
5577 static int alc880_parse_auto_config(struct hda_codec *codec)
5579 struct alc_spec *spec = codec->spec;
5581 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5583 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5587 if (!spec->autocfg.line_outs)
5588 return 0; /* can't find valid BIOS pin config */
5590 err = alc_auto_fill_dac_nids(codec);
5593 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
5596 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
5599 err = alc_auto_create_hp_out(codec);
5602 err = alc_auto_create_speaker_out(codec);
5605 err = alc_auto_create_input_ctls(codec);
5609 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5611 alc_auto_parse_digital(codec);
5613 if (spec->kctls.list)
5614 add_mixer(spec, spec->kctls.list);
5616 spec->num_mux_defs = 1;
5617 spec->input_mux = &spec->private_imux[0];
5619 if (!spec->dual_adc_switch)
5620 alc_remove_invalid_adc_nids(codec);
5622 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5627 /* additional initialization for auto-configuration model */
5628 static void alc880_auto_init(struct hda_codec *codec)
5630 struct alc_spec *spec = codec->spec;
5631 alc_auto_init_multi_out(codec);
5632 alc_auto_init_extra_out(codec);
5633 alc_auto_init_analog_input(codec);
5634 alc_auto_init_input_src(codec);
5635 alc_auto_init_digital(codec);
5636 if (spec->unsol_event)
5637 alc_inithook(codec);
5640 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5641 * one of two digital mic pins, e.g. on ALC272
5643 static void fixup_automic_adc(struct hda_codec *codec)
5645 struct alc_spec *spec = codec->spec;
5648 for (i = 0; i < spec->num_adc_nids; i++) {
5649 hda_nid_t cap = spec->capsrc_nids ?
5650 spec->capsrc_nids[i] : spec->adc_nids[i];
5653 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5656 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5659 spec->int_mic.mux_idx = iidx;
5660 spec->ext_mic.mux_idx = eidx;
5661 if (spec->capsrc_nids)
5662 spec->capsrc_nids += i;
5663 spec->adc_nids += i;
5664 spec->num_adc_nids = 1;
5665 /* optional dock-mic */
5666 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5668 spec->dock_mic.pin = 0;
5670 spec->dock_mic.mux_idx = eidx;
5673 snd_printd(KERN_INFO "hda_codec: %s: "
5674 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5675 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5676 spec->auto_mic = 0; /* disable auto-mic to be sure */
5679 /* select or unmute the given capsrc route */
5680 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5683 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5684 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5687 snd_hda_codec_write_cache(codec, cap, 0,
5688 AC_VERB_SET_CONNECT_SEL, idx);
5692 /* set the default connection to that pin */
5693 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5695 struct alc_spec *spec = codec->spec;
5700 for (i = 0; i < spec->num_adc_nids; i++) {
5701 hda_nid_t cap = spec->capsrc_nids ?
5702 spec->capsrc_nids[i] : spec->adc_nids[i];
5705 idx = get_connection_index(codec, cap, pin);
5708 select_or_unmute_capsrc(codec, cap, idx);
5709 return i; /* return the found index */
5711 return -1; /* not found */
5714 /* choose the ADC/MUX containing the input pin and initialize the setup */
5715 static void fixup_single_adc(struct hda_codec *codec)
5717 struct alc_spec *spec = codec->spec;
5718 struct auto_pin_cfg *cfg = &spec->autocfg;
5721 /* search for the input pin; there must be only one */
5722 if (cfg->num_inputs != 1)
5724 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5726 /* use only this ADC */
5727 if (spec->capsrc_nids)
5728 spec->capsrc_nids += i;
5729 spec->adc_nids += i;
5730 spec->num_adc_nids = 1;
5731 spec->single_input_src = 1;
5735 /* initialize dual adcs */
5736 static void fixup_dual_adc_switch(struct hda_codec *codec)
5738 struct alc_spec *spec = codec->spec;
5739 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5740 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5741 init_capsrc_for_pin(codec, spec->int_mic.pin);
5744 /* initialize some special cases for input sources */
5745 static void alc_init_special_input_src(struct hda_codec *codec)
5747 struct alc_spec *spec = codec->spec;
5748 if (spec->dual_adc_switch)
5749 fixup_dual_adc_switch(codec);
5750 else if (spec->single_input_src)
5751 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5754 static void set_capture_mixer(struct hda_codec *codec)
5756 struct alc_spec *spec = codec->spec;
5757 static const struct snd_kcontrol_new *caps[2][3] = {
5758 { alc_capture_mixer_nosrc1,
5759 alc_capture_mixer_nosrc2,
5760 alc_capture_mixer_nosrc3 },
5761 { alc_capture_mixer1,
5763 alc_capture_mixer3 },
5766 /* check whether either of ADC or MUX has a volume control */
5767 if (!(query_amp_caps(codec, spec->adc_nids[0], HDA_INPUT) &
5768 AC_AMPCAP_NUM_STEPS)) {
5769 if (!spec->capsrc_nids)
5770 return; /* no volume */
5771 if (!(query_amp_caps(codec, spec->capsrc_nids[0], HDA_OUTPUT) &
5772 AC_AMPCAP_NUM_STEPS))
5773 return; /* no volume in capsrc, too */
5774 spec->vol_in_capsrc = 1;
5777 if (spec->num_adc_nids > 0) {
5780 if (spec->dual_adc_switch)
5782 else if (spec->auto_mic)
5783 fixup_automic_adc(codec);
5784 else if (spec->input_mux) {
5785 if (spec->input_mux->num_items > 1)
5787 else if (spec->input_mux->num_items == 1)
5788 fixup_single_adc(codec);
5791 if (spec->num_adc_nids > 3)
5792 spec->num_adc_nids = 3;
5793 else if (!spec->num_adc_nids)
5795 num_adcs = spec->num_adc_nids;
5797 spec->cap_mixer = caps[mux][num_adcs - 1];
5801 /* filter out invalid adc_nids (and capsrc_nids) that don't give all
5804 static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
5806 struct alc_spec *spec = codec->spec;
5807 struct auto_pin_cfg *cfg = &spec->autocfg;
5808 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5809 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5813 for (n = 0; n < spec->num_adc_nids; n++) {
5814 hda_nid_t cap = spec->private_capsrc_nids[n];
5815 for (i = 0; i < cfg->num_inputs; i++) {
5816 hda_nid_t pin = cfg->inputs[i].pin;
5817 if (get_connection_index(codec, cap, pin) < 0)
5820 if (i >= cfg->num_inputs) {
5821 adc_nids[nums] = spec->private_adc_nids[n];
5822 capsrc_nids[nums++] = cap;
5826 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5827 " using fallback 0x%x\n",
5828 codec->chip_name, spec->private_adc_nids[0]);
5829 spec->num_adc_nids = 1;
5830 } else if (nums != spec->num_adc_nids) {
5831 memcpy(spec->private_adc_nids, adc_nids,
5832 nums * sizeof(hda_nid_t));
5833 memcpy(spec->private_capsrc_nids, capsrc_nids,
5834 nums * sizeof(hda_nid_t));
5835 spec->num_adc_nids = nums;
5839 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5840 #define set_beep_amp(spec, nid, idx, dir) \
5841 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5843 static const struct snd_pci_quirk beep_white_list[] = {
5844 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5845 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5846 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5847 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5848 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5852 static inline int has_cdefine_beep(struct hda_codec *codec)
5854 struct alc_spec *spec = codec->spec;
5855 const struct snd_pci_quirk *q;
5856 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5859 return spec->cdefine.enable_pcbeep;
5862 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5863 #define has_cdefine_beep(codec) 0
5867 * OK, here we have finally the patch for ALC880
5870 static int patch_alc880(struct hda_codec *codec)
5872 struct alc_spec *spec;
5876 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5882 spec->mixer_nid = 0x0b;
5884 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5887 if (board_config < 0) {
5888 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5890 board_config = ALC880_AUTO;
5893 if (board_config == ALC880_AUTO) {
5894 /* automatic parse from the BIOS config */
5895 err = alc880_parse_auto_config(codec);
5901 "hda_codec: Cannot set up configuration "
5902 "from BIOS. Using 3-stack mode...\n");
5903 board_config = ALC880_3ST;
5907 err = snd_hda_attach_beep_device(codec, 0x1);
5913 if (board_config != ALC880_AUTO)
5914 setup_preset(codec, &alc880_presets[board_config]);
5916 if (!spec->adc_nids && spec->input_mux) {
5917 alc_auto_fill_adc_caps(codec);
5918 alc_remove_invalid_adc_nids(codec);
5920 set_capture_mixer(codec);
5921 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5923 spec->vmaster_nid = 0x0c;
5925 codec->patch_ops = alc_patch_ops;
5926 if (board_config == ALC880_AUTO)
5927 spec->init_hook = alc880_auto_init;
5928 #ifdef CONFIG_SND_HDA_POWER_SAVE
5929 if (!spec->loopback.amplist)
5930 spec->loopback.amplist = alc880_loopbacks;
5941 static const hda_nid_t alc260_dac_nids[1] = {
5946 static const hda_nid_t alc260_adc_nids[1] = {
5951 static const hda_nid_t alc260_adc_nids_alt[1] = {
5956 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5957 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5959 static const hda_nid_t alc260_dual_adc_nids[2] = {
5964 #define ALC260_DIGOUT_NID 0x03
5965 #define ALC260_DIGIN_NID 0x06
5967 static const struct hda_input_mux alc260_capture_source = {
5971 { "Front Mic", 0x1 },
5977 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5978 * headphone jack and the internal CD lines since these are the only pins at
5979 * which audio can appear. For flexibility, also allow the option of
5980 * recording the mixer output on the second ADC (ADC0 doesn't have a
5981 * connection to the mixer output).
5983 static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5987 { "Mic/Line", 0x0 },
5989 { "Headphone", 0x2 },
5995 { "Mic/Line", 0x0 },
5997 { "Headphone", 0x2 },
6004 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6005 * the Fujitsu S702x, but jacks are marked differently.
6007 static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6014 { "Headphone", 0x5 },
6023 { "Headphone", 0x6 },
6029 /* Maxdata Favorit 100XS */
6030 static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6034 { "Line/Mic", 0x0 },
6041 { "Line/Mic", 0x0 },
6049 * This is just place-holder, so there's something for alc_build_pcms to look
6050 * at when it calculates the maximum number of channels. ALC260 has no mixer
6051 * element which allows changing the channel mode, so the verb list is
6054 static const struct hda_channel_mode alc260_modes[1] = {
6059 /* Mixer combinations
6061 * basic: base_output + input + pc_beep + capture
6062 * HP: base_output + input + capture_alt
6063 * HP_3013: hp_3013 + input + capture
6064 * fujitsu: fujitsu + capture
6065 * acer: acer + capture
6068 static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6069 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6070 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6071 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6072 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6073 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6074 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6078 static const struct snd_kcontrol_new alc260_input_mixer[] = {
6079 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6080 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6081 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6082 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6084 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6085 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6086 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6090 /* update HP, line and mono out pins according to the master switch */
6091 static void alc260_hp_master_update(struct hda_codec *codec)
6093 update_speakers(codec);
6096 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6097 struct snd_ctl_elem_value *ucontrol)
6099 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6100 struct alc_spec *spec = codec->spec;
6101 *ucontrol->value.integer.value = !spec->master_mute;
6105 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6106 struct snd_ctl_elem_value *ucontrol)
6108 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6109 struct alc_spec *spec = codec->spec;
6110 int val = !*ucontrol->value.integer.value;
6112 if (val == spec->master_mute)
6114 spec->master_mute = val;
6115 alc260_hp_master_update(codec);
6119 static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6121 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6122 .name = "Master Playback Switch",
6123 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6124 .info = snd_ctl_boolean_mono_info,
6125 .get = alc260_hp_master_sw_get,
6126 .put = alc260_hp_master_sw_put,
6128 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6129 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6130 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6131 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6132 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6134 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6138 static const struct hda_verb alc260_hp_unsol_verbs[] = {
6139 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6143 static void alc260_hp_setup(struct hda_codec *codec)
6145 struct alc_spec *spec = codec->spec;
6147 spec->autocfg.hp_pins[0] = 0x0f;
6148 spec->autocfg.speaker_pins[0] = 0x10;
6149 spec->autocfg.speaker_pins[1] = 0x11;
6151 spec->automute_mode = ALC_AUTOMUTE_PIN;
6154 static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6156 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6157 .name = "Master Playback Switch",
6158 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6159 .info = snd_ctl_boolean_mono_info,
6160 .get = alc260_hp_master_sw_get,
6161 .put = alc260_hp_master_sw_put,
6163 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6164 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6165 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6166 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6167 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6168 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6169 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6170 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6174 static void alc260_hp_3013_setup(struct hda_codec *codec)
6176 struct alc_spec *spec = codec->spec;
6178 spec->autocfg.hp_pins[0] = 0x15;
6179 spec->autocfg.speaker_pins[0] = 0x10;
6180 spec->autocfg.speaker_pins[1] = 0x11;
6182 spec->automute_mode = ALC_AUTOMUTE_PIN;
6185 static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6186 .ops = &snd_hda_bind_vol,
6188 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6189 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6190 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6195 static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6196 .ops = &snd_hda_bind_sw,
6198 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6199 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6204 static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6205 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6206 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6207 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6212 static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6213 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6217 static void alc260_hp_3012_setup(struct hda_codec *codec)
6219 struct alc_spec *spec = codec->spec;
6221 spec->autocfg.hp_pins[0] = 0x10;
6222 spec->autocfg.speaker_pins[0] = 0x0f;
6223 spec->autocfg.speaker_pins[1] = 0x11;
6224 spec->autocfg.speaker_pins[2] = 0x15;
6226 spec->automute_mode = ALC_AUTOMUTE_PIN;
6229 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6230 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6232 static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6233 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6234 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6235 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6236 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6237 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6238 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6239 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6240 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6241 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6242 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6246 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6247 * versions of the ALC260 don't act on requests to enable mic bias from NID
6248 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6249 * datasheet doesn't mention this restriction. At this stage it's not clear
6250 * whether this behaviour is intentional or is a hardware bug in chip
6251 * revisions available in early 2006. Therefore for now allow the
6252 * "Headphone Jack Mode" control to span all choices, but if it turns out
6253 * that the lack of mic bias for this NID is intentional we could change the
6254 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6256 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6257 * don't appear to make the mic bias available from the "line" jack, even
6258 * though the NID used for this jack (0x14) can supply it. The theory is
6259 * that perhaps Acer have included blocking capacitors between the ALC260
6260 * and the output jack. If this turns out to be the case for all such
6261 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6262 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6264 * The C20x Tablet series have a mono internal speaker which is controlled
6265 * via the chip's Mono sum widget and pin complex, so include the necessary
6266 * controls for such models. On models without a "mono speaker" the control
6267 * won't do anything.
6269 static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6270 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6271 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6272 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6273 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6275 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6277 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6278 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6279 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6280 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6281 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6282 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6283 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6284 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6288 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
6290 static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6291 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6292 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6293 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6294 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6295 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6296 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6300 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6301 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6303 static const struct snd_kcontrol_new alc260_will_mixer[] = {
6304 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6305 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6306 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6307 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6308 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6309 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6310 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6311 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6312 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6313 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6317 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6318 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6320 static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6321 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6322 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6324 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6325 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6326 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6327 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6328 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6329 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6330 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6335 * initialization verbs
6337 static const struct hda_verb alc260_init_verbs[] = {
6338 /* Line In pin widget for input */
6339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6340 /* CD pin widget for input */
6341 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6342 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6343 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6344 /* Mic2 (front panel) pin widget for input and vref at 80% */
6345 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6346 /* LINE-2 is used for line-out in rear */
6347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6348 /* select line-out */
6349 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6351 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6353 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6355 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6356 /* mute capture amp left and right */
6357 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6358 /* set connection select to line in (default select for this ADC) */
6359 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6360 /* mute capture amp left and right */
6361 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6362 /* set connection select to line in (default select for this ADC) */
6363 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6364 /* set vol=0 Line-Out mixer amp left and right */
6365 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6366 /* unmute pin widget amp left and right (no gain on this amp) */
6367 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6368 /* set vol=0 HP mixer amp left and right */
6369 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6370 /* unmute pin widget amp left and right (no gain on this amp) */
6371 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6372 /* set vol=0 Mono mixer amp left and right */
6373 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6374 /* unmute pin widget amp left and right (no gain on this amp) */
6375 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6376 /* unmute LINE-2 out pin */
6377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6378 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6381 /* mute analog inputs */
6382 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6383 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6386 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6387 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6388 /* mute Front out path */
6389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6390 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6391 /* mute Headphone out path */
6392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6394 /* mute Mono out path */
6395 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6396 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6400 #if 0 /* should be identical with alc260_init_verbs? */
6401 static const struct hda_verb alc260_hp_init_verbs[] = {
6402 /* Headphone and output */
6403 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6405 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6406 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6407 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6408 /* Mic2 (front panel) pin widget for input and vref at 80% */
6409 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6410 /* Line In pin widget for input */
6411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6412 /* Line-2 pin widget for output */
6413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6414 /* CD pin widget for input */
6415 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6416 /* unmute amp left and right */
6417 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6418 /* set connection select to line in (default select for this ADC) */
6419 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6420 /* unmute Line-Out mixer amp left and right (volume = 0) */
6421 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6422 /* mute pin widget amp left and right (no gain on this amp) */
6423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6424 /* unmute HP mixer amp left and right (volume = 0) */
6425 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6426 /* mute pin widget amp left and right (no gain on this amp) */
6427 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6428 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6431 /* mute analog inputs */
6432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6433 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6434 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6435 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6436 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6437 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6438 /* Unmute Front out path */
6439 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6440 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6441 /* Unmute Headphone out path */
6442 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6443 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6444 /* Unmute Mono out path */
6445 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6446 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6451 static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6452 /* Line out and output */
6453 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6455 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6456 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6457 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6458 /* Mic2 (front panel) pin widget for input and vref at 80% */
6459 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6460 /* Line In pin widget for input */
6461 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6462 /* Headphone pin widget for output */
6463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6464 /* CD pin widget for input */
6465 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6466 /* unmute amp left and right */
6467 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6468 /* set connection select to line in (default select for this ADC) */
6469 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6470 /* unmute Line-Out mixer amp left and right (volume = 0) */
6471 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6472 /* mute pin widget amp left and right (no gain on this amp) */
6473 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6474 /* unmute HP mixer amp left and right (volume = 0) */
6475 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6476 /* mute pin widget amp left and right (no gain on this amp) */
6477 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6478 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6481 /* mute analog inputs */
6482 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6485 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6487 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6488 /* Unmute Front out path */
6489 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6491 /* Unmute Headphone out path */
6492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6493 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6494 /* Unmute Mono out path */
6495 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6496 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6500 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6501 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6502 * audio = 0x16, internal speaker = 0x10.
6504 static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6505 /* Disable all GPIOs */
6506 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6507 /* Internal speaker is connected to headphone pin */
6508 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6509 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6510 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6511 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6512 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6513 /* Ensure all other unused pins are disabled and muted. */
6514 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6516 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6517 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6519 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6520 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6521 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6523 /* Disable digital (SPDIF) pins */
6524 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6525 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6527 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6528 * when acting as an output.
6530 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6532 /* Start with output sum widgets muted and their output gains at min */
6533 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6537 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6539 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6540 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6541 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6543 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6544 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6545 /* Unmute Line1 pin widget output buffer since it starts as an output.
6546 * If the pin mode is changed by the user the pin mode control will
6547 * take care of enabling the pin's input/output buffers as needed.
6548 * Therefore there's no need to enable the input buffer at this
6551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6552 /* Unmute input buffer of pin widget used for Line-in (no equiv
6555 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6557 /* Mute capture amp left and right */
6558 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6559 /* Set ADC connection select to match default mixer setting - line
6562 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6564 /* Do the same for the second ADC: mute capture input amp and
6565 * set ADC connection to line in (on mic1 pin)
6567 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6568 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6570 /* Mute all inputs to mixer widget (even unconnected ones) */
6571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6583 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6584 * similar laptops (adapted from Fujitsu init verbs).
6586 static const struct hda_verb alc260_acer_init_verbs[] = {
6587 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6588 * the headphone jack. Turn this on and rely on the standard mute
6589 * methods whenever the user wants to turn these outputs off.
6591 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6592 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6593 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6594 /* Internal speaker/Headphone jack is connected to Line-out pin */
6595 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6596 /* Internal microphone/Mic jack is connected to Mic1 pin */
6597 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6598 /* Line In jack is connected to Line1 pin */
6599 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6600 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6601 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6602 /* Ensure all other unused pins are disabled and muted. */
6603 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6604 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6605 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6606 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6607 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6609 /* Disable digital (SPDIF) pins */
6610 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6611 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6613 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6614 * bus when acting as outputs.
6616 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6617 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6619 /* Start with output sum widgets muted and their output gains at min */
6620 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6621 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6622 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6623 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6624 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6625 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6626 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6627 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6628 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6630 /* Unmute Line-out pin widget amp left and right
6631 * (no equiv mixer ctrl)
6633 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6634 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6635 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6636 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6637 * inputs. If the pin mode is changed by the user the pin mode control
6638 * will take care of enabling the pin's input/output buffers as needed.
6639 * Therefore there's no need to enable the input buffer at this
6642 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6643 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6645 /* Mute capture amp left and right */
6646 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6647 /* Set ADC connection select to match default mixer setting - mic
6650 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6652 /* Do similar with the second ADC: mute capture input amp and
6653 * set ADC connection to mic to match ALSA's default state.
6655 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6656 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6658 /* Mute all inputs to mixer widget (even unconnected ones) */
6659 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6660 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6662 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6663 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6664 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6665 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6666 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6671 /* Initialisation sequence for Maxdata Favorit 100XS
6672 * (adapted from Acer init verbs).
6674 static const struct hda_verb alc260_favorit100_init_verbs[] = {
6675 /* GPIO 0 enables the output jack.
6676 * Turn this on and rely on the standard mute
6677 * methods whenever the user wants to turn these outputs off.
6679 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6680 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6681 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6682 /* Line/Mic input jack is connected to Mic1 pin */
6683 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6684 /* Ensure all other unused pins are disabled and muted. */
6685 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6686 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6687 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6688 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6689 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6690 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6695 /* Disable digital (SPDIF) pins */
6696 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6697 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6699 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6700 * bus when acting as outputs.
6702 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6703 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6705 /* Start with output sum widgets muted and their output gains at min */
6706 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6707 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6708 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6709 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6710 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6711 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6712 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6713 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6714 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6716 /* Unmute Line-out pin widget amp left and right
6717 * (no equiv mixer ctrl)
6719 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6720 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6721 * inputs. If the pin mode is changed by the user the pin mode control
6722 * will take care of enabling the pin's input/output buffers as needed.
6723 * Therefore there's no need to enable the input buffer at this
6726 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6728 /* Mute capture amp left and right */
6729 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6730 /* Set ADC connection select to match default mixer setting - mic
6733 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6735 /* Do similar with the second ADC: mute capture input amp and
6736 * set ADC connection to mic to match ALSA's default state.
6738 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6739 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6741 /* Mute all inputs to mixer widget (even unconnected ones) */
6742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6748 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6754 static const struct hda_verb alc260_will_verbs[] = {
6755 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6756 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6757 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6758 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6759 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6760 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6764 static const struct hda_verb alc260_replacer_672v_verbs[] = {
6765 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6766 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6767 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6769 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6770 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6771 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6773 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6777 /* toggle speaker-output according to the hp-jack state */
6778 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6780 unsigned int present;
6782 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6783 present = snd_hda_jack_detect(codec, 0x0f);
6785 snd_hda_codec_write_cache(codec, 0x01, 0,
6786 AC_VERB_SET_GPIO_DATA, 1);
6787 snd_hda_codec_write_cache(codec, 0x0f, 0,
6788 AC_VERB_SET_PIN_WIDGET_CONTROL,
6791 snd_hda_codec_write_cache(codec, 0x01, 0,
6792 AC_VERB_SET_GPIO_DATA, 0);
6793 snd_hda_codec_write_cache(codec, 0x0f, 0,
6794 AC_VERB_SET_PIN_WIDGET_CONTROL,
6799 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6802 if ((res >> 26) == ALC880_HP_EVENT)
6803 alc260_replacer_672v_automute(codec);
6806 static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6807 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6808 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6809 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6810 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6811 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6813 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6814 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6815 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6816 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6820 /* Test configuration for debugging, modelled after the ALC880 test
6823 #ifdef CONFIG_SND_DEBUG
6824 static const hda_nid_t alc260_test_dac_nids[1] = {
6827 static const hda_nid_t alc260_test_adc_nids[2] = {
6830 /* For testing the ALC260, each input MUX needs its own definition since
6831 * the signal assignments are different. This assumes that the first ADC
6834 static const struct hda_input_mux alc260_test_capture_sources[2] = {
6838 { "MIC1 pin", 0x0 },
6839 { "MIC2 pin", 0x1 },
6840 { "LINE1 pin", 0x2 },
6841 { "LINE2 pin", 0x3 },
6843 { "LINE-OUT pin", 0x5 },
6844 { "HP-OUT pin", 0x6 },
6850 { "MIC1 pin", 0x0 },
6851 { "MIC2 pin", 0x1 },
6852 { "LINE1 pin", 0x2 },
6853 { "LINE2 pin", 0x3 },
6856 { "LINE-OUT pin", 0x6 },
6857 { "HP-OUT pin", 0x7 },
6861 static const struct snd_kcontrol_new alc260_test_mixer[] = {
6862 /* Output driver widgets */
6863 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6864 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6865 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6866 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6867 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6868 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6870 /* Modes for retasking pin widgets
6871 * Note: the ALC260 doesn't seem to act on requests to enable mic
6872 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6873 * mention this restriction. At this stage it's not clear whether
6874 * this behaviour is intentional or is a hardware bug in chip
6875 * revisions available at least up until early 2006. Therefore for
6876 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6877 * choices, but if it turns out that the lack of mic bias for these
6878 * NIDs is intentional we could change their modes from
6879 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6881 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6882 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6883 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6884 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6885 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6886 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6888 /* Loopback mixer controls */
6889 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6890 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6891 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6892 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6893 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6894 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6895 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6896 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6897 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6898 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6899 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6900 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6901 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6902 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6904 /* Controls for GPIO pins, assuming they are configured as outputs */
6905 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6906 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6907 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6908 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6910 /* Switches to allow the digital IO pins to be enabled. The datasheet
6911 * is ambigious as to which NID is which; testing on laptops which
6912 * make this output available should provide clarification.
6914 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6915 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6917 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6918 * this output to turn on an external amplifier.
6920 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6921 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6925 static const struct hda_verb alc260_test_init_verbs[] = {
6926 /* Enable all GPIOs as outputs with an initial value of 0 */
6927 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6928 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6929 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6931 /* Enable retasking pins as output, initially without power amp */
6932 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6933 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6936 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6937 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6939 /* Disable digital (SPDIF) pins initially, but users can enable
6940 * them via a mixer switch. In the case of SPDIF-out, this initverb
6941 * payload also sets the generation to 0, output to be in "consumer"
6942 * PCM format, copyright asserted, no pre-emphasis and no validity
6945 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6946 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6948 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6949 * OUT1 sum bus when acting as an output.
6951 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6952 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6953 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6954 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6956 /* Start with output sum widgets muted and their output gains at min */
6957 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6958 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6959 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6960 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6961 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6962 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6963 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6964 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6965 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6967 /* Unmute retasking pin widget output buffers since the default
6968 * state appears to be output. As the pin mode is changed by the
6969 * user the pin mode control will take care of enabling the pin's
6970 * input/output buffers as needed.
6972 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6973 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6974 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6976 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6977 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6978 /* Also unmute the mono-out pin widget */
6979 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6981 /* Mute capture amp left and right */
6982 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6983 /* Set ADC connection select to match default mixer setting (mic1
6986 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6988 /* Do the same for the second ADC: mute capture input amp and
6989 * set ADC connection to mic1 pin
6991 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6992 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6994 /* Mute all inputs to mixer widget (even unconnected ones) */
6995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7001 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7002 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7009 * for BIOS auto-configuration
7012 /* convert from pin to volume-mixer widget */
7013 static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7015 if (nid >= 0x0f && nid <= 0x11)
7017 else if (nid >= 0x12 && nid <= 0x15)
7023 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
7024 const char *pfx, int *vol_bits)
7027 unsigned long vol_val, sw_val;
7030 nid_vol = alc260_pin_to_vol_mix(nid);
7037 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, chs, 0, HDA_OUTPUT);
7038 sw_val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
7040 if (!(*vol_bits & (1 << nid_vol))) {
7041 /* first control for the volume widget */
7042 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7045 *vol_bits |= (1 << nid_vol);
7047 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7053 /* add playback controls from the parsed DAC table */
7054 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7055 const struct auto_pin_cfg *cfg)
7061 spec->multiout.num_dacs = 1;
7062 spec->multiout.dac_nids = spec->private_dac_nids;
7063 spec->private_dac_nids[0] = 0x02;
7065 nid = cfg->line_out_pins[0];
7069 pfx = alc_get_line_out_pfx(spec, 0, true, &index);
7070 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7075 nid = cfg->speaker_pins[0];
7077 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
7082 nid = cfg->hp_pins[0];
7084 err = alc260_add_playback_controls(spec, nid, "Headphone",
7092 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7093 hda_nid_t nid, int pin_type,
7098 alc_set_pin_output(codec, nid, pin_type);
7099 /* need the manual connection? */
7101 int idx = nid - 0x12;
7102 snd_hda_codec_write(codec, idx + 0x0b, 0,
7103 AC_VERB_SET_CONNECT_SEL, sel_idx);
7106 mix = alc260_pin_to_vol_mix(nid);
7109 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7111 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7113 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7117 static void alc260_auto_init_multi_out(struct hda_codec *codec)
7119 struct alc_spec *spec = codec->spec;
7122 nid = spec->autocfg.line_out_pins[0];
7124 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7125 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7128 nid = spec->autocfg.speaker_pins[0];
7130 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7132 nid = spec->autocfg.hp_pins[0];
7134 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7137 static int alc260_parse_auto_config(struct hda_codec *codec)
7139 struct alc_spec *spec = codec->spec;
7141 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7143 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7147 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7150 if (!spec->kctls.list)
7151 return 0; /* can't find valid BIOS pin config */
7152 err = alc_auto_create_input_ctls(codec);
7156 spec->multiout.max_channels = 2;
7158 if (spec->autocfg.dig_outs)
7159 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7160 if (spec->kctls.list)
7161 add_mixer(spec, spec->kctls.list);
7163 spec->num_mux_defs = 1;
7164 spec->input_mux = &spec->private_imux[0];
7166 if (!spec->dual_adc_switch)
7167 alc_remove_invalid_adc_nids(codec);
7169 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7174 /* additional initialization for auto-configuration model */
7175 static void alc260_auto_init(struct hda_codec *codec)
7177 struct alc_spec *spec = codec->spec;
7178 alc260_auto_init_multi_out(codec);
7179 alc_auto_init_analog_input(codec);
7180 alc_auto_init_input_src(codec);
7181 alc_auto_init_digital(codec);
7182 if (spec->unsol_event)
7183 alc_inithook(codec);
7186 #ifdef CONFIG_SND_HDA_POWER_SAVE
7187 static const struct hda_amp_list alc260_loopbacks[] = {
7188 { 0x07, HDA_INPUT, 0 },
7189 { 0x07, HDA_INPUT, 1 },
7190 { 0x07, HDA_INPUT, 2 },
7191 { 0x07, HDA_INPUT, 3 },
7192 { 0x07, HDA_INPUT, 4 },
7204 static const struct alc_fixup alc260_fixups[] = {
7205 [PINFIX_HP_DC5750] = {
7206 .type = ALC_FIXUP_PINS,
7207 .v.pins = (const struct alc_pincfg[]) {
7208 { 0x11, 0x90130110 }, /* speaker */
7214 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7215 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7220 * ALC260 configurations
7222 static const char * const alc260_models[ALC260_MODEL_LAST] = {
7223 [ALC260_BASIC] = "basic",
7225 [ALC260_HP_3013] = "hp-3013",
7226 [ALC260_HP_DC7600] = "hp-dc7600",
7227 [ALC260_FUJITSU_S702X] = "fujitsu",
7228 [ALC260_ACER] = "acer",
7229 [ALC260_WILL] = "will",
7230 [ALC260_REPLACER_672V] = "replacer",
7231 [ALC260_FAVORIT100] = "favorit100",
7232 #ifdef CONFIG_SND_DEBUG
7233 [ALC260_TEST] = "test",
7235 [ALC260_AUTO] = "auto",
7238 static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7239 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7240 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7241 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7242 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7243 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7244 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7245 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7246 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7247 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7248 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7249 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7250 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7251 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7252 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7253 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7254 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7255 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7256 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7257 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7258 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7262 static const struct alc_config_preset alc260_presets[] = {
7264 .mixers = { alc260_base_output_mixer,
7265 alc260_input_mixer },
7266 .init_verbs = { alc260_init_verbs },
7267 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7268 .dac_nids = alc260_dac_nids,
7269 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7270 .adc_nids = alc260_dual_adc_nids,
7271 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7272 .channel_mode = alc260_modes,
7273 .input_mux = &alc260_capture_source,
7276 .mixers = { alc260_hp_output_mixer,
7277 alc260_input_mixer },
7278 .init_verbs = { alc260_init_verbs,
7279 alc260_hp_unsol_verbs },
7280 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7281 .dac_nids = alc260_dac_nids,
7282 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7283 .adc_nids = alc260_adc_nids_alt,
7284 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7285 .channel_mode = alc260_modes,
7286 .input_mux = &alc260_capture_source,
7287 .unsol_event = alc_sku_unsol_event,
7288 .setup = alc260_hp_setup,
7289 .init_hook = alc_inithook,
7291 [ALC260_HP_DC7600] = {
7292 .mixers = { alc260_hp_dc7600_mixer,
7293 alc260_input_mixer },
7294 .init_verbs = { alc260_init_verbs,
7295 alc260_hp_dc7600_verbs },
7296 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7297 .dac_nids = alc260_dac_nids,
7298 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7299 .adc_nids = alc260_adc_nids_alt,
7300 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7301 .channel_mode = alc260_modes,
7302 .input_mux = &alc260_capture_source,
7303 .unsol_event = alc_sku_unsol_event,
7304 .setup = alc260_hp_3012_setup,
7305 .init_hook = alc_inithook,
7307 [ALC260_HP_3013] = {
7308 .mixers = { alc260_hp_3013_mixer,
7309 alc260_input_mixer },
7310 .init_verbs = { alc260_hp_3013_init_verbs,
7311 alc260_hp_3013_unsol_verbs },
7312 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7313 .dac_nids = alc260_dac_nids,
7314 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7315 .adc_nids = alc260_adc_nids_alt,
7316 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7317 .channel_mode = alc260_modes,
7318 .input_mux = &alc260_capture_source,
7319 .unsol_event = alc_sku_unsol_event,
7320 .setup = alc260_hp_3013_setup,
7321 .init_hook = alc_inithook,
7323 [ALC260_FUJITSU_S702X] = {
7324 .mixers = { alc260_fujitsu_mixer },
7325 .init_verbs = { alc260_fujitsu_init_verbs },
7326 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7327 .dac_nids = alc260_dac_nids,
7328 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7329 .adc_nids = alc260_dual_adc_nids,
7330 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7331 .channel_mode = alc260_modes,
7332 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7333 .input_mux = alc260_fujitsu_capture_sources,
7336 .mixers = { alc260_acer_mixer },
7337 .init_verbs = { alc260_acer_init_verbs },
7338 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7339 .dac_nids = alc260_dac_nids,
7340 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7341 .adc_nids = alc260_dual_adc_nids,
7342 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7343 .channel_mode = alc260_modes,
7344 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7345 .input_mux = alc260_acer_capture_sources,
7347 [ALC260_FAVORIT100] = {
7348 .mixers = { alc260_favorit100_mixer },
7349 .init_verbs = { alc260_favorit100_init_verbs },
7350 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7351 .dac_nids = alc260_dac_nids,
7352 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7353 .adc_nids = alc260_dual_adc_nids,
7354 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7355 .channel_mode = alc260_modes,
7356 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7357 .input_mux = alc260_favorit100_capture_sources,
7360 .mixers = { alc260_will_mixer },
7361 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7362 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7363 .dac_nids = alc260_dac_nids,
7364 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7365 .adc_nids = alc260_adc_nids,
7366 .dig_out_nid = ALC260_DIGOUT_NID,
7367 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7368 .channel_mode = alc260_modes,
7369 .input_mux = &alc260_capture_source,
7371 [ALC260_REPLACER_672V] = {
7372 .mixers = { alc260_replacer_672v_mixer },
7373 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7374 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7375 .dac_nids = alc260_dac_nids,
7376 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7377 .adc_nids = alc260_adc_nids,
7378 .dig_out_nid = ALC260_DIGOUT_NID,
7379 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7380 .channel_mode = alc260_modes,
7381 .input_mux = &alc260_capture_source,
7382 .unsol_event = alc260_replacer_672v_unsol_event,
7383 .init_hook = alc260_replacer_672v_automute,
7385 #ifdef CONFIG_SND_DEBUG
7387 .mixers = { alc260_test_mixer },
7388 .init_verbs = { alc260_test_init_verbs },
7389 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7390 .dac_nids = alc260_test_dac_nids,
7391 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7392 .adc_nids = alc260_test_adc_nids,
7393 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7394 .channel_mode = alc260_modes,
7395 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7396 .input_mux = alc260_test_capture_sources,
7401 static int patch_alc260(struct hda_codec *codec)
7403 struct alc_spec *spec;
7404 int err, board_config;
7406 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7412 spec->mixer_nid = 0x07;
7414 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7417 if (board_config < 0) {
7418 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7420 board_config = ALC260_AUTO;
7423 if (board_config == ALC260_AUTO) {
7424 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7425 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7428 if (board_config == ALC260_AUTO) {
7429 /* automatic parse from the BIOS config */
7430 err = alc260_parse_auto_config(codec);
7436 "hda_codec: Cannot set up configuration "
7437 "from BIOS. Using base mode...\n");
7438 board_config = ALC260_BASIC;
7442 err = snd_hda_attach_beep_device(codec, 0x1);
7448 if (board_config != ALC260_AUTO)
7449 setup_preset(codec, &alc260_presets[board_config]);
7451 if (!spec->adc_nids && spec->input_mux) {
7452 alc_auto_fill_adc_caps(codec);
7453 alc_remove_invalid_adc_nids(codec);
7455 set_capture_mixer(codec);
7456 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7458 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7460 spec->vmaster_nid = 0x08;
7462 codec->patch_ops = alc_patch_ops;
7463 if (board_config == ALC260_AUTO)
7464 spec->init_hook = alc260_auto_init;
7465 spec->shutup = alc_eapd_shutup;
7466 #ifdef CONFIG_SND_HDA_POWER_SAVE
7467 if (!spec->loopback.amplist)
7468 spec->loopback.amplist = alc260_loopbacks;
7476 * ALC882/883/885/888/889 support
7478 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7479 * configuration. Each pin widget can choose any input DACs and a mixer.
7480 * Each ADC is connected from a mixer of all inputs. This makes possible
7481 * 6-channel independent captures.
7483 * In addition, an independent DAC for the multi-playback (not used in this
7486 #define ALC882_DIGOUT_NID 0x06
7487 #define ALC882_DIGIN_NID 0x0a
7488 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7489 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7490 #define ALC1200_DIGOUT_NID 0x10
7493 static const struct hda_channel_mode alc882_ch_modes[1] = {
7498 static const hda_nid_t alc882_dac_nids[4] = {
7499 /* front, rear, clfe, rear_surr */
7500 0x02, 0x03, 0x04, 0x05
7502 #define alc883_dac_nids alc882_dac_nids
7505 #define alc882_adc_nids alc880_adc_nids
7506 #define alc882_adc_nids_alt alc880_adc_nids_alt
7507 #define alc883_adc_nids alc882_adc_nids_alt
7508 static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7509 static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7510 #define alc889_adc_nids alc880_adc_nids
7512 static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7513 static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7514 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7515 static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7516 #define alc889_capsrc_nids alc882_capsrc_nids
7519 /* FIXME: should be a matrix-type input source selection */
7521 static const struct hda_input_mux alc882_capture_source = {
7525 { "Front Mic", 0x1 },
7531 #define alc883_capture_source alc882_capture_source
7533 static const struct hda_input_mux alc889_capture_source = {
7536 { "Front Mic", 0x0 },
7542 static const struct hda_input_mux mb5_capture_source = {
7551 static const struct hda_input_mux macmini3_capture_source = {
7559 static const struct hda_input_mux alc883_3stack_6ch_intel = {
7563 { "Front Mic", 0x0 },
7569 static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7577 static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7581 { "Internal Mic", 0x1 },
7587 static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7591 { "Internal Mic", 0x1 },
7595 static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7599 { "Front Mic", 0x1 },
7604 static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7612 static const struct hda_input_mux alc889A_mb31_capture_source = {
7616 /* Front Mic (0x01) unused */
7618 /* Line 2 (0x03) unused */
7619 /* CD (0x04) unused? */
7623 static const struct hda_input_mux alc889A_imac91_capture_source = {
7627 { "Line", 0x2 }, /* Not sure! */
7634 static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7641 static const struct hda_verb alc882_3ST_ch2_init[] = {
7642 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7643 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7644 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7645 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7652 static const struct hda_verb alc882_3ST_ch4_init[] = {
7653 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7654 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7655 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7656 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7657 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7664 static const struct hda_verb alc882_3ST_ch6_init[] = {
7665 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7666 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7667 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7668 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7669 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7670 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7674 static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7675 { 2, alc882_3ST_ch2_init },
7676 { 4, alc882_3ST_ch4_init },
7677 { 6, alc882_3ST_ch6_init },
7680 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7685 static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7686 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7687 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7688 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7689 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7690 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7697 static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7698 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7699 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7700 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7701 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7702 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7703 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7710 static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7711 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7712 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7713 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7714 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7715 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7716 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7717 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7721 static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7722 { 2, alc883_3ST_ch2_clevo_init },
7723 { 4, alc883_3ST_ch4_clevo_init },
7724 { 6, alc883_3ST_ch6_clevo_init },
7731 static const struct hda_verb alc882_sixstack_ch6_init[] = {
7732 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7733 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7734 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7735 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 static const struct hda_verb alc882_sixstack_ch8_init[] = {
7743 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7745 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7746 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7750 static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7751 { 6, alc882_sixstack_ch6_init },
7752 { 8, alc882_sixstack_ch8_init },
7756 /* Macbook Air 2,1 */
7758 static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7763 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7769 static const struct hda_verb alc885_mbp_ch2_init[] = {
7770 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7771 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7772 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7779 static const struct hda_verb alc885_mbp_ch4_init[] = {
7780 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7781 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7782 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7783 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7784 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7788 static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7789 { 2, alc885_mbp_ch2_init },
7790 { 4, alc885_mbp_ch4_init },
7795 * Speakers/Woofer/HP = Front
7798 static const struct hda_verb alc885_mb5_ch2_init[] = {
7799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7806 * Speakers/HP = Front
7810 static const struct hda_verb alc885_mb5_ch6_init[] = {
7811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7813 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7817 static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7818 { 2, alc885_mb5_ch2_init },
7819 { 6, alc885_mb5_ch6_init },
7822 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7827 static const struct hda_verb alc883_4ST_ch2_init[] = {
7828 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7829 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7830 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7831 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7832 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7833 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7840 static const struct hda_verb alc883_4ST_ch4_init[] = {
7841 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7842 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7843 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7844 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7845 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7846 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7847 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7854 static const struct hda_verb alc883_4ST_ch6_init[] = {
7855 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7856 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7857 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7858 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7859 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7862 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7869 static const struct hda_verb alc883_4ST_ch8_init[] = {
7870 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7871 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7872 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7876 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7877 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7878 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7882 static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7883 { 2, alc883_4ST_ch2_init },
7884 { 4, alc883_4ST_ch4_init },
7885 { 6, alc883_4ST_ch6_init },
7886 { 8, alc883_4ST_ch8_init },
7893 static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
7894 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7895 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7896 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7897 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7904 static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
7905 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7906 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7907 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7909 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7916 static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
7917 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7918 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7919 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7920 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7921 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7922 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7926 static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7927 { 2, alc883_3ST_ch2_intel_init },
7928 { 4, alc883_3ST_ch4_intel_init },
7929 { 6, alc883_3ST_ch6_intel_init },
7935 static const struct hda_verb alc889_ch2_intel_init[] = {
7936 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7937 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7938 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7939 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7940 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7941 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7948 static const struct hda_verb alc889_ch6_intel_init[] = {
7949 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7950 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7951 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7952 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7953 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7954 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7961 static const struct hda_verb alc889_ch8_intel_init[] = {
7962 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7963 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7964 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7965 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7966 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7967 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7968 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7972 static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7973 { 2, alc889_ch2_intel_init },
7974 { 6, alc889_ch6_intel_init },
7975 { 8, alc889_ch8_intel_init },
7981 static const struct hda_verb alc883_sixstack_ch6_init[] = {
7982 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7983 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7984 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7985 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7992 static const struct hda_verb alc883_sixstack_ch8_init[] = {
7993 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7994 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7995 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7996 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8000 static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8001 { 6, alc883_sixstack_ch6_init },
8002 { 8, alc883_sixstack_ch8_init },
8006 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8007 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8009 static const struct snd_kcontrol_new alc882_base_mixer[] = {
8010 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8011 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8012 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8013 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8014 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8015 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8016 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8017 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8018 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8019 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8020 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8021 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8022 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8024 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8025 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8026 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8027 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8028 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8029 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8034 /* Macbook Air 2,1 same control for HP and internal Speaker */
8036 static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8037 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8038 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8043 static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8044 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8045 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8046 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8047 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8048 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
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, 0x00, HDA_INPUT),
8052 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8053 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8058 static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8059 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8060 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8061 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8062 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8063 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8064 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8065 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8066 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8067 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8068 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8069 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8070 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8071 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8072 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8076 static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8078 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8079 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8080 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8081 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8082 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8083 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8084 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8085 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8086 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8087 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8091 static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8092 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8093 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8098 static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8100 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8101 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8102 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8103 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8104 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8106 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8107 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8111 static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8113 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8115 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8116 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8118 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8121 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8122 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8123 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8124 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8128 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8129 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8131 static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8132 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8133 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8134 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8135 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8136 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8137 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8138 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8139 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8140 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8141 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8144 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8148 static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8149 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8150 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8154 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8155 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8157 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8162 static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8164 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8165 .name = "Channel Mode",
8166 .info = alc_ch_mode_info,
8167 .get = alc_ch_mode_get,
8168 .put = alc_ch_mode_put,
8173 static const struct hda_verb alc882_base_init_verbs[] = {
8174 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8175 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8178 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8179 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8182 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8184 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8185 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8187 /* Front Pin: output 0 (0x0c) */
8188 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8189 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8190 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8191 /* Rear Pin: output 1 (0x0d) */
8192 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8193 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8194 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8195 /* CLFE Pin: output 2 (0x0e) */
8196 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8197 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8198 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8199 /* Side Pin: output 3 (0x0f) */
8200 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8201 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8202 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8203 /* Mic (rear) pin: input vref at 80% */
8204 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8205 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8206 /* Front Mic pin: input vref at 80% */
8207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8208 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8209 /* Line In pin: input */
8210 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8211 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8212 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8213 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8214 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8215 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8216 /* CD pin widget for input */
8217 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8219 /* FIXME: use matrix-type input source selection */
8220 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8222 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8225 /* ADC2: mute amp left and right */
8226 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8227 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8228 /* ADC3: mute amp left and right */
8229 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8230 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8235 static const struct hda_verb alc882_adc1_init_verbs[] = {
8236 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8237 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8238 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8239 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8240 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8241 /* ADC1: mute amp left and right */
8242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8243 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8247 static const struct hda_verb alc882_eapd_verbs[] = {
8248 /* change to EAPD mode */
8249 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8250 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8254 static const struct hda_verb alc889_eapd_verbs[] = {
8255 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8256 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8260 static const struct hda_verb alc_hp15_unsol_verbs[] = {
8261 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8262 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8266 static const struct hda_verb alc885_init_verbs[] = {
8267 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8268 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8269 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8271 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8272 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8274 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8275 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8277 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8278 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8280 /* Front HP Pin: output 0 (0x0c) */
8281 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8282 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8284 /* Front Pin: output 0 (0x0c) */
8285 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8286 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8287 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8288 /* Rear Pin: output 1 (0x0d) */
8289 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8290 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8291 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8292 /* CLFE Pin: output 2 (0x0e) */
8293 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8294 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8295 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8296 /* Side Pin: output 3 (0x0f) */
8297 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8298 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8299 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8300 /* Mic (rear) pin: input vref at 80% */
8301 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8302 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8303 /* Front Mic pin: input vref at 80% */
8304 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8305 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8306 /* Line In pin: input */
8307 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8308 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8310 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8312 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8314 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8317 /* ADC2: mute amp left and right */
8318 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8319 /* ADC3: mute amp left and right */
8320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8325 static const struct hda_verb alc885_init_input_verbs[] = {
8326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8333 /* Unmute Selector 24h and set the default input to front mic */
8334 static const struct hda_verb alc889_init_input_verbs[] = {
8335 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8336 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8341 #define alc883_init_verbs alc882_base_init_verbs
8344 static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8345 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8346 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8347 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8348 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8349 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8350 /* FIXME: this looks suspicious...
8351 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8352 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8357 static const struct hda_verb alc882_macpro_init_verbs[] = {
8358 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8362 /* Front Pin: output 0 (0x0c) */
8363 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8364 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8365 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8366 /* Front Mic pin: input vref at 80% */
8367 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8368 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8369 /* Speaker: output */
8370 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8371 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8372 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8373 /* Headphone output (output 0 - 0x0c) */
8374 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8375 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8376 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8378 /* FIXME: use matrix-type input source selection */
8379 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8380 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8381 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8382 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8383 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8388 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8391 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8393 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8395 /* ADC1: mute amp left and right */
8396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8397 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8398 /* ADC2: mute amp left and right */
8399 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8400 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8401 /* ADC3: mute amp left and right */
8402 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8403 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 static const struct hda_verb alc885_mb5_init_verbs[] = {
8411 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8412 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8413 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8414 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8418 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8419 /* Surround mixer */
8420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8421 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8425 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8428 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8430 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8431 /* Front Pin (0x0c) */
8432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8433 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8434 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8435 /* LFE Pin (0x0e) */
8436 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8438 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8441 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8442 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8443 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8444 /* Front Mic pin: input vref at 80% */
8445 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8446 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8448 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8449 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8458 static const struct hda_verb alc885_macmini3_init_verbs[] = {
8460 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8461 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8462 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8463 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8466 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8467 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8468 /* Surround mixer */
8469 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8470 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8474 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8475 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8477 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8478 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8479 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8480 /* Front Pin (0x0c) */
8481 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8482 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8483 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8484 /* LFE Pin (0x0e) */
8485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8486 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8487 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8489 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8491 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8492 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8497 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8498 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8499 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8500 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8505 static const struct hda_verb alc885_mba21_init_verbs[] = {
8506 /*Internal and HP Speaker Mixer*/
8507 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8510 /*Internal Speaker Pin (0x0c)*/
8511 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8512 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8513 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8514 /* HP Pin: output 0 (0x0e) */
8515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8516 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8517 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8518 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8519 /* Line in (is hp when jack connected)*/
8520 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8521 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8527 /* Macbook Pro rev3 */
8528 static const struct hda_verb alc885_mbp3_init_verbs[] = {
8529 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8530 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8539 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8540 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8541 /* Front Pin: output 0 (0x0c) */
8542 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8543 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8544 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8545 /* HP Pin: output 0 (0x0e) */
8546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8548 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8549 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8550 /* Mic (rear) pin: input vref at 80% */
8551 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8552 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8553 /* Front Mic pin: input vref at 80% */
8554 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8556 /* Line In pin: use output 1 when in LineOut mode */
8557 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8558 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8559 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8561 /* FIXME: use matrix-type input source selection */
8562 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8563 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8564 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8565 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8569 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8570 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8571 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8574 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8578 /* ADC1: mute amp left and right */
8579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8580 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8581 /* ADC2: mute amp left and right */
8582 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8583 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8584 /* ADC3: mute amp left and right */
8585 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8586 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 static const struct hda_verb alc885_imac91_init_verbs[] = {
8593 /* Internal Speaker Pin (0x0c) */
8594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8596 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8597 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8599 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8602 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8603 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8604 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8606 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8607 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8608 /* Front Mic pin: input vref at 80% */
8609 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8610 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8612 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8615 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8616 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8619 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8620 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8621 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8622 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8623 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8624 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8625 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8627 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8629 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8630 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8631 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8632 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8633 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8634 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8635 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8636 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8637 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8638 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8639 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8640 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8641 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8642 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8646 /* iMac 24 mixer. */
8647 static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8648 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8649 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8653 /* iMac 24 init verbs. */
8654 static const struct hda_verb alc885_imac24_init_verbs[] = {
8655 /* Internal speakers: output 0 (0x0c) */
8656 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8657 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8659 /* Internal speakers: output 0 (0x0c) */
8660 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8661 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8662 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8663 /* Headphone: output 0 (0x0c) */
8664 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8665 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8666 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8667 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8668 /* Front Mic: input vref at 80% */
8669 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8674 /* Toggle speaker-output according to the hp-jack state */
8675 static void alc885_imac24_setup(struct hda_codec *codec)
8677 struct alc_spec *spec = codec->spec;
8679 spec->autocfg.hp_pins[0] = 0x14;
8680 spec->autocfg.speaker_pins[0] = 0x18;
8681 spec->autocfg.speaker_pins[1] = 0x1a;
8683 spec->automute_mode = ALC_AUTOMUTE_AMP;
8686 #define alc885_mb5_setup alc885_imac24_setup
8687 #define alc885_macmini3_setup alc885_imac24_setup
8689 /* Macbook Air 2,1 */
8690 static void alc885_mba21_setup(struct hda_codec *codec)
8692 struct alc_spec *spec = codec->spec;
8694 spec->autocfg.hp_pins[0] = 0x14;
8695 spec->autocfg.speaker_pins[0] = 0x18;
8697 spec->automute_mode = ALC_AUTOMUTE_AMP;
8702 static void alc885_mbp3_setup(struct hda_codec *codec)
8704 struct alc_spec *spec = codec->spec;
8706 spec->autocfg.hp_pins[0] = 0x15;
8707 spec->autocfg.speaker_pins[0] = 0x14;
8709 spec->automute_mode = ALC_AUTOMUTE_AMP;
8712 static void alc885_imac91_setup(struct hda_codec *codec)
8714 struct alc_spec *spec = codec->spec;
8716 spec->autocfg.hp_pins[0] = 0x14;
8717 spec->autocfg.speaker_pins[0] = 0x18;
8718 spec->autocfg.speaker_pins[1] = 0x1a;
8720 spec->automute_mode = ALC_AUTOMUTE_AMP;
8723 static const struct hda_verb alc882_targa_verbs[] = {
8724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8727 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8728 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8730 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8731 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8732 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8734 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8738 /* toggle speaker-output according to the hp-jack state */
8739 static void alc882_targa_automute(struct hda_codec *codec)
8741 struct alc_spec *spec = codec->spec;
8742 alc_hp_automute(codec);
8743 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8744 spec->jack_present ? 1 : 3);
8747 static void alc882_targa_setup(struct hda_codec *codec)
8749 struct alc_spec *spec = codec->spec;
8751 spec->autocfg.hp_pins[0] = 0x14;
8752 spec->autocfg.speaker_pins[0] = 0x1b;
8754 spec->automute_mode = ALC_AUTOMUTE_AMP;
8757 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8759 if ((res >> 26) == ALC880_HP_EVENT)
8760 alc882_targa_automute(codec);
8763 static const struct hda_verb alc882_asus_a7j_verbs[] = {
8764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8767 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8768 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8769 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8771 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8772 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8773 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8775 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8776 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8777 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8781 static const struct hda_verb alc882_asus_a7m_verbs[] = {
8782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8783 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8785 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8786 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8787 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8789 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8790 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8791 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8793 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8794 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8795 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8799 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8801 unsigned int gpiostate, gpiomask, gpiodir;
8803 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8804 AC_VERB_GET_GPIO_DATA, 0);
8807 gpiostate |= (1 << pin);
8809 gpiostate &= ~(1 << pin);
8811 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8812 AC_VERB_GET_GPIO_MASK, 0);
8813 gpiomask |= (1 << pin);
8815 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8816 AC_VERB_GET_GPIO_DIRECTION, 0);
8817 gpiodir |= (1 << pin);
8820 snd_hda_codec_write(codec, codec->afg, 0,
8821 AC_VERB_SET_GPIO_MASK, gpiomask);
8822 snd_hda_codec_write(codec, codec->afg, 0,
8823 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8827 snd_hda_codec_write(codec, codec->afg, 0,
8828 AC_VERB_SET_GPIO_DATA, gpiostate);
8831 /* set up GPIO at initialization */
8832 static void alc885_macpro_init_hook(struct hda_codec *codec)
8834 alc882_gpio_mute(codec, 0, 0);
8835 alc882_gpio_mute(codec, 1, 0);
8838 /* set up GPIO and update auto-muting at initialization */
8839 static void alc885_imac24_init_hook(struct hda_codec *codec)
8841 alc885_macpro_init_hook(codec);
8842 alc_hp_automute(codec);
8845 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8846 static const struct hda_verb alc889A_mb31_ch2_init[] = {
8847 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8848 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8849 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8850 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8854 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8855 static const struct hda_verb alc889A_mb31_ch4_init[] = {
8856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8857 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8858 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8859 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8863 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8864 static const struct hda_verb alc889A_mb31_ch5_init[] = {
8865 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8866 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8867 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8868 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8872 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8873 static const struct hda_verb alc889A_mb31_ch6_init[] = {
8874 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8875 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8881 static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8882 { 2, alc889A_mb31_ch2_init },
8883 { 4, alc889A_mb31_ch4_init },
8884 { 5, alc889A_mb31_ch5_init },
8885 { 6, alc889A_mb31_ch6_init },
8888 static const struct hda_verb alc883_medion_eapd_verbs[] = {
8889 /* eanable EAPD on medion laptop */
8890 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8891 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8895 #define alc883_base_mixer alc882_base_mixer
8897 static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
8898 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8899 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8900 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8901 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8902 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8903 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8904 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8906 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8908 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8909 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8910 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8914 static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8915 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8916 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8917 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8918 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8920 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8921 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8922 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8923 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8924 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8928 static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8929 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8930 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8931 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8932 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8936 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8937 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8938 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8942 static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8943 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8944 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8946 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8947 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8948 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8949 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8950 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8952 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8953 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8954 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8955 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8959 static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8965 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8966 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8967 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8968 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8971 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8972 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8973 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8977 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8978 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8982 static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8983 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8984 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8985 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8986 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8987 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8989 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8990 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8991 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8992 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8993 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8994 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8998 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8999 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9001 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9002 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9006 static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9009 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9010 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9011 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9013 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9014 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9015 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9016 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9017 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9018 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9019 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9020 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9022 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9023 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9024 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9025 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9026 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9030 static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9031 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9032 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9033 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9034 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9035 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9036 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9037 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9038 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9039 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9040 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9041 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9042 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9043 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9045 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9047 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9048 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9049 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9053 static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9054 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9055 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9056 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9057 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9058 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9059 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9060 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9061 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9062 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9063 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9064 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9065 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9066 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9067 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9069 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9070 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9074 static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9075 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9076 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9077 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9078 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9080 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9082 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9084 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9085 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9086 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9090 static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9091 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9092 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9093 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9094 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9095 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9099 static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9101 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9102 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9103 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9104 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9106 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9107 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9111 static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9112 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9113 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9115 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9116 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9119 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9120 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9124 static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9125 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9126 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9127 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9128 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9129 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9130 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9134 static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9135 /* Unmute front mixer */
9136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9137 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9139 /* Set speaker pin to front mixer */
9140 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9142 /* Init headphone pin */
9143 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9144 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9145 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9146 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9151 /* toggle speaker-output according to the hp-jack state */
9152 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9154 struct alc_spec *spec = codec->spec;
9156 spec->autocfg.hp_pins[0] = 0x1a;
9157 spec->autocfg.speaker_pins[0] = 0x15;
9159 spec->automute_mode = ALC_AUTOMUTE_AMP;
9162 static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9163 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9164 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9165 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9166 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9167 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9174 static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9175 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9176 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
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("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9180 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9182 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9183 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9187 static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9188 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9189 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9190 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9191 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9192 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9193 0x0d, 1, 0x0, HDA_OUTPUT),
9194 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9195 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9196 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9197 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9198 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9199 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9200 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9201 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9202 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9203 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9204 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9205 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9206 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9208 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9212 static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9214 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9215 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9216 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9217 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9218 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9220 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9221 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9222 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9223 /* Output switches */
9224 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9225 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9226 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9228 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9229 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9231 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9232 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9238 static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9239 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9240 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9241 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9242 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9243 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9244 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9248 static const struct hda_bind_ctls alc883_bind_cap_vol = {
9249 .ops = &snd_hda_bind_vol,
9251 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9252 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9257 static const struct hda_bind_ctls alc883_bind_cap_switch = {
9258 .ops = &snd_hda_bind_sw,
9260 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9261 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9266 static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9269 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9270 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9271 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9272 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9274 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9278 static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9279 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9280 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9282 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9283 /* .name = "Capture Source", */
9284 .name = "Input Source",
9286 .info = alc_mux_enum_info,
9287 .get = alc_mux_enum_get,
9288 .put = alc_mux_enum_put,
9293 static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9295 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9296 .name = "Channel Mode",
9297 .info = alc_ch_mode_info,
9298 .get = alc_ch_mode_get,
9299 .put = alc_ch_mode_put,
9304 /* toggle speaker-output according to the hp-jack state */
9305 static void alc883_mitac_setup(struct hda_codec *codec)
9307 struct alc_spec *spec = codec->spec;
9309 spec->autocfg.hp_pins[0] = 0x15;
9310 spec->autocfg.speaker_pins[0] = 0x14;
9311 spec->autocfg.speaker_pins[1] = 0x17;
9313 spec->automute_mode = ALC_AUTOMUTE_AMP;
9316 static const struct hda_verb alc883_mitac_verbs[] = {
9318 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9319 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9321 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9322 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9324 /* enable unsolicited event */
9325 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9326 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9331 static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9333 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9334 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9336 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9338 /* enable unsolicited event */
9340 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9341 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9347 static const struct hda_verb alc883_clevo_m720_verbs[] = {
9349 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9350 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9352 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9353 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9355 /* enable unsolicited event */
9356 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9357 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9362 static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9364 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9365 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9367 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9370 /* enable unsolicited event */
9371 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9376 static const struct hda_verb alc883_targa_verbs[] = {
9377 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9378 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9381 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9383 /* Connect Line-Out side jack (SPDIF) to Side */
9384 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9385 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9386 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9387 /* Connect Mic jack to CLFE */
9388 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9389 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9390 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9391 /* Connect Line-in jack to Surround */
9392 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9393 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9394 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9395 /* Connect HP out jack to Front */
9396 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9397 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9398 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9400 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9405 static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9406 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9407 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9408 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9412 static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9413 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9414 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9415 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9416 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9420 static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9423 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9424 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9425 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9429 static const struct hda_verb alc883_haier_w66_verbs[] = {
9430 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9431 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9433 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9435 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9436 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9437 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9438 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9442 static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9443 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9444 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9445 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9446 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9447 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9448 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9449 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9450 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9454 static const struct hda_verb alc888_6st_dell_verbs[] = {
9455 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9459 static const struct hda_verb alc883_vaiott_verbs[] = {
9461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9462 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9464 /* enable unsolicited event */
9465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9470 static void alc888_3st_hp_setup(struct hda_codec *codec)
9472 struct alc_spec *spec = codec->spec;
9474 spec->autocfg.hp_pins[0] = 0x1b;
9475 spec->autocfg.speaker_pins[0] = 0x14;
9476 spec->autocfg.speaker_pins[1] = 0x16;
9477 spec->autocfg.speaker_pins[2] = 0x18;
9479 spec->automute_mode = ALC_AUTOMUTE_AMP;
9482 static const struct hda_verb alc888_3st_hp_verbs[] = {
9483 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9484 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9485 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9486 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9493 static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9494 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9495 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9496 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9497 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9504 static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9505 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9506 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9507 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9508 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9509 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9516 static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9517 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9518 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9519 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9520 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9521 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9522 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9526 static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9527 { 2, alc888_3st_hp_2ch_init },
9528 { 4, alc888_3st_hp_4ch_init },
9529 { 6, alc888_3st_hp_6ch_init },
9532 static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9534 struct alc_spec *spec = codec->spec;
9536 spec->autocfg.hp_pins[0] = 0x1b;
9537 spec->autocfg.line_out_pins[0] = 0x14;
9538 spec->autocfg.speaker_pins[0] = 0x15;
9540 spec->automute_mode = ALC_AUTOMUTE_AMP;
9543 /* toggle speaker-output according to the hp-jack state */
9544 static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9546 struct alc_spec *spec = codec->spec;
9548 spec->autocfg.hp_pins[0] = 0x14;
9549 spec->autocfg.speaker_pins[0] = 0x15;
9551 spec->automute_mode = ALC_AUTOMUTE_AMP;
9554 /* toggle speaker-output according to the hp-jack state */
9555 #define alc883_targa_init_hook alc882_targa_init_hook
9556 #define alc883_targa_unsol_event alc882_targa_unsol_event
9558 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9560 struct alc_spec *spec = codec->spec;
9562 spec->autocfg.hp_pins[0] = 0x15;
9563 spec->autocfg.speaker_pins[0] = 0x14;
9565 spec->automute_mode = ALC_AUTOMUTE_AMP;
9568 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9570 alc_hp_automute(codec);
9571 alc88x_simple_mic_automute(codec);
9574 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9577 switch (res >> 26) {
9578 case ALC880_MIC_EVENT:
9579 alc88x_simple_mic_automute(codec);
9582 alc_sku_unsol_event(codec, res);
9587 /* toggle speaker-output according to the hp-jack state */
9588 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9590 struct alc_spec *spec = codec->spec;
9592 spec->autocfg.hp_pins[0] = 0x14;
9593 spec->autocfg.speaker_pins[0] = 0x15;
9595 spec->automute_mode = ALC_AUTOMUTE_AMP;
9598 static void alc883_haier_w66_setup(struct hda_codec *codec)
9600 struct alc_spec *spec = codec->spec;
9602 spec->autocfg.hp_pins[0] = 0x1b;
9603 spec->autocfg.speaker_pins[0] = 0x14;
9605 spec->automute_mode = ALC_AUTOMUTE_AMP;
9608 static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9610 struct alc_spec *spec = codec->spec;
9612 spec->autocfg.hp_pins[0] = 0x1b;
9613 spec->autocfg.line_out_pins[0] = 0x14;
9614 spec->autocfg.speaker_pins[0] = 0x15;
9616 spec->detect_line = 1;
9617 spec->automute_lines = 1;
9618 spec->automute_mode = ALC_AUTOMUTE_AMP;
9621 /* toggle speaker-output according to the hp-jack state */
9622 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9624 struct alc_spec *spec = codec->spec;
9626 spec->autocfg.hp_pins[0] = 0x14;
9627 spec->autocfg.speaker_pins[0] = 0x15;
9628 spec->autocfg.speaker_pins[1] = 0x16;
9630 spec->automute_mode = ALC_AUTOMUTE_AMP;
9633 static const struct hda_verb alc883_acer_eapd_verbs[] = {
9634 /* HP Pin: output 0 (0x0c) */
9635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9638 /* Front Pin: output 0 (0x0c) */
9639 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9640 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9641 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9642 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9643 /* eanable EAPD on medion laptop */
9644 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9645 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9646 /* enable unsolicited event */
9647 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9651 static void alc888_6st_dell_setup(struct hda_codec *codec)
9653 struct alc_spec *spec = codec->spec;
9655 spec->autocfg.hp_pins[0] = 0x1b;
9656 spec->autocfg.speaker_pins[0] = 0x14;
9657 spec->autocfg.speaker_pins[1] = 0x15;
9658 spec->autocfg.speaker_pins[2] = 0x16;
9659 spec->autocfg.speaker_pins[3] = 0x17;
9661 spec->automute_mode = ALC_AUTOMUTE_AMP;
9664 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9666 struct alc_spec *spec = codec->spec;
9668 spec->autocfg.hp_pins[0] = 0x1b;
9669 spec->autocfg.speaker_pins[0] = 0x14;
9670 spec->autocfg.speaker_pins[1] = 0x15;
9671 spec->autocfg.speaker_pins[2] = 0x16;
9672 spec->autocfg.speaker_pins[3] = 0x17;
9673 spec->autocfg.speaker_pins[4] = 0x1a;
9675 spec->automute_mode = ALC_AUTOMUTE_AMP;
9678 static void alc883_vaiott_setup(struct hda_codec *codec)
9680 struct alc_spec *spec = codec->spec;
9682 spec->autocfg.hp_pins[0] = 0x15;
9683 spec->autocfg.speaker_pins[0] = 0x14;
9684 spec->autocfg.speaker_pins[1] = 0x17;
9686 spec->automute_mode = ALC_AUTOMUTE_AMP;
9689 static const struct hda_verb alc888_asus_m90v_verbs[] = {
9690 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9691 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9692 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9693 /* enable unsolicited event */
9694 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9695 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9699 static void alc883_mode2_setup(struct hda_codec *codec)
9701 struct alc_spec *spec = codec->spec;
9703 spec->autocfg.hp_pins[0] = 0x1b;
9704 spec->autocfg.speaker_pins[0] = 0x14;
9705 spec->autocfg.speaker_pins[1] = 0x15;
9706 spec->autocfg.speaker_pins[2] = 0x16;
9707 spec->ext_mic.pin = 0x18;
9708 spec->int_mic.pin = 0x19;
9709 spec->ext_mic.mux_idx = 0;
9710 spec->int_mic.mux_idx = 1;
9713 spec->automute_mode = ALC_AUTOMUTE_AMP;
9716 static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9717 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9719 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9720 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9722 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9723 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9724 /* enable unsolicited event */
9725 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9729 static void alc883_eee1601_inithook(struct hda_codec *codec)
9731 struct alc_spec *spec = codec->spec;
9733 spec->autocfg.hp_pins[0] = 0x14;
9734 spec->autocfg.speaker_pins[0] = 0x1b;
9735 alc_hp_automute(codec);
9738 static const struct hda_verb alc889A_mb31_verbs[] = {
9739 /* Init rear pin (used as headphone output) */
9740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9741 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9742 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9743 /* Init line pin (used as output in 4ch and 6ch mode) */
9744 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9745 /* Init line 2 pin (used as headphone out by default) */
9746 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9747 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9751 /* Mute speakers according to the headphone jack state */
9752 static void alc889A_mb31_automute(struct hda_codec *codec)
9754 unsigned int present;
9756 /* Mute only in 2ch or 4ch mode */
9757 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9759 present = snd_hda_jack_detect(codec, 0x15);
9760 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9761 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9762 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9763 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9767 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9769 if ((res >> 26) == ALC880_HP_EVENT)
9770 alc889A_mb31_automute(codec);
9774 #ifdef CONFIG_SND_HDA_POWER_SAVE
9775 #define alc882_loopbacks alc880_loopbacks
9778 static const hda_nid_t alc883_slave_dig_outs[] = {
9779 ALC1200_DIGOUT_NID, 0,
9782 static const hda_nid_t alc1200_slave_dig_outs[] = {
9783 ALC883_DIGOUT_NID, 0,
9787 * configuration and preset
9789 static const char * const alc882_models[ALC882_MODEL_LAST] = {
9790 [ALC882_3ST_DIG] = "3stack-dig",
9791 [ALC882_6ST_DIG] = "6stack-dig",
9792 [ALC882_ARIMA] = "arima",
9793 [ALC882_W2JC] = "w2jc",
9794 [ALC882_TARGA] = "targa",
9795 [ALC882_ASUS_A7J] = "asus-a7j",
9796 [ALC882_ASUS_A7M] = "asus-a7m",
9797 [ALC885_MACPRO] = "macpro",
9798 [ALC885_MB5] = "mb5",
9799 [ALC885_MACMINI3] = "macmini3",
9800 [ALC885_MBA21] = "mba21",
9801 [ALC885_MBP3] = "mbp3",
9802 [ALC885_IMAC24] = "imac24",
9803 [ALC885_IMAC91] = "imac91",
9804 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9805 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9806 [ALC883_3ST_6ch] = "3stack-6ch",
9807 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9808 [ALC883_TARGA_DIG] = "targa-dig",
9809 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9810 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9811 [ALC883_ACER] = "acer",
9812 [ALC883_ACER_ASPIRE] = "acer-aspire",
9813 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9814 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9815 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9816 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9817 [ALC883_MEDION] = "medion",
9818 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9819 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9820 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9821 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9822 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9823 [ALC888_LENOVO_SKY] = "lenovo-sky",
9824 [ALC883_HAIER_W66] = "haier-w66",
9825 [ALC888_3ST_HP] = "3stack-hp",
9826 [ALC888_6ST_DELL] = "6stack-dell",
9827 [ALC883_MITAC] = "mitac",
9828 [ALC883_CLEVO_M540R] = "clevo-m540r",
9829 [ALC883_CLEVO_M720] = "clevo-m720",
9830 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9831 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9832 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9833 [ALC889A_INTEL] = "intel-alc889a",
9834 [ALC889_INTEL] = "intel-x58",
9835 [ALC1200_ASUS_P5Q] = "asus-p5q",
9836 [ALC889A_MB31] = "mb31",
9837 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9838 [ALC882_AUTO] = "auto",
9841 static const struct snd_pci_quirk alc882_cfg_tbl[] = {
9842 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9844 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9845 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9846 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9847 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9848 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9849 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9850 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9851 ALC888_ACER_ASPIRE_4930G),
9852 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9853 ALC888_ACER_ASPIRE_4930G),
9854 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9855 ALC888_ACER_ASPIRE_8930G),
9856 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9857 ALC888_ACER_ASPIRE_8930G),
9858 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9859 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9860 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9861 ALC888_ACER_ASPIRE_6530G),
9862 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9863 ALC888_ACER_ASPIRE_6530G),
9864 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9865 ALC888_ACER_ASPIRE_7730G),
9866 /* default Acer -- disabled as it causes more problems.
9867 * model=auto should work fine now
9869 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9871 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9873 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
9874 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9875 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9876 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9877 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9878 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9880 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9881 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9882 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9883 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9884 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9885 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9886 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9887 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9888 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9889 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9890 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9892 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9893 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9894 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9895 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9896 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9897 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9898 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9899 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9900 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9902 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9903 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9904 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9905 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9906 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9907 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9908 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9909 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9910 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9911 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9912 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9913 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9914 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9915 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9916 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9917 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9918 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9919 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9920 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9921 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9922 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9923 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9924 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9925 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9926 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9927 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9928 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9929 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9930 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9931 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9932 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9934 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9935 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9936 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9937 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9938 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9939 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9940 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9941 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9942 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9943 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9944 ALC883_FUJITSU_PI2515),
9945 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9946 ALC888_FUJITSU_XA3530),
9947 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9948 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9949 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9950 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9951 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9952 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9953 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9954 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9956 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9957 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9958 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9959 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9960 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9961 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9962 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9967 /* codec SSID table for Intel Mac */
9968 static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9969 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9970 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9971 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9972 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9973 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9974 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9975 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9976 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9977 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9978 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9979 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9980 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9981 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9982 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9983 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9984 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9985 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
9986 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9987 * so apparently no perfect solution yet
9989 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9990 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9991 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9995 static const struct alc_config_preset alc882_presets[] = {
9996 [ALC882_3ST_DIG] = {
9997 .mixers = { alc882_base_mixer },
9998 .init_verbs = { alc882_base_init_verbs,
9999 alc882_adc1_init_verbs },
10000 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10001 .dac_nids = alc882_dac_nids,
10002 .dig_out_nid = ALC882_DIGOUT_NID,
10003 .dig_in_nid = ALC882_DIGIN_NID,
10004 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10005 .channel_mode = alc882_ch_modes,
10007 .input_mux = &alc882_capture_source,
10009 [ALC882_6ST_DIG] = {
10010 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10011 .init_verbs = { alc882_base_init_verbs,
10012 alc882_adc1_init_verbs },
10013 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10014 .dac_nids = alc882_dac_nids,
10015 .dig_out_nid = ALC882_DIGOUT_NID,
10016 .dig_in_nid = ALC882_DIGIN_NID,
10017 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10018 .channel_mode = alc882_sixstack_modes,
10019 .input_mux = &alc882_capture_source,
10022 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10023 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10024 alc882_eapd_verbs },
10025 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10026 .dac_nids = alc882_dac_nids,
10027 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10028 .channel_mode = alc882_sixstack_modes,
10029 .input_mux = &alc882_capture_source,
10032 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10033 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10034 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10035 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10036 .dac_nids = alc882_dac_nids,
10037 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10038 .channel_mode = alc880_threestack_modes,
10040 .input_mux = &alc882_capture_source,
10041 .dig_out_nid = ALC882_DIGOUT_NID,
10044 .mixers = { alc885_mba21_mixer },
10045 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10047 .dac_nids = alc882_dac_nids,
10048 .channel_mode = alc885_mba21_ch_modes,
10049 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10050 .input_mux = &alc882_capture_source,
10051 .unsol_event = alc_sku_unsol_event,
10052 .setup = alc885_mba21_setup,
10053 .init_hook = alc_hp_automute,
10056 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10057 .init_verbs = { alc885_mbp3_init_verbs,
10058 alc880_gpio1_init_verbs },
10060 .dac_nids = alc882_dac_nids,
10062 .channel_mode = alc885_mbp_4ch_modes,
10063 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10064 .input_mux = &alc882_capture_source,
10065 .dig_out_nid = ALC882_DIGOUT_NID,
10066 .dig_in_nid = ALC882_DIGIN_NID,
10067 .unsol_event = alc_sku_unsol_event,
10068 .setup = alc885_mbp3_setup,
10069 .init_hook = alc_hp_automute,
10072 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10073 .init_verbs = { alc885_mb5_init_verbs,
10074 alc880_gpio1_init_verbs },
10075 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10076 .dac_nids = alc882_dac_nids,
10077 .channel_mode = alc885_mb5_6ch_modes,
10078 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10079 .input_mux = &mb5_capture_source,
10080 .dig_out_nid = ALC882_DIGOUT_NID,
10081 .dig_in_nid = ALC882_DIGIN_NID,
10082 .unsol_event = alc_sku_unsol_event,
10083 .setup = alc885_mb5_setup,
10084 .init_hook = alc_hp_automute,
10086 [ALC885_MACMINI3] = {
10087 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10088 .init_verbs = { alc885_macmini3_init_verbs,
10089 alc880_gpio1_init_verbs },
10090 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10091 .dac_nids = alc882_dac_nids,
10092 .channel_mode = alc885_macmini3_6ch_modes,
10093 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10094 .input_mux = &macmini3_capture_source,
10095 .dig_out_nid = ALC882_DIGOUT_NID,
10096 .dig_in_nid = ALC882_DIGIN_NID,
10097 .unsol_event = alc_sku_unsol_event,
10098 .setup = alc885_macmini3_setup,
10099 .init_hook = alc_hp_automute,
10101 [ALC885_MACPRO] = {
10102 .mixers = { alc882_macpro_mixer },
10103 .init_verbs = { alc882_macpro_init_verbs },
10104 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10105 .dac_nids = alc882_dac_nids,
10106 .dig_out_nid = ALC882_DIGOUT_NID,
10107 .dig_in_nid = ALC882_DIGIN_NID,
10108 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10109 .channel_mode = alc882_ch_modes,
10110 .input_mux = &alc882_capture_source,
10111 .init_hook = alc885_macpro_init_hook,
10113 [ALC885_IMAC24] = {
10114 .mixers = { alc885_imac24_mixer },
10115 .init_verbs = { alc885_imac24_init_verbs },
10116 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10117 .dac_nids = alc882_dac_nids,
10118 .dig_out_nid = ALC882_DIGOUT_NID,
10119 .dig_in_nid = ALC882_DIGIN_NID,
10120 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10121 .channel_mode = alc882_ch_modes,
10122 .input_mux = &alc882_capture_source,
10123 .unsol_event = alc_sku_unsol_event,
10124 .setup = alc885_imac24_setup,
10125 .init_hook = alc885_imac24_init_hook,
10127 [ALC885_IMAC91] = {
10128 .mixers = {alc885_imac91_mixer},
10129 .init_verbs = { alc885_imac91_init_verbs,
10130 alc880_gpio1_init_verbs },
10131 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10132 .dac_nids = alc882_dac_nids,
10133 .channel_mode = alc885_mba21_ch_modes,
10134 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10135 .input_mux = &alc889A_imac91_capture_source,
10136 .dig_out_nid = ALC882_DIGOUT_NID,
10137 .dig_in_nid = ALC882_DIGIN_NID,
10138 .unsol_event = alc_sku_unsol_event,
10139 .setup = alc885_imac91_setup,
10140 .init_hook = alc_hp_automute,
10143 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10144 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10145 alc880_gpio3_init_verbs, alc882_targa_verbs},
10146 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10147 .dac_nids = alc882_dac_nids,
10148 .dig_out_nid = ALC882_DIGOUT_NID,
10149 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10150 .adc_nids = alc882_adc_nids,
10151 .capsrc_nids = alc882_capsrc_nids,
10152 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10153 .channel_mode = alc882_3ST_6ch_modes,
10155 .input_mux = &alc882_capture_source,
10156 .unsol_event = alc_sku_unsol_event,
10157 .setup = alc882_targa_setup,
10158 .init_hook = alc882_targa_automute,
10160 [ALC882_ASUS_A7J] = {
10161 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10162 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10163 alc882_asus_a7j_verbs},
10164 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10165 .dac_nids = alc882_dac_nids,
10166 .dig_out_nid = ALC882_DIGOUT_NID,
10167 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10168 .adc_nids = alc882_adc_nids,
10169 .capsrc_nids = alc882_capsrc_nids,
10170 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10171 .channel_mode = alc882_3ST_6ch_modes,
10173 .input_mux = &alc882_capture_source,
10175 [ALC882_ASUS_A7M] = {
10176 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10177 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10178 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10179 alc882_asus_a7m_verbs },
10180 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10181 .dac_nids = alc882_dac_nids,
10182 .dig_out_nid = ALC882_DIGOUT_NID,
10183 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10184 .channel_mode = alc880_threestack_modes,
10186 .input_mux = &alc882_capture_source,
10188 [ALC883_3ST_2ch_DIG] = {
10189 .mixers = { alc883_3ST_2ch_mixer },
10190 .init_verbs = { alc883_init_verbs },
10191 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10192 .dac_nids = alc883_dac_nids,
10193 .dig_out_nid = ALC883_DIGOUT_NID,
10194 .dig_in_nid = ALC883_DIGIN_NID,
10195 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10196 .channel_mode = alc883_3ST_2ch_modes,
10197 .input_mux = &alc883_capture_source,
10199 [ALC883_3ST_6ch_DIG] = {
10200 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10201 .init_verbs = { alc883_init_verbs },
10202 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10203 .dac_nids = alc883_dac_nids,
10204 .dig_out_nid = ALC883_DIGOUT_NID,
10205 .dig_in_nid = ALC883_DIGIN_NID,
10206 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10207 .channel_mode = alc883_3ST_6ch_modes,
10209 .input_mux = &alc883_capture_source,
10211 [ALC883_3ST_6ch] = {
10212 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10213 .init_verbs = { alc883_init_verbs },
10214 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10215 .dac_nids = alc883_dac_nids,
10216 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10217 .channel_mode = alc883_3ST_6ch_modes,
10219 .input_mux = &alc883_capture_source,
10221 [ALC883_3ST_6ch_INTEL] = {
10222 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10223 .init_verbs = { alc883_init_verbs },
10224 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10225 .dac_nids = alc883_dac_nids,
10226 .dig_out_nid = ALC883_DIGOUT_NID,
10227 .dig_in_nid = ALC883_DIGIN_NID,
10228 .slave_dig_outs = alc883_slave_dig_outs,
10229 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10230 .channel_mode = alc883_3ST_6ch_intel_modes,
10232 .input_mux = &alc883_3stack_6ch_intel,
10234 [ALC889A_INTEL] = {
10235 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10236 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10237 alc_hp15_unsol_verbs },
10238 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10239 .dac_nids = alc883_dac_nids,
10240 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10241 .adc_nids = alc889_adc_nids,
10242 .dig_out_nid = ALC883_DIGOUT_NID,
10243 .dig_in_nid = ALC883_DIGIN_NID,
10244 .slave_dig_outs = alc883_slave_dig_outs,
10245 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10246 .channel_mode = alc889_8ch_intel_modes,
10247 .capsrc_nids = alc889_capsrc_nids,
10248 .input_mux = &alc889_capture_source,
10249 .setup = alc889_automute_setup,
10250 .init_hook = alc_hp_automute,
10251 .unsol_event = alc_sku_unsol_event,
10255 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10256 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10257 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10258 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10259 .dac_nids = alc883_dac_nids,
10260 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10261 .adc_nids = alc889_adc_nids,
10262 .dig_out_nid = ALC883_DIGOUT_NID,
10263 .dig_in_nid = ALC883_DIGIN_NID,
10264 .slave_dig_outs = alc883_slave_dig_outs,
10265 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10266 .channel_mode = alc889_8ch_intel_modes,
10267 .capsrc_nids = alc889_capsrc_nids,
10268 .input_mux = &alc889_capture_source,
10269 .setup = alc889_automute_setup,
10270 .init_hook = alc889_intel_init_hook,
10271 .unsol_event = alc_sku_unsol_event,
10274 [ALC883_6ST_DIG] = {
10275 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10276 .init_verbs = { alc883_init_verbs },
10277 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10278 .dac_nids = alc883_dac_nids,
10279 .dig_out_nid = ALC883_DIGOUT_NID,
10280 .dig_in_nid = ALC883_DIGIN_NID,
10281 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10282 .channel_mode = alc883_sixstack_modes,
10283 .input_mux = &alc883_capture_source,
10285 [ALC883_TARGA_DIG] = {
10286 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10287 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10288 alc883_targa_verbs},
10289 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10290 .dac_nids = alc883_dac_nids,
10291 .dig_out_nid = ALC883_DIGOUT_NID,
10292 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10293 .channel_mode = alc883_3ST_6ch_modes,
10295 .input_mux = &alc883_capture_source,
10296 .unsol_event = alc883_targa_unsol_event,
10297 .setup = alc882_targa_setup,
10298 .init_hook = alc882_targa_automute,
10300 [ALC883_TARGA_2ch_DIG] = {
10301 .mixers = { alc883_targa_2ch_mixer},
10302 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10303 alc883_targa_verbs},
10304 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10305 .dac_nids = alc883_dac_nids,
10306 .adc_nids = alc883_adc_nids_alt,
10307 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10308 .capsrc_nids = alc883_capsrc_nids,
10309 .dig_out_nid = ALC883_DIGOUT_NID,
10310 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10311 .channel_mode = alc883_3ST_2ch_modes,
10312 .input_mux = &alc883_capture_source,
10313 .unsol_event = alc883_targa_unsol_event,
10314 .setup = alc882_targa_setup,
10315 .init_hook = alc882_targa_automute,
10317 [ALC883_TARGA_8ch_DIG] = {
10318 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10319 alc883_chmode_mixer },
10320 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10321 alc883_targa_verbs },
10322 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10323 .dac_nids = alc883_dac_nids,
10324 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10325 .adc_nids = alc883_adc_nids_rev,
10326 .capsrc_nids = alc883_capsrc_nids_rev,
10327 .dig_out_nid = ALC883_DIGOUT_NID,
10328 .dig_in_nid = ALC883_DIGIN_NID,
10329 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10330 .channel_mode = alc883_4ST_8ch_modes,
10332 .input_mux = &alc883_capture_source,
10333 .unsol_event = alc883_targa_unsol_event,
10334 .setup = alc882_targa_setup,
10335 .init_hook = alc882_targa_automute,
10338 .mixers = { alc883_base_mixer },
10339 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10340 * and the headphone jack. Turn this on and rely on the
10341 * standard mute methods whenever the user wants to turn
10342 * these outputs off.
10344 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10345 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10346 .dac_nids = alc883_dac_nids,
10347 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10348 .channel_mode = alc883_3ST_2ch_modes,
10349 .input_mux = &alc883_capture_source,
10351 [ALC883_ACER_ASPIRE] = {
10352 .mixers = { alc883_acer_aspire_mixer },
10353 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10354 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10355 .dac_nids = alc883_dac_nids,
10356 .dig_out_nid = ALC883_DIGOUT_NID,
10357 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10358 .channel_mode = alc883_3ST_2ch_modes,
10359 .input_mux = &alc883_capture_source,
10360 .unsol_event = alc_sku_unsol_event,
10361 .setup = alc883_acer_aspire_setup,
10362 .init_hook = alc_hp_automute,
10364 [ALC888_ACER_ASPIRE_4930G] = {
10365 .mixers = { alc888_acer_aspire_4930g_mixer,
10366 alc883_chmode_mixer },
10367 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10368 alc888_acer_aspire_4930g_verbs },
10369 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10370 .dac_nids = alc883_dac_nids,
10371 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10372 .adc_nids = alc883_adc_nids_rev,
10373 .capsrc_nids = alc883_capsrc_nids_rev,
10374 .dig_out_nid = ALC883_DIGOUT_NID,
10375 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10376 .channel_mode = alc883_3ST_6ch_modes,
10378 .const_channel_count = 6,
10380 ARRAY_SIZE(alc888_2_capture_sources),
10381 .input_mux = alc888_2_capture_sources,
10382 .unsol_event = alc_sku_unsol_event,
10383 .setup = alc888_acer_aspire_4930g_setup,
10384 .init_hook = alc_hp_automute,
10386 [ALC888_ACER_ASPIRE_6530G] = {
10387 .mixers = { alc888_acer_aspire_6530_mixer },
10388 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10389 alc888_acer_aspire_6530g_verbs },
10390 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10391 .dac_nids = alc883_dac_nids,
10392 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10393 .adc_nids = alc883_adc_nids_rev,
10394 .capsrc_nids = alc883_capsrc_nids_rev,
10395 .dig_out_nid = ALC883_DIGOUT_NID,
10396 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10397 .channel_mode = alc883_3ST_2ch_modes,
10399 ARRAY_SIZE(alc888_2_capture_sources),
10400 .input_mux = alc888_acer_aspire_6530_sources,
10401 .unsol_event = alc_sku_unsol_event,
10402 .setup = alc888_acer_aspire_6530g_setup,
10403 .init_hook = alc_hp_automute,
10405 [ALC888_ACER_ASPIRE_8930G] = {
10406 .mixers = { alc889_acer_aspire_8930g_mixer,
10407 alc883_chmode_mixer },
10408 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10409 alc889_acer_aspire_8930g_verbs,
10410 alc889_eapd_verbs},
10411 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10412 .dac_nids = alc883_dac_nids,
10413 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10414 .adc_nids = alc889_adc_nids,
10415 .capsrc_nids = alc889_capsrc_nids,
10416 .dig_out_nid = ALC883_DIGOUT_NID,
10417 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10418 .channel_mode = alc883_3ST_6ch_modes,
10420 .const_channel_count = 6,
10422 ARRAY_SIZE(alc889_capture_sources),
10423 .input_mux = alc889_capture_sources,
10424 .unsol_event = alc_sku_unsol_event,
10425 .setup = alc889_acer_aspire_8930g_setup,
10426 .init_hook = alc_hp_automute,
10427 #ifdef CONFIG_SND_HDA_POWER_SAVE
10428 .power_hook = alc_power_eapd,
10431 [ALC888_ACER_ASPIRE_7730G] = {
10432 .mixers = { alc883_3ST_6ch_mixer,
10433 alc883_chmode_mixer },
10434 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10435 alc888_acer_aspire_7730G_verbs },
10436 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10437 .dac_nids = alc883_dac_nids,
10438 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10439 .adc_nids = alc883_adc_nids_rev,
10440 .capsrc_nids = alc883_capsrc_nids_rev,
10441 .dig_out_nid = ALC883_DIGOUT_NID,
10442 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10443 .channel_mode = alc883_3ST_6ch_modes,
10445 .const_channel_count = 6,
10446 .input_mux = &alc883_capture_source,
10447 .unsol_event = alc_sku_unsol_event,
10448 .setup = alc888_acer_aspire_7730g_setup,
10449 .init_hook = alc_hp_automute,
10451 [ALC883_MEDION] = {
10452 .mixers = { alc883_fivestack_mixer,
10453 alc883_chmode_mixer },
10454 .init_verbs = { alc883_init_verbs,
10455 alc883_medion_eapd_verbs },
10456 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10457 .dac_nids = alc883_dac_nids,
10458 .adc_nids = alc883_adc_nids_alt,
10459 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10460 .capsrc_nids = alc883_capsrc_nids,
10461 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10462 .channel_mode = alc883_sixstack_modes,
10463 .input_mux = &alc883_capture_source,
10465 [ALC883_MEDION_WIM2160] = {
10466 .mixers = { alc883_medion_wim2160_mixer },
10467 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10468 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10469 .dac_nids = alc883_dac_nids,
10470 .dig_out_nid = ALC883_DIGOUT_NID,
10471 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10472 .adc_nids = alc883_adc_nids,
10473 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10474 .channel_mode = alc883_3ST_2ch_modes,
10475 .input_mux = &alc883_capture_source,
10476 .unsol_event = alc_sku_unsol_event,
10477 .setup = alc883_medion_wim2160_setup,
10478 .init_hook = alc_hp_automute,
10480 [ALC883_LAPTOP_EAPD] = {
10481 .mixers = { alc883_base_mixer },
10482 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10483 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10484 .dac_nids = alc883_dac_nids,
10485 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10486 .channel_mode = alc883_3ST_2ch_modes,
10487 .input_mux = &alc883_capture_source,
10489 [ALC883_CLEVO_M540R] = {
10490 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10491 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10492 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10493 .dac_nids = alc883_dac_nids,
10494 .dig_out_nid = ALC883_DIGOUT_NID,
10495 .dig_in_nid = ALC883_DIGIN_NID,
10496 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10497 .channel_mode = alc883_3ST_6ch_clevo_modes,
10499 .input_mux = &alc883_capture_source,
10500 /* This machine has the hardware HP auto-muting, thus
10501 * we need no software mute via unsol event
10504 [ALC883_CLEVO_M720] = {
10505 .mixers = { alc883_clevo_m720_mixer },
10506 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10507 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10508 .dac_nids = alc883_dac_nids,
10509 .dig_out_nid = ALC883_DIGOUT_NID,
10510 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10511 .channel_mode = alc883_3ST_2ch_modes,
10512 .input_mux = &alc883_capture_source,
10513 .unsol_event = alc883_clevo_m720_unsol_event,
10514 .setup = alc883_clevo_m720_setup,
10515 .init_hook = alc883_clevo_m720_init_hook,
10517 [ALC883_LENOVO_101E_2ch] = {
10518 .mixers = { alc883_lenovo_101e_2ch_mixer},
10519 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10520 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10521 .dac_nids = alc883_dac_nids,
10522 .adc_nids = alc883_adc_nids_alt,
10523 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10524 .capsrc_nids = alc883_capsrc_nids,
10525 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10526 .channel_mode = alc883_3ST_2ch_modes,
10527 .input_mux = &alc883_lenovo_101e_capture_source,
10528 .setup = alc883_lenovo_101e_setup,
10529 .unsol_event = alc_sku_unsol_event,
10530 .init_hook = alc_inithook,
10532 [ALC883_LENOVO_NB0763] = {
10533 .mixers = { alc883_lenovo_nb0763_mixer },
10534 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10535 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10536 .dac_nids = alc883_dac_nids,
10537 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10538 .channel_mode = alc883_3ST_2ch_modes,
10540 .input_mux = &alc883_lenovo_nb0763_capture_source,
10541 .unsol_event = alc_sku_unsol_event,
10542 .setup = alc883_lenovo_nb0763_setup,
10543 .init_hook = alc_hp_automute,
10545 [ALC888_LENOVO_MS7195_DIG] = {
10546 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10547 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10548 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10549 .dac_nids = alc883_dac_nids,
10550 .dig_out_nid = ALC883_DIGOUT_NID,
10551 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10552 .channel_mode = alc883_3ST_6ch_modes,
10554 .input_mux = &alc883_capture_source,
10555 .unsol_event = alc_sku_unsol_event,
10556 .setup = alc888_lenovo_ms7195_setup,
10557 .init_hook = alc_inithook,
10559 [ALC883_HAIER_W66] = {
10560 .mixers = { alc883_targa_2ch_mixer},
10561 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10562 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10563 .dac_nids = alc883_dac_nids,
10564 .dig_out_nid = ALC883_DIGOUT_NID,
10565 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10566 .channel_mode = alc883_3ST_2ch_modes,
10567 .input_mux = &alc883_capture_source,
10568 .unsol_event = alc_sku_unsol_event,
10569 .setup = alc883_haier_w66_setup,
10570 .init_hook = alc_hp_automute,
10572 [ALC888_3ST_HP] = {
10573 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10574 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10575 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10576 .dac_nids = alc883_dac_nids,
10577 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10578 .channel_mode = alc888_3st_hp_modes,
10580 .input_mux = &alc883_capture_source,
10581 .unsol_event = alc_sku_unsol_event,
10582 .setup = alc888_3st_hp_setup,
10583 .init_hook = alc_hp_automute,
10585 [ALC888_6ST_DELL] = {
10586 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10587 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10588 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10589 .dac_nids = alc883_dac_nids,
10590 .dig_out_nid = ALC883_DIGOUT_NID,
10591 .dig_in_nid = ALC883_DIGIN_NID,
10592 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10593 .channel_mode = alc883_sixstack_modes,
10594 .input_mux = &alc883_capture_source,
10595 .unsol_event = alc_sku_unsol_event,
10596 .setup = alc888_6st_dell_setup,
10597 .init_hook = alc_hp_automute,
10600 .mixers = { alc883_mitac_mixer },
10601 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10602 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10603 .dac_nids = alc883_dac_nids,
10604 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10605 .channel_mode = alc883_3ST_2ch_modes,
10606 .input_mux = &alc883_capture_source,
10607 .unsol_event = alc_sku_unsol_event,
10608 .setup = alc883_mitac_setup,
10609 .init_hook = alc_hp_automute,
10611 [ALC883_FUJITSU_PI2515] = {
10612 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10613 .init_verbs = { alc883_init_verbs,
10614 alc883_2ch_fujitsu_pi2515_verbs},
10615 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10616 .dac_nids = alc883_dac_nids,
10617 .dig_out_nid = ALC883_DIGOUT_NID,
10618 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10619 .channel_mode = alc883_3ST_2ch_modes,
10620 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10621 .unsol_event = alc_sku_unsol_event,
10622 .setup = alc883_2ch_fujitsu_pi2515_setup,
10623 .init_hook = alc_hp_automute,
10625 [ALC888_FUJITSU_XA3530] = {
10626 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10627 .init_verbs = { alc883_init_verbs,
10628 alc888_fujitsu_xa3530_verbs },
10629 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10630 .dac_nids = alc883_dac_nids,
10631 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10632 .adc_nids = alc883_adc_nids_rev,
10633 .capsrc_nids = alc883_capsrc_nids_rev,
10634 .dig_out_nid = ALC883_DIGOUT_NID,
10635 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10636 .channel_mode = alc888_4ST_8ch_intel_modes,
10638 ARRAY_SIZE(alc888_2_capture_sources),
10639 .input_mux = alc888_2_capture_sources,
10640 .unsol_event = alc_sku_unsol_event,
10641 .setup = alc888_fujitsu_xa3530_setup,
10642 .init_hook = alc_hp_automute,
10644 [ALC888_LENOVO_SKY] = {
10645 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10646 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10647 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10648 .dac_nids = alc883_dac_nids,
10649 .dig_out_nid = ALC883_DIGOUT_NID,
10650 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10651 .channel_mode = alc883_sixstack_modes,
10653 .input_mux = &alc883_lenovo_sky_capture_source,
10654 .unsol_event = alc_sku_unsol_event,
10655 .setup = alc888_lenovo_sky_setup,
10656 .init_hook = alc_hp_automute,
10658 [ALC888_ASUS_M90V] = {
10659 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10660 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10661 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10662 .dac_nids = alc883_dac_nids,
10663 .dig_out_nid = ALC883_DIGOUT_NID,
10664 .dig_in_nid = ALC883_DIGIN_NID,
10665 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10666 .channel_mode = alc883_3ST_6ch_modes,
10668 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10669 .unsol_event = alc_sku_unsol_event,
10670 .setup = alc883_mode2_setup,
10671 .init_hook = alc_inithook,
10673 [ALC888_ASUS_EEE1601] = {
10674 .mixers = { alc883_asus_eee1601_mixer },
10675 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10676 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10677 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10678 .dac_nids = alc883_dac_nids,
10679 .dig_out_nid = ALC883_DIGOUT_NID,
10680 .dig_in_nid = ALC883_DIGIN_NID,
10681 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10682 .channel_mode = alc883_3ST_2ch_modes,
10684 .input_mux = &alc883_asus_eee1601_capture_source,
10685 .unsol_event = alc_sku_unsol_event,
10686 .init_hook = alc883_eee1601_inithook,
10688 [ALC1200_ASUS_P5Q] = {
10689 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10690 .init_verbs = { alc883_init_verbs },
10691 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10692 .dac_nids = alc883_dac_nids,
10693 .dig_out_nid = ALC1200_DIGOUT_NID,
10694 .dig_in_nid = ALC883_DIGIN_NID,
10695 .slave_dig_outs = alc1200_slave_dig_outs,
10696 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10697 .channel_mode = alc883_sixstack_modes,
10698 .input_mux = &alc883_capture_source,
10701 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10702 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10703 alc880_gpio1_init_verbs },
10704 .adc_nids = alc883_adc_nids,
10705 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10706 .capsrc_nids = alc883_capsrc_nids,
10707 .dac_nids = alc883_dac_nids,
10708 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10709 .channel_mode = alc889A_mb31_6ch_modes,
10710 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10711 .input_mux = &alc889A_mb31_capture_source,
10712 .dig_out_nid = ALC883_DIGOUT_NID,
10713 .unsol_event = alc889A_mb31_unsol_event,
10714 .init_hook = alc889A_mb31_automute,
10716 [ALC883_SONY_VAIO_TT] = {
10717 .mixers = { alc883_vaiott_mixer },
10718 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10719 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10720 .dac_nids = alc883_dac_nids,
10721 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10722 .channel_mode = alc883_3ST_2ch_modes,
10723 .input_mux = &alc883_capture_source,
10724 .unsol_event = alc_sku_unsol_event,
10725 .setup = alc883_vaiott_setup,
10726 .init_hook = alc_hp_automute,
10735 PINFIX_ABIT_AW9D_MAX,
10736 PINFIX_LENOVO_Y530,
10738 PINFIX_ACER_ASPIRE_7736,
10741 static const struct alc_fixup alc882_fixups[] = {
10742 [PINFIX_ABIT_AW9D_MAX] = {
10743 .type = ALC_FIXUP_PINS,
10744 .v.pins = (const struct alc_pincfg[]) {
10745 { 0x15, 0x01080104 }, /* side */
10746 { 0x16, 0x01011012 }, /* rear */
10747 { 0x17, 0x01016011 }, /* clfe */
10751 [PINFIX_LENOVO_Y530] = {
10752 .type = ALC_FIXUP_PINS,
10753 .v.pins = (const struct alc_pincfg[]) {
10754 { 0x15, 0x99130112 }, /* rear int speakers */
10755 { 0x16, 0x99130111 }, /* subwoofer */
10759 [PINFIX_PB_M5210] = {
10760 .type = ALC_FIXUP_VERBS,
10761 .v.verbs = (const struct hda_verb[]) {
10762 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10766 [PINFIX_ACER_ASPIRE_7736] = {
10767 .type = ALC_FIXUP_SKU,
10768 .v.sku = ALC_FIXUP_SKU_IGNORE,
10772 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
10773 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10774 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
10775 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10776 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10781 * BIOS auto configuration
10783 static void alc_auto_init_input_src(struct hda_codec *codec)
10785 struct alc_spec *spec = codec->spec;
10788 if (spec->dual_adc_switch)
10791 for (c = 0; c < spec->num_adc_nids; c++) {
10793 unsigned int mux_idx;
10794 const struct hda_input_mux *imux;
10795 int conns, mute, idx, item;
10796 unsigned int wid_type;
10798 nid = spec->capsrc_nids ?
10799 spec->capsrc_nids[c] : spec->adc_nids[c];
10801 if (query_amp_caps(codec, spec->adc_nids[c], HDA_INPUT) &
10803 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
10804 AC_VERB_SET_AMP_GAIN_MUTE,
10806 else if (query_amp_caps(codec, nid, HDA_OUTPUT) &
10808 snd_hda_codec_write(codec, nid, 0,
10809 AC_VERB_SET_AMP_GAIN_MUTE,
10812 conns = snd_hda_get_conn_list(codec, nid, NULL);
10815 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10816 imux = &spec->input_mux[mux_idx];
10817 if (!imux->num_items && mux_idx > 0)
10818 imux = &spec->input_mux[0];
10819 wid_type = get_wcaps_type(get_wcaps(codec, nid));
10820 for (idx = 0; idx < conns; idx++) {
10821 /* if the current connection is the selected one,
10822 * unmute it as default - otherwise mute it
10824 mute = AMP_IN_MUTE(idx);
10825 for (item = 0; item < imux->num_items; item++) {
10826 if (imux->items[item].index == idx) {
10827 if (spec->cur_mux[c] == item)
10828 mute = AMP_IN_UNMUTE(idx);
10832 /* initialize the mute status if mute-amp is present */
10833 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
10834 snd_hda_codec_write(codec, nid, 0,
10835 AC_VERB_SET_AMP_GAIN_MUTE,
10837 if (wid_type == AC_WID_AUD_SEL &&
10838 mute != AMP_IN_MUTE(idx))
10839 snd_hda_codec_write(codec, nid, 0,
10840 AC_VERB_SET_CONNECT_SEL,
10846 /* add mic boosts if needed */
10847 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10849 struct alc_spec *spec = codec->spec;
10850 struct auto_pin_cfg *cfg = &spec->autocfg;
10854 const char *prev_label = NULL;
10856 for (i = 0; i < cfg->num_inputs; i++) {
10857 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10859 nid = cfg->inputs[i].pin;
10860 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10862 char boost_label[32];
10864 label = hda_get_autocfg_input_label(codec, cfg, i);
10865 if (prev_label && !strcmp(label, prev_label))
10869 prev_label = label;
10871 snprintf(boost_label, sizeof(boost_label),
10872 "%s Boost Volume", label);
10873 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10874 boost_label, type_idx,
10875 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10883 /* almost identical with ALC880 parser... */
10884 static int alc882_parse_auto_config(struct hda_codec *codec)
10886 struct alc_spec *spec = codec->spec;
10887 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10890 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10894 if (!spec->autocfg.line_outs)
10895 return 0; /* can't find valid BIOS pin config */
10897 err = alc_auto_fill_dac_nids(codec);
10900 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
10903 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
10906 err = alc_auto_create_hp_out(codec);
10909 err = alc_auto_create_speaker_out(codec);
10912 err = alc_auto_create_input_ctls(codec);
10916 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10918 alc_auto_parse_digital(codec);
10920 if (spec->kctls.list)
10921 add_mixer(spec, spec->kctls.list);
10923 spec->num_mux_defs = 1;
10924 spec->input_mux = &spec->private_imux[0];
10926 if (!spec->dual_adc_switch)
10927 alc_remove_invalid_adc_nids(codec);
10929 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10931 err = alc_auto_add_mic_boost(codec);
10935 return 1; /* config found */
10938 /* additional initialization for auto-configuration model */
10939 static void alc882_auto_init(struct hda_codec *codec)
10941 struct alc_spec *spec = codec->spec;
10942 alc_auto_init_multi_out(codec);
10943 alc_auto_init_extra_out(codec);
10944 alc_auto_init_analog_input(codec);
10945 alc_auto_init_input_src(codec);
10946 alc_auto_init_digital(codec);
10947 if (spec->unsol_event)
10948 alc_inithook(codec);
10951 static int patch_alc882(struct hda_codec *codec)
10953 struct alc_spec *spec;
10954 int err, board_config;
10956 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10960 codec->spec = spec;
10962 spec->mixer_nid = 0x0b;
10964 switch (codec->vendor_id) {
10969 /* ALC883 and variants */
10970 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10974 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10978 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10979 board_config = snd_hda_check_board_codec_sid_config(codec,
10980 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10982 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
10983 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10985 board_config = ALC882_AUTO;
10988 if (board_config == ALC882_AUTO) {
10989 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
10990 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
10993 alc_auto_parse_customize_define(codec);
10995 if (board_config == ALC882_AUTO) {
10996 /* automatic parse from the BIOS config */
10997 err = alc882_parse_auto_config(codec);
11003 "hda_codec: Cannot set up configuration "
11004 "from BIOS. Using base mode...\n");
11005 board_config = ALC882_3ST_DIG;
11009 if (has_cdefine_beep(codec)) {
11010 err = snd_hda_attach_beep_device(codec, 0x1);
11017 if (board_config != ALC882_AUTO)
11018 setup_preset(codec, &alc882_presets[board_config]);
11020 if (!spec->adc_nids && spec->input_mux) {
11021 alc_auto_fill_adc_caps(codec);
11022 alc_remove_invalid_adc_nids(codec);
11025 set_capture_mixer(codec);
11027 if (has_cdefine_beep(codec))
11028 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11030 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11032 spec->vmaster_nid = 0x0c;
11034 codec->patch_ops = alc_patch_ops;
11035 if (board_config == ALC882_AUTO)
11036 spec->init_hook = alc882_auto_init;
11038 alc_init_jacks(codec);
11039 #ifdef CONFIG_SND_HDA_POWER_SAVE
11040 if (!spec->loopback.amplist)
11041 spec->loopback.amplist = alc882_loopbacks;
11052 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11053 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
11055 #define alc262_dac_nids alc260_dac_nids
11056 #define alc262_adc_nids alc882_adc_nids
11057 #define alc262_adc_nids_alt alc882_adc_nids_alt
11058 #define alc262_capsrc_nids alc882_capsrc_nids
11059 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11061 #define alc262_modes alc260_modes
11062 #define alc262_capture_source alc882_capture_source
11064 static const hda_nid_t alc262_dmic_adc_nids[1] = {
11069 static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11071 static const struct snd_kcontrol_new alc262_base_mixer[] = {
11072 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11073 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11074 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11075 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11076 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11077 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11078 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11079 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11080 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11081 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11082 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11083 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11084 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11085 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11086 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11087 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11091 /* update HP, line and mono-out pins according to the master switch */
11092 #define alc262_hp_master_update alc260_hp_master_update
11094 static void alc262_hp_bpc_setup(struct hda_codec *codec)
11096 struct alc_spec *spec = codec->spec;
11098 spec->autocfg.hp_pins[0] = 0x1b;
11099 spec->autocfg.speaker_pins[0] = 0x16;
11100 spec->automute = 1;
11101 spec->automute_mode = ALC_AUTOMUTE_PIN;
11104 static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11106 struct alc_spec *spec = codec->spec;
11108 spec->autocfg.hp_pins[0] = 0x15;
11109 spec->autocfg.speaker_pins[0] = 0x16;
11110 spec->automute = 1;
11111 spec->automute_mode = ALC_AUTOMUTE_PIN;
11114 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11115 #define alc262_hp_master_sw_put alc260_hp_master_sw_put
11117 #define ALC262_HP_MASTER_SWITCH \
11119 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11120 .name = "Master Playback Switch", \
11121 .info = snd_ctl_boolean_mono_info, \
11122 .get = alc262_hp_master_sw_get, \
11123 .put = alc262_hp_master_sw_put, \
11126 .iface = NID_MAPPING, \
11127 .name = "Master Playback Switch", \
11128 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11132 static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11133 ALC262_HP_MASTER_SWITCH,
11134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11135 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11137 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11139 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11142 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11143 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11147 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11148 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11149 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11150 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11151 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11152 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11156 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11157 ALC262_HP_MASTER_SWITCH,
11158 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11159 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11160 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11161 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11162 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11164 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11166 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11167 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11168 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11169 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11170 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11171 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11172 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11176 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11177 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11178 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11179 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11183 /* mute/unmute internal speaker according to the hp jack and mute state */
11184 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11186 struct alc_spec *spec = codec->spec;
11188 spec->autocfg.hp_pins[0] = 0x15;
11189 spec->autocfg.speaker_pins[0] = 0x14;
11190 spec->automute = 1;
11191 spec->automute_mode = ALC_AUTOMUTE_PIN;
11194 static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11195 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11196 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11197 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11201 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11205 static const struct hda_verb alc262_hp_t5735_verbs[] = {
11206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11207 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11209 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11213 static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11214 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11216 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11217 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11223 static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11224 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11225 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11226 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11227 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11228 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11229 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11230 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11232 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11233 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11237 static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11244 /* bind hp and internal speaker mute (with plug check) as master switch */
11245 #define alc262_hippo_master_update alc262_hp_master_update
11246 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11247 #define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11249 #define ALC262_HIPPO_MASTER_SWITCH \
11251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11252 .name = "Master Playback Switch", \
11253 .info = snd_ctl_boolean_mono_info, \
11254 .get = alc262_hippo_master_sw_get, \
11255 .put = alc262_hippo_master_sw_put, \
11258 .iface = NID_MAPPING, \
11259 .name = "Master Playback Switch", \
11260 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11261 (SUBDEV_SPEAKER(0) << 16), \
11264 static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11265 ALC262_HIPPO_MASTER_SWITCH,
11266 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11267 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11268 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11269 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11270 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11275 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11276 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11277 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11281 static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11282 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11283 ALC262_HIPPO_MASTER_SWITCH,
11284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11288 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11289 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11290 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11291 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11292 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11293 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11297 /* mute/unmute internal speaker according to the hp jack and mute state */
11298 static void alc262_hippo_setup(struct hda_codec *codec)
11300 struct alc_spec *spec = codec->spec;
11302 spec->autocfg.hp_pins[0] = 0x15;
11303 spec->autocfg.speaker_pins[0] = 0x14;
11304 spec->automute = 1;
11305 spec->automute_mode = ALC_AUTOMUTE_AMP;
11308 static void alc262_hippo1_setup(struct hda_codec *codec)
11310 struct alc_spec *spec = codec->spec;
11312 spec->autocfg.hp_pins[0] = 0x1b;
11313 spec->autocfg.speaker_pins[0] = 0x14;
11314 spec->automute = 1;
11315 spec->automute_mode = ALC_AUTOMUTE_AMP;
11319 static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11320 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11321 ALC262_HIPPO_MASTER_SWITCH,
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("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11325 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11329 static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11330 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11331 ALC262_HIPPO_MASTER_SWITCH,
11332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11333 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11334 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11335 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11336 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11340 static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11341 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11342 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11343 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11344 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11345 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11346 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11348 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11349 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11350 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11351 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11352 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11356 static const struct hda_verb alc262_tyan_verbs[] = {
11357 /* Headphone automute */
11358 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11359 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11360 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11362 /* P11 AUX_IN, white 4-pin connector */
11363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11364 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11365 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11366 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11371 /* unsolicited event for HP jack sensing */
11372 static void alc262_tyan_setup(struct hda_codec *codec)
11374 struct alc_spec *spec = codec->spec;
11376 spec->autocfg.hp_pins[0] = 0x1b;
11377 spec->autocfg.speaker_pins[0] = 0x15;
11378 spec->automute = 1;
11379 spec->automute_mode = ALC_AUTOMUTE_AMP;
11383 #define alc262_capture_mixer alc882_capture_mixer
11384 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11387 * generic initialization of ADC, input mixers and output mixers
11389 static const struct hda_verb alc262_init_verbs[] = {
11391 * Unmute ADC0-2 and set the default input to mic-in
11393 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11394 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11395 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11396 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11397 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11398 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11400 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11402 * Note: PASD motherboards uses the Line In 2 as the input for
11403 * front panel mic (mic 2)
11405 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11413 * Set up output mixers (0x0c - 0x0e)
11415 /* set vol=0 to output mixers */
11416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11419 /* set up input amps for analog loopback */
11420 /* Amp Indices: DAC = 0, mixer = 1 */
11421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11423 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11425 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11428 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11429 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11430 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11432 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11433 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11435 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11437 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11438 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11439 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11441 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11442 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11444 /* FIXME: use matrix-type input source selection */
11445 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11446 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11465 static const struct hda_verb alc262_eapd_verbs[] = {
11466 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11467 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11471 static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11472 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11473 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11474 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11476 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11477 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11481 static const struct hda_verb alc262_sony_unsol_verbs[] = {
11482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11483 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11486 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11491 static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11492 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11493 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11494 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11496 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11500 static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11501 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11502 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11504 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11505 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11506 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11507 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11508 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11512 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11514 struct alc_spec *spec = codec->spec;
11516 spec->autocfg.hp_pins[0] = 0x15;
11517 spec->autocfg.speaker_pins[0] = 0x14;
11518 spec->ext_mic.pin = 0x18;
11519 spec->ext_mic.mux_idx = 0;
11520 spec->int_mic.pin = 0x12;
11521 spec->int_mic.mux_idx = 9;
11522 spec->auto_mic = 1;
11523 spec->automute = 1;
11524 spec->automute_mode = ALC_AUTOMUTE_PIN;
11530 * 0x16 = internal speaker
11531 * 0x18 = external mic
11534 static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11535 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11536 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11538 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11539 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11540 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11547 static const struct hda_verb alc262_nec_verbs[] = {
11548 /* Unmute Speaker */
11549 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11552 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11553 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11555 /* External mic to headphone */
11556 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11557 /* External mic to speaker */
11558 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11564 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11565 * 0x1b = port replicator headphone out
11568 #define ALC_HP_EVENT ALC880_HP_EVENT
11570 static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11571 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11572 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11573 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11574 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11578 static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11579 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11580 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11584 static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11585 /* Front Mic pin: input vref at 50% */
11586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11591 static const struct hda_input_mux alc262_fujitsu_capture_source = {
11595 { "Internal Mic", 0x1 },
11600 static const struct hda_input_mux alc262_HP_capture_source = {
11604 { "Front Mic", 0x1 },
11611 static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11615 { "Front Mic", 0x2 },
11621 static void alc262_fujitsu_setup(struct hda_codec *codec)
11623 struct alc_spec *spec = codec->spec;
11625 spec->autocfg.hp_pins[0] = 0x14;
11626 spec->autocfg.hp_pins[1] = 0x1b;
11627 spec->autocfg.speaker_pins[0] = 0x15;
11628 spec->automute = 1;
11629 spec->automute_mode = ALC_AUTOMUTE_AMP;
11632 /* bind volumes of both NID 0x0c and 0x0d */
11633 static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11634 .ops = &snd_hda_bind_vol,
11636 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11637 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11642 static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11643 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11645 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11646 .name = "Master Playback Switch",
11647 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11648 .info = snd_ctl_boolean_mono_info,
11649 .get = alc262_hp_master_sw_get,
11650 .put = alc262_hp_master_sw_put,
11653 .iface = NID_MAPPING,
11654 .name = "Master Playback Switch",
11655 .private_value = 0x1b,
11657 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11658 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11662 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11663 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11664 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11668 static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11670 struct alc_spec *spec = codec->spec;
11672 spec->autocfg.hp_pins[0] = 0x1b;
11673 spec->autocfg.speaker_pins[0] = 0x14;
11674 spec->autocfg.speaker_pins[1] = 0x16;
11675 spec->automute = 1;
11676 spec->automute_mode = ALC_AUTOMUTE_AMP;
11679 static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11680 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11683 .name = "Master Playback Switch",
11684 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11685 .info = snd_ctl_boolean_mono_info,
11686 .get = alc262_hp_master_sw_get,
11687 .put = alc262_hp_master_sw_put,
11689 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11690 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11691 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11694 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11695 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11696 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11700 static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11701 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11702 ALC262_HIPPO_MASTER_SWITCH,
11703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11705 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11706 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11707 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11708 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11712 /* additional init verbs for Benq laptops */
11713 static const struct hda_verb alc262_EAPD_verbs[] = {
11714 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11715 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11719 static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11720 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11721 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11723 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11724 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11728 /* Samsung Q1 Ultra Vista model setup */
11729 static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
11730 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11731 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11734 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11735 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11739 static const struct hda_verb alc262_ultra_verbs[] = {
11741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11742 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11745 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11746 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11748 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11750 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11752 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11753 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11754 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11757 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11758 /* ADC, choose mic */
11759 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11768 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11772 /* mute/unmute internal speaker according to the hp jack and mute state */
11773 static void alc262_ultra_automute(struct hda_codec *codec)
11775 struct alc_spec *spec = codec->spec;
11779 /* auto-mute only when HP is used as HP */
11780 if (!spec->cur_mux[0]) {
11781 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11782 if (spec->jack_present)
11783 mute = HDA_AMP_MUTE;
11785 /* mute/unmute internal speaker */
11786 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11787 HDA_AMP_MUTE, mute);
11788 /* mute/unmute HP */
11789 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11790 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11793 /* unsolicited event for HP jack sensing */
11794 static void alc262_ultra_unsol_event(struct hda_codec *codec,
11797 if ((res >> 26) != ALC880_HP_EVENT)
11799 alc262_ultra_automute(codec);
11802 static const struct hda_input_mux alc262_ultra_capture_source = {
11806 { "Headphone", 0x7 },
11810 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11811 struct snd_ctl_elem_value *ucontrol)
11813 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11814 struct alc_spec *spec = codec->spec;
11817 ret = alc_mux_enum_put(kcontrol, ucontrol);
11820 /* reprogram the HP pin as mic or HP according to the input source */
11821 snd_hda_codec_write_cache(codec, 0x15, 0,
11822 AC_VERB_SET_PIN_WIDGET_CONTROL,
11823 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11824 alc262_ultra_automute(codec); /* mute/unmute HP */
11828 static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11829 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11830 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11833 .name = "Capture Source",
11834 .info = alc_mux_enum_info,
11835 .get = alc_mux_enum_get,
11836 .put = alc262_ultra_mux_enum_put,
11839 .iface = NID_MAPPING,
11840 .name = "Capture Source",
11841 .private_value = 0x15,
11846 /* We use two mixers depending on the output pin; 0x16 is a mono output
11847 * and thus it's bound with a different mixer.
11848 * This function returns which mixer amp should be used.
11850 static int alc262_check_volbit(hda_nid_t nid)
11854 else if (nid == 0x16)
11860 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11861 const char *pfx, int *vbits, int idx)
11866 vbit = alc262_check_volbit(nid);
11869 if (*vbits & vbit) /* a volume control for this mixer already there */
11873 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11875 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11876 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
11879 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11880 const char *pfx, int idx)
11887 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11889 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11890 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
11893 /* add playback controls from the parsed DAC table */
11894 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11895 const struct auto_pin_cfg *cfg)
11901 spec->multiout.num_dacs = 1; /* only use one dac */
11902 spec->multiout.dac_nids = spec->private_dac_nids;
11903 spec->private_dac_nids[0] = 2;
11905 for (i = 0; i < 2; i++) {
11906 pfx = alc_get_line_out_pfx(spec, i, true, &index);
11909 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
11913 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11914 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
11919 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
11920 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
11927 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11928 alc262_check_volbit(cfg->speaker_pins[0]) |
11929 alc262_check_volbit(cfg->hp_pins[0]);
11931 for (i = 0; i < 2; i++) {
11932 pfx = alc_get_line_out_pfx(spec, i, true, &index);
11935 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
11939 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11940 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
11941 "Speaker", &vbits, i);
11945 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
11946 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
11947 "Headphone", &vbits, i);
11955 static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
11957 * Unmute ADC0-2 and set the default input to mic-in
11959 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11961 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11962 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11963 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11964 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11966 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11968 * Note: PASD motherboards uses the Line In 2 as the input for
11969 * front panel mic (mic 2)
11971 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11972 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11973 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11974 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11975 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11976 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11977 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11978 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11981 * Set up output mixers (0x0c - 0x0e)
11983 /* set vol=0 to output mixers */
11984 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11985 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11986 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11988 /* set up input amps for analog loopback */
11989 /* Amp Indices: DAC = 0, mixer = 1 */
11990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11993 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11994 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11995 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11998 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11999 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12001 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12004 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12005 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12007 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12008 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12009 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12010 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12011 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12013 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12014 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12015 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12016 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12017 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12018 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12021 /* FIXME: use matrix-type input source selection */
12022 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12023 /* Input mixer1: only unmute Mic */
12024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12030 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12031 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12032 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12034 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12035 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12036 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12037 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12038 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12039 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12040 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12041 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12042 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12044 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12047 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12049 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12050 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12054 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12059 static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12061 * Unmute ADC0-2 and set the default input to mic-in
12063 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12064 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12065 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12066 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12067 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12068 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12070 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12072 * Note: PASD motherboards uses the Line In 2 as the input for front
12073 * panel mic (mic 2)
12075 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12076 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12077 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12078 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12079 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12080 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12082 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12083 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12085 * Set up output mixers (0x0c - 0x0e)
12087 /* set vol=0 to output mixers */
12088 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12089 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12090 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12092 /* set up input amps for analog loopback */
12093 /* Amp Indices: DAC = 0, mixer = 1 */
12094 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12095 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12096 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12097 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12098 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12099 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12102 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12103 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12104 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12105 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12106 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12107 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12108 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12110 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12113 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12114 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12116 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12117 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12118 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12119 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12120 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12121 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12123 /* FIXME: use matrix-type input source selection */
12124 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12125 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12126 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12127 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12128 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12129 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12130 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12131 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12132 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12134 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12135 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12139 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12147 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12148 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12150 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12155 static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12158 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12159 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12161 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12162 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12163 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12166 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12168 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12180 static const struct alc_fixup alc262_fixups[] = {
12181 [PINFIX_FSC_H270] = {
12182 .type = ALC_FIXUP_PINS,
12183 .v.pins = (const struct alc_pincfg[]) {
12184 { 0x14, 0x99130110 }, /* speaker */
12185 { 0x15, 0x0221142f }, /* front HP */
12186 { 0x1b, 0x0121141f }, /* rear HP */
12190 [PINFIX_HP_Z200] = {
12191 .type = ALC_FIXUP_PINS,
12192 .v.pins = (const struct alc_pincfg[]) {
12193 { 0x16, 0x99130120 }, /* internal speaker */
12199 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12200 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12201 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12206 #ifdef CONFIG_SND_HDA_POWER_SAVE
12207 #define alc262_loopbacks alc880_loopbacks
12211 * BIOS auto configuration
12213 static int alc262_parse_auto_config(struct hda_codec *codec)
12215 struct alc_spec *spec = codec->spec;
12217 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12219 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12223 if (!spec->autocfg.line_outs) {
12224 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12225 spec->multiout.max_channels = 2;
12226 spec->no_analog = 1;
12229 return 0; /* can't find valid BIOS pin config */
12231 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12234 err = alc_auto_create_input_ctls(codec);
12238 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12241 alc_auto_parse_digital(codec);
12243 if (spec->kctls.list)
12244 add_mixer(spec, spec->kctls.list);
12246 spec->num_mux_defs = 1;
12247 spec->input_mux = &spec->private_imux[0];
12249 if (!spec->dual_adc_switch)
12250 alc_remove_invalid_adc_nids(codec);
12252 err = alc_auto_add_mic_boost(codec);
12256 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12262 /* init callback for auto-configuration model -- overriding the default init */
12263 static void alc262_auto_init(struct hda_codec *codec)
12265 struct alc_spec *spec = codec->spec;
12266 alc_auto_init_multi_out(codec);
12267 alc_auto_init_extra_out(codec);
12268 alc_auto_init_analog_input(codec);
12269 alc_auto_init_input_src(codec);
12270 alc_auto_init_digital(codec);
12271 if (spec->unsol_event)
12272 alc_inithook(codec);
12276 * configuration and preset
12278 static const char * const alc262_models[ALC262_MODEL_LAST] = {
12279 [ALC262_BASIC] = "basic",
12280 [ALC262_HIPPO] = "hippo",
12281 [ALC262_HIPPO_1] = "hippo_1",
12282 [ALC262_FUJITSU] = "fujitsu",
12283 [ALC262_HP_BPC] = "hp-bpc",
12284 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12285 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12286 [ALC262_HP_RP5700] = "hp-rp5700",
12287 [ALC262_BENQ_ED8] = "benq",
12288 [ALC262_BENQ_T31] = "benq-t31",
12289 [ALC262_SONY_ASSAMD] = "sony-assamd",
12290 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12291 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12292 [ALC262_ULTRA] = "ultra",
12293 [ALC262_LENOVO_3000] = "lenovo-3000",
12294 [ALC262_NEC] = "nec",
12295 [ALC262_TYAN] = "tyan",
12296 [ALC262_AUTO] = "auto",
12299 static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12300 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12301 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12302 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12304 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12306 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12308 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12310 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12312 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12313 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12314 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12315 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12316 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12317 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12318 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12319 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12320 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12321 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12322 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12323 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12324 ALC262_HP_TC_T5735),
12325 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12326 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12327 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12328 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12329 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12330 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12331 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12332 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12333 #if 0 /* disable the quirk since model=auto works better in recent versions */
12334 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12335 ALC262_SONY_ASSAMD),
12337 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12338 ALC262_TOSHIBA_RX1),
12339 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12340 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12341 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12342 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12343 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12345 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12346 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12347 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12348 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12349 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12353 static const struct alc_config_preset alc262_presets[] = {
12355 .mixers = { alc262_base_mixer },
12356 .init_verbs = { alc262_init_verbs },
12357 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12358 .dac_nids = alc262_dac_nids,
12360 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12361 .channel_mode = alc262_modes,
12362 .input_mux = &alc262_capture_source,
12365 .mixers = { alc262_hippo_mixer },
12366 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12367 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12368 .dac_nids = alc262_dac_nids,
12370 .dig_out_nid = ALC262_DIGOUT_NID,
12371 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12372 .channel_mode = alc262_modes,
12373 .input_mux = &alc262_capture_source,
12374 .unsol_event = alc_sku_unsol_event,
12375 .setup = alc262_hippo_setup,
12376 .init_hook = alc_inithook,
12378 [ALC262_HIPPO_1] = {
12379 .mixers = { alc262_hippo1_mixer },
12380 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12381 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12382 .dac_nids = alc262_dac_nids,
12384 .dig_out_nid = ALC262_DIGOUT_NID,
12385 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12386 .channel_mode = alc262_modes,
12387 .input_mux = &alc262_capture_source,
12388 .unsol_event = alc_sku_unsol_event,
12389 .setup = alc262_hippo1_setup,
12390 .init_hook = alc_inithook,
12392 [ALC262_FUJITSU] = {
12393 .mixers = { alc262_fujitsu_mixer },
12394 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12395 alc262_fujitsu_unsol_verbs },
12396 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12397 .dac_nids = alc262_dac_nids,
12399 .dig_out_nid = ALC262_DIGOUT_NID,
12400 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12401 .channel_mode = alc262_modes,
12402 .input_mux = &alc262_fujitsu_capture_source,
12403 .unsol_event = alc_sku_unsol_event,
12404 .setup = alc262_fujitsu_setup,
12405 .init_hook = alc_inithook,
12407 [ALC262_HP_BPC] = {
12408 .mixers = { alc262_HP_BPC_mixer },
12409 .init_verbs = { alc262_HP_BPC_init_verbs },
12410 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12411 .dac_nids = alc262_dac_nids,
12413 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12414 .channel_mode = alc262_modes,
12415 .input_mux = &alc262_HP_capture_source,
12416 .unsol_event = alc_sku_unsol_event,
12417 .setup = alc262_hp_bpc_setup,
12418 .init_hook = alc_inithook,
12420 [ALC262_HP_BPC_D7000_WF] = {
12421 .mixers = { alc262_HP_BPC_WildWest_mixer },
12422 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12423 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12424 .dac_nids = alc262_dac_nids,
12426 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12427 .channel_mode = alc262_modes,
12428 .input_mux = &alc262_HP_D7000_capture_source,
12429 .unsol_event = alc_sku_unsol_event,
12430 .setup = alc262_hp_wildwest_setup,
12431 .init_hook = alc_inithook,
12433 [ALC262_HP_BPC_D7000_WL] = {
12434 .mixers = { alc262_HP_BPC_WildWest_mixer,
12435 alc262_HP_BPC_WildWest_option_mixer },
12436 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12437 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12438 .dac_nids = alc262_dac_nids,
12440 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12441 .channel_mode = alc262_modes,
12442 .input_mux = &alc262_HP_D7000_capture_source,
12443 .unsol_event = alc_sku_unsol_event,
12444 .setup = alc262_hp_wildwest_setup,
12445 .init_hook = alc_inithook,
12447 [ALC262_HP_TC_T5735] = {
12448 .mixers = { alc262_hp_t5735_mixer },
12449 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12450 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12451 .dac_nids = alc262_dac_nids,
12453 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12454 .channel_mode = alc262_modes,
12455 .input_mux = &alc262_capture_source,
12456 .unsol_event = alc_sku_unsol_event,
12457 .setup = alc262_hp_t5735_setup,
12458 .init_hook = alc_inithook,
12460 [ALC262_HP_RP5700] = {
12461 .mixers = { alc262_hp_rp5700_mixer },
12462 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12463 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12464 .dac_nids = alc262_dac_nids,
12465 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12466 .channel_mode = alc262_modes,
12467 .input_mux = &alc262_hp_rp5700_capture_source,
12469 [ALC262_BENQ_ED8] = {
12470 .mixers = { alc262_base_mixer },
12471 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12472 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12473 .dac_nids = alc262_dac_nids,
12475 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12476 .channel_mode = alc262_modes,
12477 .input_mux = &alc262_capture_source,
12479 [ALC262_SONY_ASSAMD] = {
12480 .mixers = { alc262_sony_mixer },
12481 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12482 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12483 .dac_nids = alc262_dac_nids,
12485 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12486 .channel_mode = alc262_modes,
12487 .input_mux = &alc262_capture_source,
12488 .unsol_event = alc_sku_unsol_event,
12489 .setup = alc262_hippo_setup,
12490 .init_hook = alc_inithook,
12492 [ALC262_BENQ_T31] = {
12493 .mixers = { alc262_benq_t31_mixer },
12494 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12495 alc_hp15_unsol_verbs },
12496 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12497 .dac_nids = alc262_dac_nids,
12499 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12500 .channel_mode = alc262_modes,
12501 .input_mux = &alc262_capture_source,
12502 .unsol_event = alc_sku_unsol_event,
12503 .setup = alc262_hippo_setup,
12504 .init_hook = alc_inithook,
12507 .mixers = { alc262_ultra_mixer },
12508 .cap_mixer = alc262_ultra_capture_mixer,
12509 .init_verbs = { alc262_ultra_verbs },
12510 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12511 .dac_nids = alc262_dac_nids,
12512 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12513 .channel_mode = alc262_modes,
12514 .input_mux = &alc262_ultra_capture_source,
12515 .adc_nids = alc262_adc_nids, /* ADC0 */
12516 .capsrc_nids = alc262_capsrc_nids,
12517 .num_adc_nids = 1, /* single ADC */
12518 .unsol_event = alc262_ultra_unsol_event,
12519 .init_hook = alc262_ultra_automute,
12521 [ALC262_LENOVO_3000] = {
12522 .mixers = { alc262_lenovo_3000_mixer },
12523 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12524 alc262_lenovo_3000_unsol_verbs,
12525 alc262_lenovo_3000_init_verbs },
12526 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12527 .dac_nids = alc262_dac_nids,
12529 .dig_out_nid = ALC262_DIGOUT_NID,
12530 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12531 .channel_mode = alc262_modes,
12532 .input_mux = &alc262_fujitsu_capture_source,
12533 .unsol_event = alc_sku_unsol_event,
12534 .setup = alc262_lenovo_3000_setup,
12535 .init_hook = alc_inithook,
12538 .mixers = { alc262_nec_mixer },
12539 .init_verbs = { alc262_nec_verbs },
12540 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12541 .dac_nids = alc262_dac_nids,
12543 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12544 .channel_mode = alc262_modes,
12545 .input_mux = &alc262_capture_source,
12547 [ALC262_TOSHIBA_S06] = {
12548 .mixers = { alc262_toshiba_s06_mixer },
12549 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12550 alc262_eapd_verbs },
12551 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12552 .capsrc_nids = alc262_dmic_capsrc_nids,
12553 .dac_nids = alc262_dac_nids,
12554 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12555 .num_adc_nids = 1, /* single ADC */
12556 .dig_out_nid = ALC262_DIGOUT_NID,
12557 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12558 .channel_mode = alc262_modes,
12559 .unsol_event = alc_sku_unsol_event,
12560 .setup = alc262_toshiba_s06_setup,
12561 .init_hook = alc_inithook,
12563 [ALC262_TOSHIBA_RX1] = {
12564 .mixers = { alc262_toshiba_rx1_mixer },
12565 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12566 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12567 .dac_nids = alc262_dac_nids,
12569 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12570 .channel_mode = alc262_modes,
12571 .input_mux = &alc262_capture_source,
12572 .unsol_event = alc_sku_unsol_event,
12573 .setup = alc262_hippo_setup,
12574 .init_hook = alc_inithook,
12577 .mixers = { alc262_tyan_mixer },
12578 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12579 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12580 .dac_nids = alc262_dac_nids,
12582 .dig_out_nid = ALC262_DIGOUT_NID,
12583 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12584 .channel_mode = alc262_modes,
12585 .input_mux = &alc262_capture_source,
12586 .unsol_event = alc_sku_unsol_event,
12587 .setup = alc262_tyan_setup,
12588 .init_hook = alc_hp_automute,
12592 static int patch_alc262(struct hda_codec *codec)
12594 struct alc_spec *spec;
12598 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12602 codec->spec = spec;
12604 spec->mixer_nid = 0x0b;
12607 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12612 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12613 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12614 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12615 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12618 alc_auto_parse_customize_define(codec);
12620 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12622 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12626 if (board_config < 0) {
12627 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12629 board_config = ALC262_AUTO;
12632 if (board_config == ALC262_AUTO) {
12633 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12634 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12637 if (board_config == ALC262_AUTO) {
12638 /* automatic parse from the BIOS config */
12639 err = alc262_parse_auto_config(codec);
12645 "hda_codec: Cannot set up configuration "
12646 "from BIOS. Using base mode...\n");
12647 board_config = ALC262_BASIC;
12651 if (!spec->no_analog && has_cdefine_beep(codec)) {
12652 err = snd_hda_attach_beep_device(codec, 0x1);
12659 if (board_config != ALC262_AUTO)
12660 setup_preset(codec, &alc262_presets[board_config]);
12662 if (!spec->adc_nids && spec->input_mux) {
12663 alc_auto_fill_adc_caps(codec);
12664 alc_remove_invalid_adc_nids(codec);
12666 if (!spec->cap_mixer && !spec->no_analog)
12667 set_capture_mixer(codec);
12668 if (!spec->no_analog && has_cdefine_beep(codec))
12669 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12671 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
12673 spec->vmaster_nid = 0x0c;
12675 codec->patch_ops = alc_patch_ops;
12676 if (board_config == ALC262_AUTO)
12677 spec->init_hook = alc262_auto_init;
12678 spec->shutup = alc_eapd_shutup;
12680 alc_init_jacks(codec);
12681 #ifdef CONFIG_SND_HDA_POWER_SAVE
12682 if (!spec->loopback.amplist)
12683 spec->loopback.amplist = alc262_loopbacks;
12690 * ALC268 channel source setting (2 channel)
12692 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12693 #define alc268_modes alc260_modes
12695 static const hda_nid_t alc268_dac_nids[2] = {
12700 static const hda_nid_t alc268_adc_nids[2] = {
12705 static const hda_nid_t alc268_adc_nids_alt[1] = {
12710 static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12712 static const struct snd_kcontrol_new alc268_base_mixer[] = {
12713 /* output mixer control */
12714 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12715 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12716 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12717 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12718 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12719 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12720 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12724 static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12725 /* output mixer control */
12726 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12727 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12728 ALC262_HIPPO_MASTER_SWITCH,
12729 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12730 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12731 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12735 /* bind Beep switches of both NID 0x0f and 0x10 */
12736 static const struct hda_bind_ctls alc268_bind_beep_sw = {
12737 .ops = &snd_hda_bind_sw,
12739 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12740 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12745 static const struct snd_kcontrol_new alc268_beep_mixer[] = {
12746 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12747 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12751 static const struct hda_verb alc268_eapd_verbs[] = {
12752 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12753 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12757 /* Toshiba specific */
12758 static const struct hda_verb alc268_toshiba_verbs[] = {
12759 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12763 /* Acer specific */
12764 /* bind volumes of both NID 0x02 and 0x03 */
12765 static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
12766 .ops = &snd_hda_bind_vol,
12768 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12769 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12774 static void alc268_acer_setup(struct hda_codec *codec)
12776 struct alc_spec *spec = codec->spec;
12778 spec->autocfg.hp_pins[0] = 0x14;
12779 spec->autocfg.speaker_pins[0] = 0x15;
12780 spec->automute = 1;
12781 spec->automute_mode = ALC_AUTOMUTE_AMP;
12784 #define alc268_acer_master_sw_get alc262_hp_master_sw_get
12785 #define alc268_acer_master_sw_put alc262_hp_master_sw_put
12787 static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12788 /* output mixer control */
12789 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12792 .name = "Master Playback Switch",
12793 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
12794 .info = snd_ctl_boolean_mono_info,
12795 .get = alc268_acer_master_sw_get,
12796 .put = alc268_acer_master_sw_put,
12798 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12802 static const struct snd_kcontrol_new alc268_acer_mixer[] = {
12803 /* output mixer control */
12804 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12807 .name = "Master Playback Switch",
12808 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12809 .info = snd_ctl_boolean_mono_info,
12810 .get = alc268_acer_master_sw_get,
12811 .put = alc268_acer_master_sw_put,
12813 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12814 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12815 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12819 static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12820 /* output mixer control */
12821 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12824 .name = "Master Playback Switch",
12825 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12826 .info = snd_ctl_boolean_mono_info,
12827 .get = alc268_acer_master_sw_get,
12828 .put = alc268_acer_master_sw_put,
12830 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12831 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12835 static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
12836 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12837 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12838 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12839 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12840 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12841 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12845 static const struct hda_verb alc268_acer_verbs[] = {
12846 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12847 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12848 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12851 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12852 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12856 /* unsolicited event for HP jack sensing */
12857 #define alc268_toshiba_setup alc262_hippo_setup
12859 static void alc268_acer_lc_setup(struct hda_codec *codec)
12861 struct alc_spec *spec = codec->spec;
12862 spec->autocfg.hp_pins[0] = 0x15;
12863 spec->autocfg.speaker_pins[0] = 0x14;
12864 spec->automute = 1;
12865 spec->automute_mode = ALC_AUTOMUTE_AMP;
12866 spec->ext_mic.pin = 0x18;
12867 spec->ext_mic.mux_idx = 0;
12868 spec->int_mic.pin = 0x12;
12869 spec->int_mic.mux_idx = 6;
12870 spec->auto_mic = 1;
12873 static const struct snd_kcontrol_new alc268_dell_mixer[] = {
12874 /* output mixer control */
12875 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12876 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12877 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12878 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12879 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12880 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12884 static const struct hda_verb alc268_dell_verbs[] = {
12885 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12886 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12887 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12888 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12892 /* mute/unmute internal speaker according to the hp jack and mute state */
12893 static void alc268_dell_setup(struct hda_codec *codec)
12895 struct alc_spec *spec = codec->spec;
12897 spec->autocfg.hp_pins[0] = 0x15;
12898 spec->autocfg.speaker_pins[0] = 0x14;
12899 spec->ext_mic.pin = 0x18;
12900 spec->ext_mic.mux_idx = 0;
12901 spec->int_mic.pin = 0x19;
12902 spec->int_mic.mux_idx = 1;
12903 spec->auto_mic = 1;
12904 spec->automute = 1;
12905 spec->automute_mode = ALC_AUTOMUTE_PIN;
12908 static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12909 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12910 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12911 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12912 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12913 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12914 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12915 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12916 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12920 static const struct hda_verb alc267_quanta_il1_verbs[] = {
12921 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12922 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12926 static void alc267_quanta_il1_setup(struct hda_codec *codec)
12928 struct alc_spec *spec = codec->spec;
12929 spec->autocfg.hp_pins[0] = 0x15;
12930 spec->autocfg.speaker_pins[0] = 0x14;
12931 spec->ext_mic.pin = 0x18;
12932 spec->ext_mic.mux_idx = 0;
12933 spec->int_mic.pin = 0x19;
12934 spec->int_mic.mux_idx = 1;
12935 spec->auto_mic = 1;
12936 spec->automute = 1;
12937 spec->automute_mode = ALC_AUTOMUTE_PIN;
12941 * generic initialization of ADC, input mixers and output mixers
12943 static const struct hda_verb alc268_base_init_verbs[] = {
12944 /* Unmute DAC0-1 and set vol = 0 */
12945 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12946 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12949 * Set up output mixers (0x0c - 0x0e)
12951 /* set vol=0 to output mixers */
12952 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12953 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12955 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12956 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12958 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12959 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12960 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12961 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12962 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12963 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12964 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12965 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12967 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12969 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12970 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12971 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12973 /* set PCBEEP vol = 0, mute connections */
12974 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12975 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12976 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12978 /* Unmute Selector 23h,24h and set the default input to mic-in */
12980 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12982 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12983 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12988 /* only for model=test */
12989 #ifdef CONFIG_SND_DEBUG
12991 * generic initialization of ADC, input mixers and output mixers
12993 static const struct hda_verb alc268_volume_init_verbs[] = {
12994 /* set output DAC */
12995 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12996 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12998 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12999 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13000 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13001 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13002 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13004 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13005 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13006 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13008 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13009 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13012 #endif /* CONFIG_SND_DEBUG */
13014 /* set PCBEEP vol = 0, mute connections */
13015 static const struct hda_verb alc268_beep_init_verbs[] = {
13016 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13017 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13018 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13022 static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13023 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13024 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13028 static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13029 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13030 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13035 static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13036 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13037 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13038 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13039 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13044 static const struct hda_input_mux alc268_capture_source = {
13048 { "Front Mic", 0x1 },
13054 static const struct hda_input_mux alc268_acer_capture_source = {
13058 { "Internal Mic", 0x1 },
13063 static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13067 { "Internal Mic", 0x6 },
13072 #ifdef CONFIG_SND_DEBUG
13073 static const struct snd_kcontrol_new alc268_test_mixer[] = {
13074 /* Volume widgets */
13075 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13076 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13077 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13078 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13079 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13080 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13081 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13082 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13083 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13084 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13085 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13086 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13087 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13088 /* The below appears problematic on some hardwares */
13089 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13090 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13091 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13092 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13093 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13095 /* Modes for retasking pin widgets */
13096 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13097 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13098 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13099 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13101 /* Controls for GPIO pins, assuming they are configured as outputs */
13102 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13103 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13104 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13105 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13107 /* Switches to allow the digital SPDIF output pin to be enabled.
13108 * The ALC268 does not have an SPDIF input.
13110 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13112 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13113 * this output to turn on an external amplifier.
13115 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13116 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13122 /* create input playback/capture controls for the given pin */
13123 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13124 const char *ctlname, int idx)
13135 case 0x1a: /* ALC259/269 only */
13136 case 0x1b: /* ALC259/269 only */
13137 case 0x21: /* ALC269vb has this pin, too */
13141 snd_printd(KERN_WARNING "hda_codec: "
13142 "ignoring pin 0x%x as unknown\n", nid);
13145 if (spec->multiout.dac_nids[0] != dac &&
13146 spec->multiout.dac_nids[1] != dac) {
13147 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13148 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13152 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13156 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13157 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13159 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13160 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13166 /* add playback controls from the parsed DAC table */
13167 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13168 const struct auto_pin_cfg *cfg)
13173 spec->multiout.dac_nids = spec->private_dac_nids;
13175 nid = cfg->line_out_pins[0];
13179 name = alc_get_line_out_pfx(spec, 0, true, &index);
13180 err = alc268_new_analog_output(spec, nid, name, 0);
13185 nid = cfg->speaker_pins[0];
13187 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13188 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13192 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13196 nid = cfg->hp_pins[0];
13198 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13203 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13205 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13206 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13213 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13214 hda_nid_t nid, int pin_type)
13218 alc_set_pin_output(codec, nid, pin_type);
13219 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
13221 if (nid == 0x14 || nid == 0x16)
13225 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13228 static void alc268_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
13232 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13236 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13238 struct alc_spec *spec = codec->spec;
13241 for (i = 0; i < spec->autocfg.line_outs; i++) {
13242 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13243 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13244 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13247 for (i = 0; i < spec->multiout.num_dacs; i++)
13248 alc268_auto_init_dac(codec, spec->multiout.dac_nids[i]);
13251 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13253 struct alc_spec *spec = codec->spec;
13257 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13258 pin = spec->autocfg.hp_pins[i];
13259 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13261 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13262 pin = spec->autocfg.speaker_pins[i];
13263 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13265 if (spec->autocfg.mono_out_pin)
13266 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13267 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13269 alc268_auto_init_dac(codec, spec->multiout.hp_nid);
13270 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
13271 alc268_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
13274 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13276 struct alc_spec *spec = codec->spec;
13277 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13278 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13279 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13280 unsigned int dac_vol1, dac_vol2;
13282 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13283 snd_hda_codec_write(codec, speaker_nid, 0,
13284 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13285 /* mute mixer inputs from 0x1d */
13286 snd_hda_codec_write(codec, 0x0f, 0,
13287 AC_VERB_SET_AMP_GAIN_MUTE,
13289 snd_hda_codec_write(codec, 0x10, 0,
13290 AC_VERB_SET_AMP_GAIN_MUTE,
13293 /* unmute mixer inputs from 0x1d */
13294 snd_hda_codec_write(codec, 0x0f, 0,
13295 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13296 snd_hda_codec_write(codec, 0x10, 0,
13297 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13300 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13301 if (line_nid == 0x14)
13302 dac_vol2 = AMP_OUT_ZERO;
13303 else if (line_nid == 0x15)
13304 dac_vol1 = AMP_OUT_ZERO;
13305 if (hp_nid == 0x14)
13306 dac_vol2 = AMP_OUT_ZERO;
13307 else if (hp_nid == 0x15)
13308 dac_vol1 = AMP_OUT_ZERO;
13309 if (line_nid != 0x16 || hp_nid != 0x16 ||
13310 spec->autocfg.line_out_pins[1] != 0x16 ||
13311 spec->autocfg.line_out_pins[2] != 0x16)
13312 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13314 snd_hda_codec_write(codec, 0x02, 0,
13315 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13316 snd_hda_codec_write(codec, 0x03, 0,
13317 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13321 * BIOS auto configuration
13323 static int alc268_parse_auto_config(struct hda_codec *codec)
13325 struct alc_spec *spec = codec->spec;
13327 static const hda_nid_t alc268_ignore[] = { 0 };
13329 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13333 if (!spec->autocfg.line_outs) {
13334 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13335 spec->multiout.max_channels = 2;
13336 spec->no_analog = 1;
13339 return 0; /* can't find valid BIOS pin config */
13341 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13344 err = alc_auto_create_input_ctls(codec);
13348 spec->multiout.max_channels = 2;
13351 /* digital only support output */
13352 alc_auto_parse_digital(codec);
13353 if (spec->kctls.list)
13354 add_mixer(spec, spec->kctls.list);
13356 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
13357 add_mixer(spec, alc268_beep_mixer);
13358 add_verb(spec, alc268_beep_init_verbs);
13361 spec->num_mux_defs = 1;
13362 spec->input_mux = &spec->private_imux[0];
13364 if (!spec->dual_adc_switch)
13365 alc_remove_invalid_adc_nids(codec);
13367 err = alc_auto_add_mic_boost(codec);
13371 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13376 /* init callback for auto-configuration model -- overriding the default init */
13377 static void alc268_auto_init(struct hda_codec *codec)
13379 struct alc_spec *spec = codec->spec;
13380 alc268_auto_init_multi_out(codec);
13381 alc268_auto_init_hp_out(codec);
13382 alc268_auto_init_mono_speaker_out(codec);
13383 alc_auto_init_analog_input(codec);
13384 alc_auto_init_input_src(codec);
13385 alc_auto_init_digital(codec);
13386 if (spec->unsol_event)
13387 alc_inithook(codec);
13391 * configuration and preset
13393 static const char * const alc268_models[ALC268_MODEL_LAST] = {
13394 [ALC267_QUANTA_IL1] = "quanta-il1",
13395 [ALC268_3ST] = "3stack",
13396 [ALC268_TOSHIBA] = "toshiba",
13397 [ALC268_ACER] = "acer",
13398 [ALC268_ACER_DMIC] = "acer-dmic",
13399 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13400 [ALC268_DELL] = "dell",
13401 [ALC268_ZEPTO] = "zepto",
13402 #ifdef CONFIG_SND_DEBUG
13403 [ALC268_TEST] = "test",
13405 [ALC268_AUTO] = "auto",
13408 static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13409 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13410 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13411 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13412 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13413 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13414 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13415 ALC268_ACER_ASPIRE_ONE),
13416 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13417 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13418 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13419 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13420 /* almost compatible with toshiba but with optional digital outs;
13421 * auto-probing seems working fine
13423 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13425 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13426 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13427 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13428 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13432 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13433 static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13434 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13435 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13436 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13441 static const struct alc_config_preset alc268_presets[] = {
13442 [ALC267_QUANTA_IL1] = {
13443 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13444 alc268_capture_nosrc_mixer },
13445 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13446 alc267_quanta_il1_verbs },
13447 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13448 .dac_nids = alc268_dac_nids,
13449 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13450 .adc_nids = alc268_adc_nids_alt,
13452 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13453 .channel_mode = alc268_modes,
13454 .unsol_event = alc_sku_unsol_event,
13455 .setup = alc267_quanta_il1_setup,
13456 .init_hook = alc_inithook,
13459 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13460 alc268_beep_mixer },
13461 .init_verbs = { alc268_base_init_verbs },
13462 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13463 .dac_nids = alc268_dac_nids,
13464 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13465 .adc_nids = alc268_adc_nids_alt,
13466 .capsrc_nids = alc268_capsrc_nids,
13468 .dig_out_nid = ALC268_DIGOUT_NID,
13469 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13470 .channel_mode = alc268_modes,
13471 .input_mux = &alc268_capture_source,
13473 [ALC268_TOSHIBA] = {
13474 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13475 alc268_beep_mixer },
13476 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13477 alc268_toshiba_verbs },
13478 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13479 .dac_nids = alc268_dac_nids,
13480 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13481 .adc_nids = alc268_adc_nids_alt,
13482 .capsrc_nids = alc268_capsrc_nids,
13484 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13485 .channel_mode = alc268_modes,
13486 .input_mux = &alc268_capture_source,
13487 .unsol_event = alc_sku_unsol_event,
13488 .setup = alc268_toshiba_setup,
13489 .init_hook = alc_inithook,
13492 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13493 alc268_beep_mixer },
13494 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13495 alc268_acer_verbs },
13496 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13497 .dac_nids = alc268_dac_nids,
13498 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13499 .adc_nids = alc268_adc_nids_alt,
13500 .capsrc_nids = alc268_capsrc_nids,
13502 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13503 .channel_mode = alc268_modes,
13504 .input_mux = &alc268_acer_capture_source,
13505 .unsol_event = alc_sku_unsol_event,
13506 .setup = alc268_acer_setup,
13507 .init_hook = alc_inithook,
13509 [ALC268_ACER_DMIC] = {
13510 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13511 alc268_beep_mixer },
13512 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13513 alc268_acer_verbs },
13514 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13515 .dac_nids = alc268_dac_nids,
13516 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13517 .adc_nids = alc268_adc_nids_alt,
13518 .capsrc_nids = alc268_capsrc_nids,
13520 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13521 .channel_mode = alc268_modes,
13522 .input_mux = &alc268_acer_dmic_capture_source,
13523 .unsol_event = alc_sku_unsol_event,
13524 .setup = alc268_acer_setup,
13525 .init_hook = alc_inithook,
13527 [ALC268_ACER_ASPIRE_ONE] = {
13528 .mixers = { alc268_acer_aspire_one_mixer,
13530 alc268_capture_nosrc_mixer },
13531 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13532 alc268_acer_aspire_one_verbs },
13533 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13534 .dac_nids = alc268_dac_nids,
13535 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13536 .adc_nids = alc268_adc_nids_alt,
13537 .capsrc_nids = alc268_capsrc_nids,
13539 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13540 .channel_mode = alc268_modes,
13541 .unsol_event = alc_sku_unsol_event,
13542 .setup = alc268_acer_lc_setup,
13543 .init_hook = alc_inithook,
13546 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13547 alc268_capture_nosrc_mixer },
13548 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13549 alc268_dell_verbs },
13550 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13551 .dac_nids = alc268_dac_nids,
13552 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13553 .adc_nids = alc268_adc_nids_alt,
13554 .capsrc_nids = alc268_capsrc_nids,
13556 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13557 .channel_mode = alc268_modes,
13558 .unsol_event = alc_sku_unsol_event,
13559 .setup = alc268_dell_setup,
13560 .init_hook = alc_inithook,
13563 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13564 alc268_beep_mixer },
13565 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13566 alc268_toshiba_verbs },
13567 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13568 .dac_nids = alc268_dac_nids,
13569 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13570 .adc_nids = alc268_adc_nids_alt,
13571 .capsrc_nids = alc268_capsrc_nids,
13573 .dig_out_nid = ALC268_DIGOUT_NID,
13574 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13575 .channel_mode = alc268_modes,
13576 .input_mux = &alc268_capture_source,
13577 .unsol_event = alc_sku_unsol_event,
13578 .setup = alc268_toshiba_setup,
13579 .init_hook = alc_inithook,
13581 #ifdef CONFIG_SND_DEBUG
13583 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13584 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13585 alc268_volume_init_verbs,
13586 alc268_beep_init_verbs },
13587 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13588 .dac_nids = alc268_dac_nids,
13589 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13590 .adc_nids = alc268_adc_nids_alt,
13591 .capsrc_nids = alc268_capsrc_nids,
13593 .dig_out_nid = ALC268_DIGOUT_NID,
13594 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13595 .channel_mode = alc268_modes,
13596 .input_mux = &alc268_capture_source,
13601 static int patch_alc268(struct hda_codec *codec)
13603 struct alc_spec *spec;
13605 int i, has_beep, err;
13607 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13611 codec->spec = spec;
13613 /* ALC268 has no aa-loopback mixer */
13615 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13619 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13620 board_config = snd_hda_check_board_codec_sid_config(codec,
13621 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13623 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13624 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13626 board_config = ALC268_AUTO;
13629 if (board_config == ALC268_AUTO) {
13630 /* automatic parse from the BIOS config */
13631 err = alc268_parse_auto_config(codec);
13637 "hda_codec: Cannot set up configuration "
13638 "from BIOS. Using base mode...\n");
13639 board_config = ALC268_3ST;
13643 if (board_config != ALC268_AUTO)
13644 setup_preset(codec, &alc268_presets[board_config]);
13647 for (i = 0; i < spec->num_mixers; i++) {
13648 if (spec->mixers[i] == alc268_beep_mixer) {
13655 err = snd_hda_attach_beep_device(codec, 0x1);
13660 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13661 /* override the amp caps for beep generator */
13662 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
13663 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13664 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13665 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13666 (0 << AC_AMPCAP_MUTE_SHIFT));
13669 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
13670 alc_auto_fill_adc_caps(codec);
13671 alc_remove_invalid_adc_nids(codec);
13674 if (!spec->cap_mixer && !spec->no_analog)
13675 set_capture_mixer(codec);
13677 spec->vmaster_nid = 0x02;
13679 codec->patch_ops = alc_patch_ops;
13680 if (board_config == ALC268_AUTO)
13681 spec->init_hook = alc268_auto_init;
13682 spec->shutup = alc_eapd_shutup;
13684 alc_init_jacks(codec);
13690 * ALC269 channel source setting (2 channel)
13692 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13694 #define alc269_dac_nids alc260_dac_nids
13696 static const hda_nid_t alc269_adc_nids[1] = {
13701 static const hda_nid_t alc269_capsrc_nids[1] = {
13705 static const hda_nid_t alc269vb_adc_nids[1] = {
13710 static const hda_nid_t alc269vb_capsrc_nids[1] = {
13714 #define alc269_modes alc260_modes
13715 #define alc269_capture_source alc880_lg_lw_capture_source
13717 static const struct snd_kcontrol_new alc269_base_mixer[] = {
13718 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13719 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13720 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13721 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13722 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13723 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13724 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13725 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13726 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13727 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13729 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13733 static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13734 /* output mixer control */
13735 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13738 .name = "Master Playback Switch",
13739 .subdevice = HDA_SUBDEV_AMP_FLAG,
13740 .info = snd_hda_mixer_amp_switch_info,
13741 .get = snd_hda_mixer_amp_switch_get,
13742 .put = alc268_acer_master_sw_put,
13743 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13747 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13748 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13749 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13750 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13754 static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13755 /* output mixer control */
13756 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13758 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13759 .name = "Master Playback Switch",
13760 .subdevice = HDA_SUBDEV_AMP_FLAG,
13761 .info = snd_hda_mixer_amp_switch_info,
13762 .get = snd_hda_mixer_amp_switch_get,
13763 .put = alc268_acer_master_sw_put,
13764 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13767 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13768 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13769 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13770 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13771 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13772 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13773 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13774 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
13778 static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
13779 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13780 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13781 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13782 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13786 static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13787 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13788 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13789 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13790 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13794 static const struct snd_kcontrol_new alc269_asus_mixer[] = {
13795 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13796 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
13800 /* capture mixer elements */
13801 static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13802 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13803 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13804 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13805 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13809 static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13810 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13811 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13812 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13816 static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13817 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13818 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13819 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13820 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13824 static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13825 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13826 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13827 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13832 #define alc269_fujitsu_mixer alc269_laptop_mixer
13834 static const struct hda_verb alc269_quanta_fl1_verbs[] = {
13835 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13836 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13837 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13838 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13839 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13840 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13844 static const struct hda_verb alc269_lifebook_verbs[] = {
13845 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13846 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13847 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13848 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13849 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13850 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13851 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13852 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13853 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13854 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13858 /* toggle speaker-output according to the hp-jack state */
13859 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13861 alc_hp_automute(codec);
13863 snd_hda_codec_write(codec, 0x20, 0,
13864 AC_VERB_SET_COEF_INDEX, 0x0c);
13865 snd_hda_codec_write(codec, 0x20, 0,
13866 AC_VERB_SET_PROC_COEF, 0x680);
13868 snd_hda_codec_write(codec, 0x20, 0,
13869 AC_VERB_SET_COEF_INDEX, 0x0c);
13870 snd_hda_codec_write(codec, 0x20, 0,
13871 AC_VERB_SET_PROC_COEF, 0x480);
13874 #define alc269_lifebook_speaker_automute \
13875 alc269_quanta_fl1_speaker_automute
13877 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13879 unsigned int present_laptop;
13880 unsigned int present_dock;
13882 present_laptop = snd_hda_jack_detect(codec, 0x18);
13883 present_dock = snd_hda_jack_detect(codec, 0x1b);
13885 /* Laptop mic port overrides dock mic port, design decision */
13887 snd_hda_codec_write(codec, 0x23, 0,
13888 AC_VERB_SET_CONNECT_SEL, 0x3);
13889 if (present_laptop)
13890 snd_hda_codec_write(codec, 0x23, 0,
13891 AC_VERB_SET_CONNECT_SEL, 0x0);
13892 if (!present_dock && !present_laptop)
13893 snd_hda_codec_write(codec, 0x23, 0,
13894 AC_VERB_SET_CONNECT_SEL, 0x1);
13897 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13900 switch (res >> 26) {
13901 case ALC880_HP_EVENT:
13902 alc269_quanta_fl1_speaker_automute(codec);
13904 case ALC880_MIC_EVENT:
13905 alc_mic_automute(codec);
13910 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13913 if ((res >> 26) == ALC880_HP_EVENT)
13914 alc269_lifebook_speaker_automute(codec);
13915 if ((res >> 26) == ALC880_MIC_EVENT)
13916 alc269_lifebook_mic_autoswitch(codec);
13919 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13921 struct alc_spec *spec = codec->spec;
13922 spec->autocfg.hp_pins[0] = 0x15;
13923 spec->autocfg.speaker_pins[0] = 0x14;
13924 spec->automute_mixer_nid[0] = 0x0c;
13925 spec->automute = 1;
13926 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13927 spec->ext_mic.pin = 0x18;
13928 spec->ext_mic.mux_idx = 0;
13929 spec->int_mic.pin = 0x19;
13930 spec->int_mic.mux_idx = 1;
13931 spec->auto_mic = 1;
13934 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13936 alc269_quanta_fl1_speaker_automute(codec);
13937 alc_mic_automute(codec);
13940 static void alc269_lifebook_setup(struct hda_codec *codec)
13942 struct alc_spec *spec = codec->spec;
13943 spec->autocfg.hp_pins[0] = 0x15;
13944 spec->autocfg.hp_pins[1] = 0x1a;
13945 spec->autocfg.speaker_pins[0] = 0x14;
13946 spec->automute_mixer_nid[0] = 0x0c;
13947 spec->automute = 1;
13948 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13951 static void alc269_lifebook_init_hook(struct hda_codec *codec)
13953 alc269_lifebook_speaker_automute(codec);
13954 alc269_lifebook_mic_autoswitch(codec);
13957 static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13958 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13959 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13960 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13961 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13962 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13963 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13964 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13968 static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
13969 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13970 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13971 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13972 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13973 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13974 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13978 static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13979 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13980 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13981 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13982 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13983 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13984 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13985 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13989 static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13990 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13991 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13992 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13993 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13994 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13995 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13996 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14000 static const struct hda_verb alc271_acer_dmic_verbs[] = {
14001 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14002 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14003 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14004 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14005 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14006 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14007 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14008 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14010 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14014 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14016 struct alc_spec *spec = codec->spec;
14017 spec->autocfg.hp_pins[0] = 0x15;
14018 spec->autocfg.speaker_pins[0] = 0x14;
14019 spec->automute_mixer_nid[0] = 0x0c;
14020 spec->automute = 1;
14021 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14022 spec->ext_mic.pin = 0x18;
14023 spec->ext_mic.mux_idx = 0;
14024 spec->int_mic.pin = 0x19;
14025 spec->int_mic.mux_idx = 1;
14026 spec->auto_mic = 1;
14029 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14031 struct alc_spec *spec = codec->spec;
14032 spec->autocfg.hp_pins[0] = 0x15;
14033 spec->autocfg.speaker_pins[0] = 0x14;
14034 spec->automute_mixer_nid[0] = 0x0c;
14035 spec->automute = 1;
14036 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14037 spec->ext_mic.pin = 0x18;
14038 spec->ext_mic.mux_idx = 0;
14039 spec->int_mic.pin = 0x12;
14040 spec->int_mic.mux_idx = 5;
14041 spec->auto_mic = 1;
14044 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14046 struct alc_spec *spec = codec->spec;
14047 spec->autocfg.hp_pins[0] = 0x21;
14048 spec->autocfg.speaker_pins[0] = 0x14;
14049 spec->automute_mixer_nid[0] = 0x0c;
14050 spec->automute = 1;
14051 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14052 spec->ext_mic.pin = 0x18;
14053 spec->ext_mic.mux_idx = 0;
14054 spec->int_mic.pin = 0x19;
14055 spec->int_mic.mux_idx = 1;
14056 spec->auto_mic = 1;
14059 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14061 struct alc_spec *spec = codec->spec;
14062 spec->autocfg.hp_pins[0] = 0x21;
14063 spec->autocfg.speaker_pins[0] = 0x14;
14064 spec->automute_mixer_nid[0] = 0x0c;
14065 spec->automute = 1;
14066 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14067 spec->ext_mic.pin = 0x18;
14068 spec->ext_mic.mux_idx = 0;
14069 spec->int_mic.pin = 0x12;
14070 spec->int_mic.mux_idx = 6;
14071 spec->auto_mic = 1;
14075 * generic initialization of ADC, input mixers and output mixers
14077 static const struct hda_verb alc269_init_verbs[] = {
14079 * Unmute ADC0 and set the default input to mic-in
14081 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14084 * Set up output mixers (0x02 - 0x03)
14086 /* set vol=0 to output mixers */
14087 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14088 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14090 /* set up input amps for analog loopback */
14091 /* Amp Indices: DAC = 0, mixer = 1 */
14092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14094 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14095 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14096 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14097 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14101 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14102 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14103 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14104 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14105 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14107 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14108 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14110 /* FIXME: use Mux-type input source selection */
14111 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14112 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14113 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14116 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14120 static const struct hda_verb alc269vb_init_verbs[] = {
14122 * Unmute ADC0 and set the default input to mic-in
14124 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14127 * Set up output mixers (0x02 - 0x03)
14129 /* set vol=0 to output mixers */
14130 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14131 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14133 /* set up input amps for analog loopback */
14134 /* Amp Indices: DAC = 0, mixer = 1 */
14135 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14137 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14138 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14139 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14140 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14142 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14143 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14144 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14145 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14146 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14147 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14150 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14151 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14153 /* FIXME: use Mux-type input source selection */
14154 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14155 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14156 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14159 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14163 #define alc269_auto_create_multi_out_ctls \
14164 alc268_auto_create_multi_out_ctls
14166 #ifdef CONFIG_SND_HDA_POWER_SAVE
14167 #define alc269_loopbacks alc880_loopbacks
14170 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14174 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14175 /* NID is set in alc_build_pcms */
14177 .open = alc_playback_pcm_open,
14178 .prepare = alc_playback_pcm_prepare,
14179 .cleanup = alc_playback_pcm_cleanup
14183 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14187 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14188 /* NID is set in alc_build_pcms */
14191 #ifdef CONFIG_SND_HDA_POWER_SAVE
14192 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14194 switch (codec->subsystem_id) {
14201 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14203 /* update mute-LED according to the speaker mute state */
14204 if (nid == 0x01 || nid == 0x14) {
14206 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14211 /* mic2 vref pin is used for mute LED control */
14212 snd_hda_codec_update_cache(codec, 0x19, 0,
14213 AC_VERB_SET_PIN_WIDGET_CONTROL,
14216 return alc_check_power_status(codec, nid);
14218 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14220 static int alc275_setup_dual_adc(struct hda_codec *codec)
14222 struct alc_spec *spec = codec->spec;
14224 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14226 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14227 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14228 if (spec->ext_mic.pin <= 0x12) {
14229 spec->private_adc_nids[0] = 0x08;
14230 spec->private_adc_nids[1] = 0x11;
14231 spec->private_capsrc_nids[0] = 0x23;
14232 spec->private_capsrc_nids[1] = 0x22;
14234 spec->private_adc_nids[0] = 0x11;
14235 spec->private_adc_nids[1] = 0x08;
14236 spec->private_capsrc_nids[0] = 0x22;
14237 spec->private_capsrc_nids[1] = 0x23;
14239 spec->adc_nids = spec->private_adc_nids;
14240 spec->capsrc_nids = spec->private_capsrc_nids;
14241 spec->num_adc_nids = 2;
14242 spec->dual_adc_switch = 1;
14243 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14244 spec->adc_nids[0], spec->adc_nids[1]);
14250 /* different alc269-variants */
14252 ALC269_TYPE_ALC269VA,
14253 ALC269_TYPE_ALC269VB,
14254 ALC269_TYPE_ALC269VC,
14258 * BIOS auto configuration
14260 static int alc269_parse_auto_config(struct hda_codec *codec)
14262 struct alc_spec *spec = codec->spec;
14264 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14266 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14271 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14274 err = alc_auto_create_input_ctls(codec);
14278 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14280 alc_auto_parse_digital(codec);
14282 if (spec->kctls.list)
14283 add_mixer(spec, spec->kctls.list);
14285 if (spec->codec_variant != ALC269_TYPE_ALC269VA)
14286 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14288 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14290 spec->num_mux_defs = 1;
14291 spec->input_mux = &spec->private_imux[0];
14293 alc275_setup_dual_adc(codec);
14294 if (!spec->dual_adc_switch)
14295 alc_remove_invalid_adc_nids(codec);
14297 err = alc_auto_add_mic_boost(codec);
14301 if (!spec->cap_mixer && !spec->no_analog)
14302 set_capture_mixer(codec);
14307 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14308 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14311 /* init callback for auto-configuration model -- overriding the default init */
14312 static void alc269_auto_init(struct hda_codec *codec)
14314 struct alc_spec *spec = codec->spec;
14315 alc269_auto_init_multi_out(codec);
14316 alc269_auto_init_hp_out(codec);
14317 alc_auto_init_analog_input(codec);
14318 alc_auto_init_input_src(codec);
14319 alc_auto_init_digital(codec);
14320 if (spec->unsol_event)
14321 alc_inithook(codec);
14324 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14326 int val = alc_read_coef_idx(codec, 0x04);
14331 alc_write_coef_idx(codec, 0x04, val);
14334 static void alc269_shutup(struct hda_codec *codec)
14336 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14337 alc269_toggle_power_output(codec, 0);
14338 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14339 alc269_toggle_power_output(codec, 0);
14344 #ifdef SND_HDA_NEEDS_RESUME
14345 static int alc269_resume(struct hda_codec *codec)
14347 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14348 alc269_toggle_power_output(codec, 0);
14352 codec->patch_ops.init(codec);
14354 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14355 alc269_toggle_power_output(codec, 1);
14359 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14360 alc269_toggle_power_output(codec, 1);
14362 snd_hda_codec_resume_amp(codec);
14363 snd_hda_codec_resume_cache(codec);
14364 hda_call_check_power_status(codec, 0x01);
14367 #endif /* SND_HDA_NEEDS_RESUME */
14369 static void alc269_fixup_hweq(struct hda_codec *codec,
14370 const struct alc_fixup *fix, int action)
14374 if (action != ALC_FIXUP_ACT_INIT)
14376 coef = alc_read_coef_idx(codec, 0x1e);
14377 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14380 static void alc271_fixup_dmic(struct hda_codec *codec,
14381 const struct alc_fixup *fix, int action)
14383 static const struct hda_verb verbs[] = {
14384 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14385 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14390 if (strcmp(codec->chip_name, "ALC271X"))
14392 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14393 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14394 snd_hda_sequence_write(codec, verbs);
14398 ALC269_FIXUP_SONY_VAIO,
14399 ALC275_FIXUP_SONY_VAIO_GPIO2,
14400 ALC269_FIXUP_DELL_M101Z,
14401 ALC269_FIXUP_SKU_IGNORE,
14402 ALC269_FIXUP_ASUS_G73JW,
14403 ALC269_FIXUP_LENOVO_EAPD,
14404 ALC275_FIXUP_SONY_HWEQ,
14408 static const struct alc_fixup alc269_fixups[] = {
14409 [ALC269_FIXUP_SONY_VAIO] = {
14410 .type = ALC_FIXUP_VERBS,
14411 .v.verbs = (const struct hda_verb[]) {
14412 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14416 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14417 .type = ALC_FIXUP_VERBS,
14418 .v.verbs = (const struct hda_verb[]) {
14419 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14420 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14421 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14425 .chain_id = ALC269_FIXUP_SONY_VAIO
14427 [ALC269_FIXUP_DELL_M101Z] = {
14428 .type = ALC_FIXUP_VERBS,
14429 .v.verbs = (const struct hda_verb[]) {
14430 /* Enables internal speaker */
14431 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14432 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14436 [ALC269_FIXUP_SKU_IGNORE] = {
14437 .type = ALC_FIXUP_SKU,
14438 .v.sku = ALC_FIXUP_SKU_IGNORE,
14440 [ALC269_FIXUP_ASUS_G73JW] = {
14441 .type = ALC_FIXUP_PINS,
14442 .v.pins = (const struct alc_pincfg[]) {
14443 { 0x17, 0x99130111 }, /* subwoofer */
14447 [ALC269_FIXUP_LENOVO_EAPD] = {
14448 .type = ALC_FIXUP_VERBS,
14449 .v.verbs = (const struct hda_verb[]) {
14450 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14454 [ALC275_FIXUP_SONY_HWEQ] = {
14455 .type = ALC_FIXUP_FUNC,
14456 .v.func = alc269_fixup_hweq,
14458 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14460 [ALC271_FIXUP_DMIC] = {
14461 .type = ALC_FIXUP_FUNC,
14462 .v.func = alc271_fixup_dmic,
14466 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14467 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14468 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14469 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14470 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14471 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14472 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14473 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14474 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14475 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14476 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14477 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14478 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14479 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14485 * configuration and preset
14487 static const char * const alc269_models[ALC269_MODEL_LAST] = {
14488 [ALC269_BASIC] = "basic",
14489 [ALC269_QUANTA_FL1] = "quanta",
14490 [ALC269_AMIC] = "laptop-amic",
14491 [ALC269_DMIC] = "laptop-dmic",
14492 [ALC269_FUJITSU] = "fujitsu",
14493 [ALC269_LIFEBOOK] = "lifebook",
14494 [ALC269_AUTO] = "auto",
14497 static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14498 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14499 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14500 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14502 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14503 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14504 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14505 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14506 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14507 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14508 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14509 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14510 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14511 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
14512 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14513 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14514 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14515 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14516 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14517 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14518 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14519 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14520 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14521 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14522 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14523 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14524 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14525 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14526 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14527 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14528 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14529 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14530 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14531 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14532 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14533 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14534 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14535 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14536 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14537 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14538 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14540 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14542 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14543 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14544 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14545 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14546 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14547 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14548 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14549 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14550 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14551 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14555 static const struct alc_config_preset alc269_presets[] = {
14557 .mixers = { alc269_base_mixer },
14558 .init_verbs = { alc269_init_verbs },
14559 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14560 .dac_nids = alc269_dac_nids,
14562 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14563 .channel_mode = alc269_modes,
14564 .input_mux = &alc269_capture_source,
14566 [ALC269_QUANTA_FL1] = {
14567 .mixers = { alc269_quanta_fl1_mixer },
14568 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14569 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14570 .dac_nids = alc269_dac_nids,
14572 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14573 .channel_mode = alc269_modes,
14574 .input_mux = &alc269_capture_source,
14575 .unsol_event = alc269_quanta_fl1_unsol_event,
14576 .setup = alc269_quanta_fl1_setup,
14577 .init_hook = alc269_quanta_fl1_init_hook,
14580 .mixers = { alc269_laptop_mixer },
14581 .cap_mixer = alc269_laptop_analog_capture_mixer,
14582 .init_verbs = { alc269_init_verbs,
14583 alc269_laptop_amic_init_verbs },
14584 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14585 .dac_nids = alc269_dac_nids,
14587 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14588 .channel_mode = alc269_modes,
14589 .unsol_event = alc_sku_unsol_event,
14590 .setup = alc269_laptop_amic_setup,
14591 .init_hook = alc_inithook,
14594 .mixers = { alc269_laptop_mixer },
14595 .cap_mixer = alc269_laptop_digital_capture_mixer,
14596 .init_verbs = { alc269_init_verbs,
14597 alc269_laptop_dmic_init_verbs },
14598 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14599 .dac_nids = alc269_dac_nids,
14601 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14602 .channel_mode = alc269_modes,
14603 .unsol_event = alc_sku_unsol_event,
14604 .setup = alc269_laptop_dmic_setup,
14605 .init_hook = alc_inithook,
14607 [ALC269VB_AMIC] = {
14608 .mixers = { alc269vb_laptop_mixer },
14609 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14610 .init_verbs = { alc269vb_init_verbs,
14611 alc269vb_laptop_amic_init_verbs },
14612 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14613 .dac_nids = alc269_dac_nids,
14615 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14616 .channel_mode = alc269_modes,
14617 .unsol_event = alc_sku_unsol_event,
14618 .setup = alc269vb_laptop_amic_setup,
14619 .init_hook = alc_inithook,
14621 [ALC269VB_DMIC] = {
14622 .mixers = { alc269vb_laptop_mixer },
14623 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14624 .init_verbs = { alc269vb_init_verbs,
14625 alc269vb_laptop_dmic_init_verbs },
14626 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14627 .dac_nids = alc269_dac_nids,
14629 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14630 .channel_mode = alc269_modes,
14631 .unsol_event = alc_sku_unsol_event,
14632 .setup = alc269vb_laptop_dmic_setup,
14633 .init_hook = alc_inithook,
14635 [ALC269_FUJITSU] = {
14636 .mixers = { alc269_fujitsu_mixer },
14637 .cap_mixer = alc269_laptop_digital_capture_mixer,
14638 .init_verbs = { alc269_init_verbs,
14639 alc269_laptop_dmic_init_verbs },
14640 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14641 .dac_nids = alc269_dac_nids,
14643 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14644 .channel_mode = alc269_modes,
14645 .unsol_event = alc_sku_unsol_event,
14646 .setup = alc269_laptop_dmic_setup,
14647 .init_hook = alc_inithook,
14649 [ALC269_LIFEBOOK] = {
14650 .mixers = { alc269_lifebook_mixer },
14651 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14652 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14653 .dac_nids = alc269_dac_nids,
14655 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14656 .channel_mode = alc269_modes,
14657 .input_mux = &alc269_capture_source,
14658 .unsol_event = alc269_lifebook_unsol_event,
14659 .setup = alc269_lifebook_setup,
14660 .init_hook = alc269_lifebook_init_hook,
14663 .mixers = { alc269_asus_mixer },
14664 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14665 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14666 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14667 .dac_nids = alc269_dac_nids,
14668 .adc_nids = alc262_dmic_adc_nids,
14669 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14670 .capsrc_nids = alc262_dmic_capsrc_nids,
14671 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14672 .channel_mode = alc269_modes,
14673 .input_mux = &alc269_capture_source,
14674 .dig_out_nid = ALC880_DIGOUT_NID,
14675 .unsol_event = alc_sku_unsol_event,
14676 .setup = alc269vb_laptop_dmic_setup,
14677 .init_hook = alc_inithook,
14681 static int alc269_fill_coef(struct hda_codec *codec)
14685 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
14686 alc_write_coef_idx(codec, 0xf, 0x960b);
14687 alc_write_coef_idx(codec, 0xe, 0x8817);
14690 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
14691 alc_write_coef_idx(codec, 0xf, 0x960b);
14692 alc_write_coef_idx(codec, 0xe, 0x8814);
14695 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14696 val = alc_read_coef_idx(codec, 0x04);
14697 /* Power up output pin */
14698 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14701 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14702 val = alc_read_coef_idx(codec, 0xd);
14703 if ((val & 0x0c00) >> 10 != 0x1) {
14704 /* Capless ramp up clock control */
14705 alc_write_coef_idx(codec, 0xd, val | (1<<10));
14707 val = alc_read_coef_idx(codec, 0x17);
14708 if ((val & 0x01c0) >> 6 != 0x4) {
14709 /* Class D power on reset */
14710 alc_write_coef_idx(codec, 0x17, val | (1<<7));
14714 val = alc_read_coef_idx(codec, 0xd); /* Class D */
14715 alc_write_coef_idx(codec, 0xd, val | (1<<14));
14717 val = alc_read_coef_idx(codec, 0x4); /* HP */
14718 alc_write_coef_idx(codec, 0x4, val | (1<<11));
14723 static int patch_alc269(struct hda_codec *codec)
14725 struct alc_spec *spec;
14726 int board_config, coef;
14729 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14733 codec->spec = spec;
14735 spec->mixer_nid = 0x0b;
14737 alc_auto_parse_customize_define(codec);
14739 if (codec->vendor_id == 0x10ec0269) {
14740 spec->codec_variant = ALC269_TYPE_ALC269VA;
14741 coef = alc_read_coef_idx(codec, 0);
14742 if ((coef & 0x00f0) == 0x0010) {
14743 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14744 spec->cdefine.platform_type == 1) {
14745 alc_codec_rename(codec, "ALC271X");
14746 } else if ((coef & 0xf000) == 0x2000) {
14747 alc_codec_rename(codec, "ALC259");
14748 } else if ((coef & 0xf000) == 0x3000) {
14749 alc_codec_rename(codec, "ALC258");
14750 } else if ((coef & 0xfff0) == 0x3010) {
14751 alc_codec_rename(codec, "ALC277");
14753 alc_codec_rename(codec, "ALC269VB");
14755 spec->codec_variant = ALC269_TYPE_ALC269VB;
14756 } else if ((coef & 0x00f0) == 0x0020) {
14757 if (coef == 0xa023)
14758 alc_codec_rename(codec, "ALC259");
14759 else if (coef == 0x6023)
14760 alc_codec_rename(codec, "ALC281X");
14761 else if (codec->bus->pci->subsystem_vendor == 0x17aa &&
14762 codec->bus->pci->subsystem_device == 0x21f3)
14763 alc_codec_rename(codec, "ALC3202");
14765 alc_codec_rename(codec, "ALC269VC");
14766 spec->codec_variant = ALC269_TYPE_ALC269VC;
14768 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14769 alc269_fill_coef(codec);
14772 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14776 if (board_config < 0) {
14777 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14779 board_config = ALC269_AUTO;
14782 if (board_config == ALC269_AUTO) {
14783 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
14784 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
14787 if (board_config == ALC269_AUTO) {
14788 /* automatic parse from the BIOS config */
14789 err = alc269_parse_auto_config(codec);
14795 "hda_codec: Cannot set up configuration "
14796 "from BIOS. Using base mode...\n");
14797 board_config = ALC269_BASIC;
14801 if (has_cdefine_beep(codec)) {
14802 err = snd_hda_attach_beep_device(codec, 0x1);
14809 if (board_config != ALC269_AUTO)
14810 setup_preset(codec, &alc269_presets[board_config]);
14812 if (board_config == ALC269_QUANTA_FL1) {
14813 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14814 * fix the sample rate of analog I/O to 44.1kHz
14816 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14817 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14820 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14821 alc_auto_fill_adc_caps(codec);
14822 alc_remove_invalid_adc_nids(codec);
14825 if (!spec->cap_mixer)
14826 set_capture_mixer(codec);
14827 if (has_cdefine_beep(codec))
14828 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14830 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
14832 spec->vmaster_nid = 0x02;
14834 codec->patch_ops = alc_patch_ops;
14835 #ifdef SND_HDA_NEEDS_RESUME
14836 codec->patch_ops.resume = alc269_resume;
14838 if (board_config == ALC269_AUTO)
14839 spec->init_hook = alc269_auto_init;
14840 spec->shutup = alc269_shutup;
14842 alc_init_jacks(codec);
14843 #ifdef CONFIG_SND_HDA_POWER_SAVE
14844 if (!spec->loopback.amplist)
14845 spec->loopback.amplist = alc269_loopbacks;
14846 if (alc269_mic2_for_mute_led(codec))
14847 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
14854 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14858 * set the path ways for 2 channel output
14859 * need to set the codec line out and mic 1 pin widgets to inputs
14861 static const struct hda_verb alc861_threestack_ch2_init[] = {
14862 /* set pin widget 1Ah (line in) for input */
14863 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14864 /* set pin widget 18h (mic1/2) for input, for mic also enable
14867 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14869 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14871 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14872 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14878 * need to set the codec line out and mic 1 pin widgets to outputs
14880 static const struct hda_verb alc861_threestack_ch6_init[] = {
14881 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14882 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14883 /* set pin widget 18h (mic1) for output (CLFE)*/
14884 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14886 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14887 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14889 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14891 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14892 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14897 static const struct hda_channel_mode alc861_threestack_modes[2] = {
14898 { 2, alc861_threestack_ch2_init },
14899 { 6, alc861_threestack_ch6_init },
14901 /* Set mic1 as input and unmute the mixer */
14902 static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14903 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14904 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14907 /* Set mic1 as output and mute mixer */
14908 static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14909 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14910 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14914 static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14915 { 2, alc861_uniwill_m31_ch2_init },
14916 { 4, alc861_uniwill_m31_ch4_init },
14919 /* Set mic1 and line-in as input and unmute the mixer */
14920 static const struct hda_verb alc861_asus_ch2_init[] = {
14921 /* set pin widget 1Ah (line in) for input */
14922 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14923 /* set pin widget 18h (mic1/2) for input, for mic also enable
14926 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14928 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14930 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14931 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14935 /* Set mic1 nad line-in as output and mute mixer */
14936 static const struct hda_verb alc861_asus_ch6_init[] = {
14937 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14938 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14939 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14940 /* set pin widget 18h (mic1) for output (CLFE)*/
14941 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14942 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14943 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14944 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14946 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14948 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14949 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14954 static const struct hda_channel_mode alc861_asus_modes[2] = {
14955 { 2, alc861_asus_ch2_init },
14956 { 6, alc861_asus_ch6_init },
14961 static const struct snd_kcontrol_new alc861_base_mixer[] = {
14962 /* output mixer control */
14963 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14964 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14965 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14966 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14967 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14969 /*Input mixer control */
14970 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14971 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14972 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14973 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14974 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14975 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14977 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14978 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14979 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14984 static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
14985 /* output mixer control */
14986 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14987 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14988 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14989 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14990 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14992 /* Input mixer control */
14993 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14994 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14995 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14996 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14997 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14998 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14999 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15000 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15001 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15002 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15006 .name = "Channel Mode",
15007 .info = alc_ch_mode_info,
15008 .get = alc_ch_mode_get,
15009 .put = alc_ch_mode_put,
15010 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15015 static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15016 /* output mixer control */
15017 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15019 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15024 static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15025 /* output mixer control */
15026 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15027 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15028 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15029 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15030 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15032 /* Input mixer control */
15033 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15034 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15035 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15036 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15037 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15038 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15039 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15040 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15041 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15042 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15045 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15046 .name = "Channel Mode",
15047 .info = alc_ch_mode_info,
15048 .get = alc_ch_mode_get,
15049 .put = alc_ch_mode_put,
15050 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15055 static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15056 /* output mixer control */
15057 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15058 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15059 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15060 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15061 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15063 /* Input mixer control */
15064 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15065 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15066 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15067 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15068 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15069 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15070 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15071 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15072 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15073 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15076 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15077 .name = "Channel Mode",
15078 .info = alc_ch_mode_info,
15079 .get = alc_ch_mode_get,
15080 .put = alc_ch_mode_put,
15081 .private_value = ARRAY_SIZE(alc861_asus_modes),
15086 /* additional mixer */
15087 static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15088 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15089 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15094 * generic initialization of ADC, input mixers and output mixers
15096 static const struct hda_verb alc861_base_init_verbs[] = {
15098 * Unmute ADC0 and set the default input to mic-in
15100 /* port-A for surround (rear panel) */
15101 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15102 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15103 /* port-B for mic-in (rear panel) with vref */
15104 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15105 /* port-C for line-in (rear panel) */
15106 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15107 /* port-D for Front */
15108 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15109 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15110 /* port-E for HP out (front panel) */
15111 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15112 /* route front PCM to HP */
15113 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15114 /* port-F for mic-in (front panel) with vref */
15115 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15116 /* port-G for CLFE (rear panel) */
15117 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15118 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15119 /* port-H for side (rear panel) */
15120 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15121 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15123 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15124 /* route front mic to ADC1*/
15125 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15126 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15128 /* Unmute DAC0~3 & spdif out*/
15129 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15130 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15131 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15132 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15133 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15135 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15136 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15137 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15138 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15139 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15141 /* Unmute Stereo Mixer 15 */
15142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15143 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15144 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15145 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15147 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15148 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15149 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15150 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15151 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15152 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15153 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15154 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15155 /* hp used DAC 3 (Front) */
15156 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15157 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15162 static const struct hda_verb alc861_threestack_init_verbs[] = {
15164 * Unmute ADC0 and set the default input to mic-in
15166 /* port-A for surround (rear panel) */
15167 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15168 /* port-B for mic-in (rear panel) with vref */
15169 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15170 /* port-C for line-in (rear panel) */
15171 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15172 /* port-D for Front */
15173 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15174 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15175 /* port-E for HP out (front panel) */
15176 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15177 /* route front PCM to HP */
15178 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15179 /* port-F for mic-in (front panel) with vref */
15180 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15181 /* port-G for CLFE (rear panel) */
15182 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15183 /* port-H for side (rear panel) */
15184 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15186 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15187 /* route front mic to ADC1*/
15188 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15189 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15190 /* Unmute DAC0~3 & spdif out*/
15191 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15192 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15193 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15194 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15197 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15198 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15199 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15200 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15201 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15203 /* Unmute Stereo Mixer 15 */
15204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15206 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15209 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15210 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15211 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15212 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15214 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15215 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15216 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15217 /* hp used DAC 3 (Front) */
15218 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15223 static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15225 * Unmute ADC0 and set the default input to mic-in
15227 /* port-A for surround (rear panel) */
15228 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15229 /* port-B for mic-in (rear panel) with vref */
15230 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15231 /* port-C for line-in (rear panel) */
15232 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15233 /* port-D for Front */
15234 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15235 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15236 /* port-E for HP out (front panel) */
15237 /* this has to be set to VREF80 */
15238 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15239 /* route front PCM to HP */
15240 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15241 /* port-F for mic-in (front panel) with vref */
15242 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15243 /* port-G for CLFE (rear panel) */
15244 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15245 /* port-H for side (rear panel) */
15246 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15248 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15249 /* route front mic to ADC1*/
15250 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15251 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15252 /* Unmute DAC0~3 & spdif out*/
15253 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15254 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15255 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15256 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15259 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15260 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15261 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15262 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15263 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15265 /* Unmute Stereo Mixer 15 */
15266 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15267 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15268 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15271 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15272 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15273 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15274 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15275 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15276 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15277 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15278 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15279 /* hp used DAC 3 (Front) */
15280 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15281 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15285 static const struct hda_verb alc861_asus_init_verbs[] = {
15287 * Unmute ADC0 and set the default input to mic-in
15289 /* port-A for surround (rear panel)
15290 * according to codec#0 this is the HP jack
15292 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15293 /* route front PCM to HP */
15294 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15295 /* port-B for mic-in (rear panel) with vref */
15296 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15297 /* port-C for line-in (rear panel) */
15298 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15299 /* port-D for Front */
15300 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15301 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15302 /* port-E for HP out (front panel) */
15303 /* this has to be set to VREF80 */
15304 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15305 /* route front PCM to HP */
15306 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15307 /* port-F for mic-in (front panel) with vref */
15308 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15309 /* port-G for CLFE (rear panel) */
15310 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15311 /* port-H for side (rear panel) */
15312 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15314 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15315 /* route front mic to ADC1*/
15316 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15318 /* Unmute DAC0~3 & spdif out*/
15319 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15320 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15321 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15322 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15324 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15325 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15326 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15327 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15328 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15330 /* Unmute Stereo Mixer 15 */
15331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15332 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15333 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15334 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15336 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15337 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15338 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15341 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15343 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15344 /* hp used DAC 3 (Front) */
15345 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15346 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15350 /* additional init verbs for ASUS laptops */
15351 static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15352 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15353 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15357 static const struct hda_verb alc861_toshiba_init_verbs[] = {
15358 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15363 /* toggle speaker-output according to the hp-jack state */
15364 static void alc861_toshiba_automute(struct hda_codec *codec)
15366 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15368 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15369 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15370 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15371 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15374 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15377 if ((res >> 26) == ALC880_HP_EVENT)
15378 alc861_toshiba_automute(codec);
15381 #define ALC861_DIGOUT_NID 0x07
15383 static const struct hda_channel_mode alc861_8ch_modes[1] = {
15387 static const hda_nid_t alc861_dac_nids[4] = {
15388 /* front, surround, clfe, side */
15389 0x03, 0x06, 0x05, 0x04
15392 static const hda_nid_t alc660_dac_nids[3] = {
15393 /* front, clfe, surround */
15397 static const hda_nid_t alc861_adc_nids[1] = {
15402 static const struct hda_input_mux alc861_capture_source = {
15406 { "Front Mic", 0x3 },
15413 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15415 struct alc_spec *spec = codec->spec;
15416 hda_nid_t mix, srcs[5];
15419 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15421 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15424 for (i = 0; i < num; i++) {
15426 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15427 if (type != AC_WID_AUD_OUT)
15429 if (!found_in_nid_list(srcs[i], spec->multiout.dac_nids,
15430 spec->multiout.num_dacs))
15436 /* fill in the dac_nids table from the parsed pin configuration */
15437 static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
15439 struct alc_spec *spec = codec->spec;
15440 const struct auto_pin_cfg *cfg = &spec->autocfg;
15442 hda_nid_t nid, dac;
15444 spec->multiout.dac_nids = spec->private_dac_nids;
15445 for (i = 0; i < cfg->line_outs; i++) {
15446 nid = cfg->line_out_pins[i];
15447 dac = alc861_look_for_dac(codec, nid);
15450 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
15455 static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15456 hda_nid_t nid, int idx, unsigned int chs)
15458 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
15459 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15462 #define alc861_create_out_sw(codec, pfx, nid, chs) \
15463 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15465 /* add playback controls from the parsed DAC table */
15466 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15467 const struct auto_pin_cfg *cfg)
15469 struct alc_spec *spec = codec->spec;
15471 int i, err, noutputs;
15473 noutputs = cfg->line_outs;
15474 if (spec->multi_ios > 0)
15475 noutputs += spec->multi_ios;
15477 for (i = 0; i < noutputs; i++) {
15480 nid = spec->multiout.dac_nids[i];
15483 name = alc_get_line_out_pfx(spec, i, true, &index);
15486 err = alc861_create_out_sw(codec, "Center", nid, 1);
15489 err = alc861_create_out_sw(codec, "LFE", nid, 2);
15493 err = __alc861_create_out_sw(codec, name, nid, index, 3);
15501 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
15503 struct alc_spec *spec = codec->spec;
15510 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
15511 nid = alc861_look_for_dac(codec, pin);
15513 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15516 spec->multiout.hp_nid = nid;
15522 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15524 int pin_type, hda_nid_t dac)
15526 hda_nid_t mix, srcs[5];
15529 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15531 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15533 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15535 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15538 for (i = 0; i < num; i++) {
15540 if (srcs[i] == dac || srcs[i] == 0x15)
15541 mute = AMP_IN_UNMUTE(i);
15543 mute = AMP_IN_MUTE(i);
15544 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15549 static void alc861_auto_init_multi_out(struct hda_codec *codec)
15551 struct alc_spec *spec = codec->spec;
15554 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
15555 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15556 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15558 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
15559 spec->multiout.dac_nids[i]);
15563 static void alc861_auto_init_hp_out(struct hda_codec *codec)
15565 struct alc_spec *spec = codec->spec;
15567 if (spec->autocfg.hp_outs)
15568 alc861_auto_set_output_and_unmute(codec,
15569 spec->autocfg.hp_pins[0],
15571 spec->multiout.hp_nid);
15572 if (spec->autocfg.speaker_outs)
15573 alc861_auto_set_output_and_unmute(codec,
15574 spec->autocfg.speaker_pins[0],
15576 spec->multiout.dac_nids[0]);
15579 /* parse the BIOS configuration and set up the alc_spec */
15580 /* return 1 if successful, 0 if the proper config is not found,
15581 * or a negative error code
15583 static int alc861_parse_auto_config(struct hda_codec *codec)
15585 struct alc_spec *spec = codec->spec;
15587 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15589 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15593 if (!spec->autocfg.line_outs)
15594 return 0; /* can't find valid BIOS pin config */
15596 err = alc861_auto_fill_dac_nids(codec);
15599 err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids);
15602 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
15605 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
15608 err = alc_auto_create_input_ctls(codec);
15612 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15614 alc_auto_parse_digital(codec);
15616 if (spec->kctls.list)
15617 add_mixer(spec, spec->kctls.list);
15619 spec->num_mux_defs = 1;
15620 spec->input_mux = &spec->private_imux[0];
15622 if (!spec->dual_adc_switch)
15623 alc_remove_invalid_adc_nids(codec);
15625 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
15627 set_capture_mixer(codec);
15632 /* additional initialization for auto-configuration model */
15633 static void alc861_auto_init(struct hda_codec *codec)
15635 struct alc_spec *spec = codec->spec;
15636 alc861_auto_init_multi_out(codec);
15637 alc861_auto_init_hp_out(codec);
15638 alc_auto_init_analog_input(codec);
15639 alc_auto_init_digital(codec);
15640 if (spec->unsol_event)
15641 alc_inithook(codec);
15644 #ifdef CONFIG_SND_HDA_POWER_SAVE
15645 static const struct hda_amp_list alc861_loopbacks[] = {
15646 { 0x15, HDA_INPUT, 0 },
15647 { 0x15, HDA_INPUT, 1 },
15648 { 0x15, HDA_INPUT, 2 },
15649 { 0x15, HDA_INPUT, 3 },
15656 * configuration and preset
15658 static const char * const alc861_models[ALC861_MODEL_LAST] = {
15659 [ALC861_3ST] = "3stack",
15660 [ALC660_3ST] = "3stack-660",
15661 [ALC861_3ST_DIG] = "3stack-dig",
15662 [ALC861_6ST_DIG] = "6stack-dig",
15663 [ALC861_UNIWILL_M31] = "uniwill-m31",
15664 [ALC861_TOSHIBA] = "toshiba",
15665 [ALC861_ASUS] = "asus",
15666 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15667 [ALC861_AUTO] = "auto",
15670 static const struct snd_pci_quirk alc861_cfg_tbl[] = {
15671 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
15672 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15673 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15674 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
15675 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
15676 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
15677 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
15678 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15679 * Any other models that need this preset?
15681 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
15682 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15683 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
15684 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
15685 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15686 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15687 /* FIXME: the below seems conflict */
15688 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
15689 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
15690 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
15694 static const struct alc_config_preset alc861_presets[] = {
15696 .mixers = { alc861_3ST_mixer },
15697 .init_verbs = { alc861_threestack_init_verbs },
15698 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15699 .dac_nids = alc861_dac_nids,
15700 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15701 .channel_mode = alc861_threestack_modes,
15703 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15704 .adc_nids = alc861_adc_nids,
15705 .input_mux = &alc861_capture_source,
15707 [ALC861_3ST_DIG] = {
15708 .mixers = { alc861_base_mixer },
15709 .init_verbs = { alc861_threestack_init_verbs },
15710 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15711 .dac_nids = alc861_dac_nids,
15712 .dig_out_nid = ALC861_DIGOUT_NID,
15713 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15714 .channel_mode = alc861_threestack_modes,
15716 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15717 .adc_nids = alc861_adc_nids,
15718 .input_mux = &alc861_capture_source,
15720 [ALC861_6ST_DIG] = {
15721 .mixers = { alc861_base_mixer },
15722 .init_verbs = { alc861_base_init_verbs },
15723 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15724 .dac_nids = alc861_dac_nids,
15725 .dig_out_nid = ALC861_DIGOUT_NID,
15726 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15727 .channel_mode = alc861_8ch_modes,
15728 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15729 .adc_nids = alc861_adc_nids,
15730 .input_mux = &alc861_capture_source,
15733 .mixers = { alc861_3ST_mixer },
15734 .init_verbs = { alc861_threestack_init_verbs },
15735 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15736 .dac_nids = alc660_dac_nids,
15737 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15738 .channel_mode = alc861_threestack_modes,
15740 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15741 .adc_nids = alc861_adc_nids,
15742 .input_mux = &alc861_capture_source,
15744 [ALC861_UNIWILL_M31] = {
15745 .mixers = { alc861_uniwill_m31_mixer },
15746 .init_verbs = { alc861_uniwill_m31_init_verbs },
15747 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15748 .dac_nids = alc861_dac_nids,
15749 .dig_out_nid = ALC861_DIGOUT_NID,
15750 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15751 .channel_mode = alc861_uniwill_m31_modes,
15753 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15754 .adc_nids = alc861_adc_nids,
15755 .input_mux = &alc861_capture_source,
15757 [ALC861_TOSHIBA] = {
15758 .mixers = { alc861_toshiba_mixer },
15759 .init_verbs = { alc861_base_init_verbs,
15760 alc861_toshiba_init_verbs },
15761 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15762 .dac_nids = alc861_dac_nids,
15763 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15764 .channel_mode = alc883_3ST_2ch_modes,
15765 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15766 .adc_nids = alc861_adc_nids,
15767 .input_mux = &alc861_capture_source,
15768 .unsol_event = alc861_toshiba_unsol_event,
15769 .init_hook = alc861_toshiba_automute,
15772 .mixers = { alc861_asus_mixer },
15773 .init_verbs = { alc861_asus_init_verbs },
15774 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15775 .dac_nids = alc861_dac_nids,
15776 .dig_out_nid = ALC861_DIGOUT_NID,
15777 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15778 .channel_mode = alc861_asus_modes,
15781 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15782 .adc_nids = alc861_adc_nids,
15783 .input_mux = &alc861_capture_source,
15785 [ALC861_ASUS_LAPTOP] = {
15786 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15787 .init_verbs = { alc861_asus_init_verbs,
15788 alc861_asus_laptop_init_verbs },
15789 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15790 .dac_nids = alc861_dac_nids,
15791 .dig_out_nid = ALC861_DIGOUT_NID,
15792 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15793 .channel_mode = alc883_3ST_2ch_modes,
15795 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15796 .adc_nids = alc861_adc_nids,
15797 .input_mux = &alc861_capture_source,
15801 /* Pin config fixes */
15803 PINFIX_FSC_AMILO_PI1505,
15806 static const struct alc_fixup alc861_fixups[] = {
15807 [PINFIX_FSC_AMILO_PI1505] = {
15808 .type = ALC_FIXUP_PINS,
15809 .v.pins = (const struct alc_pincfg[]) {
15810 { 0x0b, 0x0221101f }, /* HP */
15811 { 0x0f, 0x90170310 }, /* speaker */
15817 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
15818 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15822 static int patch_alc861(struct hda_codec *codec)
15824 struct alc_spec *spec;
15828 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15832 codec->spec = spec;
15834 spec->mixer_nid = 0x15;
15836 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15840 if (board_config < 0) {
15841 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15843 board_config = ALC861_AUTO;
15846 if (board_config == ALC861_AUTO) {
15847 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
15848 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15851 if (board_config == ALC861_AUTO) {
15852 /* automatic parse from the BIOS config */
15853 err = alc861_parse_auto_config(codec);
15859 "hda_codec: Cannot set up configuration "
15860 "from BIOS. Using base mode...\n");
15861 board_config = ALC861_3ST_DIG;
15865 err = snd_hda_attach_beep_device(codec, 0x23);
15871 if (board_config != ALC861_AUTO)
15872 setup_preset(codec, &alc861_presets[board_config]);
15874 if (!spec->cap_mixer)
15875 set_capture_mixer(codec);
15876 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15878 spec->vmaster_nid = 0x03;
15880 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15882 codec->patch_ops = alc_patch_ops;
15883 if (board_config == ALC861_AUTO) {
15884 spec->init_hook = alc861_auto_init;
15885 #ifdef CONFIG_SND_HDA_POWER_SAVE
15886 spec->power_hook = alc_power_eapd;
15889 #ifdef CONFIG_SND_HDA_POWER_SAVE
15890 if (!spec->loopback.amplist)
15891 spec->loopback.amplist = alc861_loopbacks;
15898 * ALC861-VD support
15902 * In addition, an independent DAC
15904 #define ALC861VD_DIGOUT_NID 0x06
15906 static const hda_nid_t alc861vd_dac_nids[4] = {
15907 /* front, surr, clfe, side surr */
15908 0x02, 0x03, 0x04, 0x05
15911 /* dac_nids for ALC660vd are in a different order - according to
15912 * Realtek's driver.
15913 * This should probably result in a different mixer for 6stack models
15914 * of ALC660vd codecs, but for now there is only 3stack mixer
15915 * - and it is the same as in 861vd.
15916 * adc_nids in ALC660vd are (is) the same as in 861vd
15918 static const hda_nid_t alc660vd_dac_nids[3] = {
15919 /* front, rear, clfe, rear_surr */
15923 static const hda_nid_t alc861vd_adc_nids[1] = {
15928 static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15931 /* FIXME: should be a matrix-type input source selection */
15932 static const struct hda_input_mux alc861vd_capture_source = {
15936 { "Front Mic", 0x1 },
15942 static const struct hda_input_mux alc861vd_dallas_capture_source = {
15946 { "Internal Mic", 0x1 },
15950 static const struct hda_input_mux alc861vd_hp_capture_source = {
15953 { "Front Mic", 0x0 },
15954 { "ATAPI Mic", 0x1 },
15961 static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15968 static const struct hda_verb alc861vd_6stack_ch6_init[] = {
15969 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15970 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15971 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15972 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15979 static const struct hda_verb alc861vd_6stack_ch8_init[] = {
15980 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15981 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15982 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15983 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15987 static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
15988 { 6, alc861vd_6stack_ch6_init },
15989 { 8, alc861vd_6stack_ch8_init },
15992 static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15995 .name = "Channel Mode",
15996 .info = alc_ch_mode_info,
15997 .get = alc_ch_mode_get,
15998 .put = alc_ch_mode_put,
16003 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16004 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16006 static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16007 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16010 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16011 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16013 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16015 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16017 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16018 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16020 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16021 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16023 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16025 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16026 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16027 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16029 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16031 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16034 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16036 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16037 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16042 static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16043 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16044 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16046 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16048 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16049 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16050 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16052 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16053 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16054 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16056 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16057 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16059 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16060 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16065 static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16066 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16067 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16068 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16070 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16072 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16073 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16074 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16076 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16077 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16078 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16080 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16081 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16086 /* Pin assignment: Speaker=0x14, HP = 0x15,
16087 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16089 static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16090 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16091 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16092 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16093 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16094 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16095 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16096 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16097 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16098 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16099 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16103 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16104 * Front Mic=0x18, ATAPI Mic = 0x19,
16106 static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16107 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16108 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16109 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16110 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16111 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16112 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16113 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16114 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16120 * generic initialization of ADC, input mixers and output mixers
16122 static const struct hda_verb alc861vd_volume_init_verbs[] = {
16124 * Unmute ADC0 and set the default input to mic-in
16126 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16129 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16130 * the analog-loopback mixer widget
16132 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16133 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16139 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16146 * Set up output mixers (0x02 - 0x05)
16148 /* set vol=0 to output mixers */
16149 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16150 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16151 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16152 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16154 /* set up input amps for analog loopback */
16155 /* Amp Indices: DAC = 0, mixer = 1 */
16156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16157 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16158 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16159 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16160 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16161 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16162 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16163 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16169 * 3-stack pin configuration:
16170 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16172 static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16174 * Set pin mode and muting
16176 /* set front pin widgets 0x14 for output */
16177 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16178 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16179 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16181 /* Mic (rear) pin: input vref at 80% */
16182 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16183 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16184 /* Front Mic pin: input vref at 80% */
16185 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16186 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16187 /* Line In pin: input */
16188 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16189 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16190 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16191 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16192 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16193 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16194 /* CD pin widget for input */
16195 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16201 * 6-stack pin configuration:
16203 static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16205 * Set pin mode and muting
16207 /* set front pin widgets 0x14 for output */
16208 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16210 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16212 /* Rear Pin: output 1 (0x0d) */
16213 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16214 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16215 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16216 /* CLFE Pin: output 2 (0x0e) */
16217 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16218 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16219 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16220 /* Side Pin: output 3 (0x0f) */
16221 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16222 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16223 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16225 /* Mic (rear) pin: input vref at 80% */
16226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16227 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16228 /* Front Mic pin: input vref at 80% */
16229 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16230 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16231 /* Line In pin: input */
16232 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16233 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16234 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16235 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16236 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16237 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16238 /* CD pin widget for input */
16239 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16244 static const struct hda_verb alc861vd_eapd_verbs[] = {
16245 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16249 static const struct hda_verb alc660vd_eapd_verbs[] = {
16250 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16251 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16255 static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16258 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16259 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16260 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16264 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16266 struct alc_spec *spec = codec->spec;
16267 spec->autocfg.hp_pins[0] = 0x1b;
16268 spec->autocfg.speaker_pins[0] = 0x14;
16269 spec->automute = 1;
16270 spec->automute_mode = ALC_AUTOMUTE_AMP;
16273 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16275 alc_hp_automute(codec);
16276 alc88x_simple_mic_automute(codec);
16279 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16282 switch (res >> 26) {
16283 case ALC880_MIC_EVENT:
16284 alc88x_simple_mic_automute(codec);
16287 alc_sku_unsol_event(codec, res);
16292 static const struct hda_verb alc861vd_dallas_verbs[] = {
16293 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16294 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16295 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16296 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16299 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16300 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16301 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16302 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16303 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16304 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16305 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16307 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16308 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16309 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16310 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16311 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16312 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16313 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16314 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16316 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16317 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16318 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16319 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16321 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16322 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16323 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16328 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16330 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16331 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16332 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16337 /* toggle speaker-output according to the hp-jack state */
16338 static void alc861vd_dallas_setup(struct hda_codec *codec)
16340 struct alc_spec *spec = codec->spec;
16342 spec->autocfg.hp_pins[0] = 0x15;
16343 spec->autocfg.speaker_pins[0] = 0x14;
16344 spec->automute = 1;
16345 spec->automute_mode = ALC_AUTOMUTE_AMP;
16348 #ifdef CONFIG_SND_HDA_POWER_SAVE
16349 #define alc861vd_loopbacks alc880_loopbacks
16353 * configuration and preset
16355 static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16356 [ALC660VD_3ST] = "3stack-660",
16357 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16358 [ALC660VD_ASUS_V1S] = "asus-v1s",
16359 [ALC861VD_3ST] = "3stack",
16360 [ALC861VD_3ST_DIG] = "3stack-digout",
16361 [ALC861VD_6ST_DIG] = "6stack-digout",
16362 [ALC861VD_LENOVO] = "lenovo",
16363 [ALC861VD_DALLAS] = "dallas",
16364 [ALC861VD_HP] = "hp",
16365 [ALC861VD_AUTO] = "auto",
16368 static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16369 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16370 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16371 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16372 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16373 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16374 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16375 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16376 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16377 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16378 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16379 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16380 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16381 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16382 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16383 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16387 static const struct alc_config_preset alc861vd_presets[] = {
16389 .mixers = { alc861vd_3st_mixer },
16390 .init_verbs = { alc861vd_volume_init_verbs,
16391 alc861vd_3stack_init_verbs },
16392 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16393 .dac_nids = alc660vd_dac_nids,
16394 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16395 .channel_mode = alc861vd_3stack_2ch_modes,
16396 .input_mux = &alc861vd_capture_source,
16398 [ALC660VD_3ST_DIG] = {
16399 .mixers = { alc861vd_3st_mixer },
16400 .init_verbs = { alc861vd_volume_init_verbs,
16401 alc861vd_3stack_init_verbs },
16402 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16403 .dac_nids = alc660vd_dac_nids,
16404 .dig_out_nid = ALC861VD_DIGOUT_NID,
16405 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16406 .channel_mode = alc861vd_3stack_2ch_modes,
16407 .input_mux = &alc861vd_capture_source,
16410 .mixers = { alc861vd_3st_mixer },
16411 .init_verbs = { alc861vd_volume_init_verbs,
16412 alc861vd_3stack_init_verbs },
16413 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16414 .dac_nids = alc861vd_dac_nids,
16415 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16416 .channel_mode = alc861vd_3stack_2ch_modes,
16417 .input_mux = &alc861vd_capture_source,
16419 [ALC861VD_3ST_DIG] = {
16420 .mixers = { alc861vd_3st_mixer },
16421 .init_verbs = { alc861vd_volume_init_verbs,
16422 alc861vd_3stack_init_verbs },
16423 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16424 .dac_nids = alc861vd_dac_nids,
16425 .dig_out_nid = ALC861VD_DIGOUT_NID,
16426 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16427 .channel_mode = alc861vd_3stack_2ch_modes,
16428 .input_mux = &alc861vd_capture_source,
16430 [ALC861VD_6ST_DIG] = {
16431 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16432 .init_verbs = { alc861vd_volume_init_verbs,
16433 alc861vd_6stack_init_verbs },
16434 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16435 .dac_nids = alc861vd_dac_nids,
16436 .dig_out_nid = ALC861VD_DIGOUT_NID,
16437 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16438 .channel_mode = alc861vd_6stack_modes,
16439 .input_mux = &alc861vd_capture_source,
16441 [ALC861VD_LENOVO] = {
16442 .mixers = { alc861vd_lenovo_mixer },
16443 .init_verbs = { alc861vd_volume_init_verbs,
16444 alc861vd_3stack_init_verbs,
16445 alc861vd_eapd_verbs,
16446 alc861vd_lenovo_unsol_verbs },
16447 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16448 .dac_nids = alc660vd_dac_nids,
16449 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16450 .channel_mode = alc861vd_3stack_2ch_modes,
16451 .input_mux = &alc861vd_capture_source,
16452 .unsol_event = alc861vd_lenovo_unsol_event,
16453 .setup = alc861vd_lenovo_setup,
16454 .init_hook = alc861vd_lenovo_init_hook,
16456 [ALC861VD_DALLAS] = {
16457 .mixers = { alc861vd_dallas_mixer },
16458 .init_verbs = { alc861vd_dallas_verbs },
16459 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16460 .dac_nids = alc861vd_dac_nids,
16461 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16462 .channel_mode = alc861vd_3stack_2ch_modes,
16463 .input_mux = &alc861vd_dallas_capture_source,
16464 .unsol_event = alc_sku_unsol_event,
16465 .setup = alc861vd_dallas_setup,
16466 .init_hook = alc_hp_automute,
16469 .mixers = { alc861vd_hp_mixer },
16470 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16471 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16472 .dac_nids = alc861vd_dac_nids,
16473 .dig_out_nid = ALC861VD_DIGOUT_NID,
16474 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16475 .channel_mode = alc861vd_3stack_2ch_modes,
16476 .input_mux = &alc861vd_hp_capture_source,
16477 .unsol_event = alc_sku_unsol_event,
16478 .setup = alc861vd_dallas_setup,
16479 .init_hook = alc_hp_automute,
16481 [ALC660VD_ASUS_V1S] = {
16482 .mixers = { alc861vd_lenovo_mixer },
16483 .init_verbs = { alc861vd_volume_init_verbs,
16484 alc861vd_3stack_init_verbs,
16485 alc861vd_eapd_verbs,
16486 alc861vd_lenovo_unsol_verbs },
16487 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16488 .dac_nids = alc660vd_dac_nids,
16489 .dig_out_nid = ALC861VD_DIGOUT_NID,
16490 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16491 .channel_mode = alc861vd_3stack_2ch_modes,
16492 .input_mux = &alc861vd_capture_source,
16493 .unsol_event = alc861vd_lenovo_unsol_event,
16494 .setup = alc861vd_lenovo_setup,
16495 .init_hook = alc861vd_lenovo_init_hook,
16500 * BIOS auto configuration
16502 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16503 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16505 /* add playback controls from the parsed DAC table */
16506 /* Based on ALC880 version. But ALC861VD has separate,
16507 * different NIDs for mute/unmute switch and volume control */
16508 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16509 const struct auto_pin_cfg *cfg)
16511 hda_nid_t nid_v, nid_s;
16512 int i, err, noutputs;
16514 noutputs = cfg->line_outs;
16515 if (spec->multi_ios > 0)
16516 noutputs += spec->multi_ios;
16518 for (i = 0; i < noutputs; i++) {
16521 if (!spec->multiout.dac_nids[i])
16523 nid_v = alc861vd_idx_to_mixer_vol(
16525 spec->multiout.dac_nids[i]));
16526 nid_s = alc861vd_idx_to_mixer_switch(
16528 spec->multiout.dac_nids[i]));
16530 name = alc_get_line_out_pfx(spec, i, true, &index);
16533 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16535 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16539 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16541 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16545 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16547 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16551 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16553 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16558 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16560 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16564 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16566 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
16575 /* add playback controls for speaker and HP outputs */
16576 /* Based on ALC880 version. But ALC861VD has separate,
16577 * different NIDs for mute/unmute switch and volume control */
16578 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16579 hda_nid_t pin, const char *pfx)
16581 hda_nid_t nid_v, nid_s;
16587 if (alc880_is_fixed_pin(pin)) {
16588 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16589 /* specify the DAC as the extra output */
16590 if (!spec->multiout.hp_nid)
16591 spec->multiout.hp_nid = nid_v;
16593 spec->multiout.extra_out_nid[0] = nid_v;
16594 /* control HP volume/switch on the output mixer amp */
16595 nid_v = alc861vd_idx_to_mixer_vol(
16596 alc880_fixed_pin_idx(pin));
16597 nid_s = alc861vd_idx_to_mixer_switch(
16598 alc880_fixed_pin_idx(pin));
16600 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16601 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16604 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16605 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16608 } else if (alc880_is_multi_pin(pin)) {
16609 /* set manual connection */
16610 /* we have only a switch on HP-out PIN */
16611 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
16612 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16619 /* parse the BIOS configuration and set up the alc_spec
16620 * return 1 if successful, 0 if the proper config is not found,
16621 * or a negative error code
16622 * Based on ALC880 version - had to change it to override
16623 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16624 static int alc861vd_parse_auto_config(struct hda_codec *codec)
16626 struct alc_spec *spec = codec->spec;
16628 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16630 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16634 if (!spec->autocfg.line_outs)
16635 return 0; /* can't find valid BIOS pin config */
16637 err = alc_auto_fill_dac_nids(codec);
16640 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
16643 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16646 err = alc861vd_auto_create_extra_out(spec,
16647 spec->autocfg.speaker_pins[0],
16651 err = alc861vd_auto_create_extra_out(spec,
16652 spec->autocfg.hp_pins[0],
16656 err = alc_auto_create_input_ctls(codec);
16660 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16662 alc_auto_parse_digital(codec);
16664 if (spec->kctls.list)
16665 add_mixer(spec, spec->kctls.list);
16667 spec->num_mux_defs = 1;
16668 spec->input_mux = &spec->private_imux[0];
16670 if (!spec->dual_adc_switch)
16671 alc_remove_invalid_adc_nids(codec);
16673 err = alc_auto_add_mic_boost(codec);
16677 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
16682 /* additional initialization for auto-configuration model */
16683 static void alc861vd_auto_init(struct hda_codec *codec)
16685 struct alc_spec *spec = codec->spec;
16686 alc_auto_init_multi_out(codec);
16687 alc_auto_init_extra_out(codec);
16688 alc_auto_init_analog_input(codec);
16689 alc_auto_init_input_src(codec);
16690 alc_auto_init_digital(codec);
16691 if (spec->unsol_event)
16692 alc_inithook(codec);
16696 ALC660VD_FIX_ASUS_GPIO1
16700 static const struct alc_fixup alc861vd_fixups[] = {
16701 [ALC660VD_FIX_ASUS_GPIO1] = {
16702 .type = ALC_FIXUP_VERBS,
16703 .v.verbs = (const struct hda_verb[]) {
16704 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16705 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16706 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16712 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16713 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16717 static int patch_alc861vd(struct hda_codec *codec)
16719 struct alc_spec *spec;
16720 int err, board_config;
16722 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16726 codec->spec = spec;
16728 spec->mixer_nid = 0x0b;
16730 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16734 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
16735 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16737 board_config = ALC861VD_AUTO;
16740 if (board_config == ALC861VD_AUTO) {
16741 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
16742 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16745 if (board_config == ALC861VD_AUTO) {
16746 /* automatic parse from the BIOS config */
16747 err = alc861vd_parse_auto_config(codec);
16753 "hda_codec: Cannot set up configuration "
16754 "from BIOS. Using base mode...\n");
16755 board_config = ALC861VD_3ST;
16759 err = snd_hda_attach_beep_device(codec, 0x23);
16765 if (board_config != ALC861VD_AUTO)
16766 setup_preset(codec, &alc861vd_presets[board_config]);
16768 if (codec->vendor_id == 0x10ec0660) {
16769 /* always turn on EAPD */
16770 add_verb(spec, alc660vd_eapd_verbs);
16773 if (!spec->adc_nids) {
16774 alc_auto_fill_adc_caps(codec);
16775 alc_remove_invalid_adc_nids(codec);
16778 set_capture_mixer(codec);
16779 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
16781 spec->vmaster_nid = 0x02;
16783 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16785 codec->patch_ops = alc_patch_ops;
16787 if (board_config == ALC861VD_AUTO)
16788 spec->init_hook = alc861vd_auto_init;
16789 spec->shutup = alc_eapd_shutup;
16790 #ifdef CONFIG_SND_HDA_POWER_SAVE
16791 if (!spec->loopback.amplist)
16792 spec->loopback.amplist = alc861vd_loopbacks;
16801 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16802 * configuration. Each pin widget can choose any input DACs and a mixer.
16803 * Each ADC is connected from a mixer of all inputs. This makes possible
16804 * 6-channel independent captures.
16806 * In addition, an independent DAC for the multi-playback (not used in this
16809 #define ALC662_DIGOUT_NID 0x06
16810 #define ALC662_DIGIN_NID 0x0a
16812 static const hda_nid_t alc662_dac_nids[3] = {
16813 /* front, rear, clfe */
16817 static const hda_nid_t alc272_dac_nids[2] = {
16821 static const hda_nid_t alc662_adc_nids[2] = {
16826 static const hda_nid_t alc272_adc_nids[1] = {
16831 static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16832 static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16836 /* FIXME: should be a matrix-type input source selection */
16837 static const struct hda_input_mux alc662_capture_source = {
16841 { "Front Mic", 0x1 },
16847 static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
16855 static const struct hda_input_mux alc663_capture_source = {
16859 { "Front Mic", 0x1 },
16864 #if 0 /* set to 1 for testing other input sources below */
16865 static const struct hda_input_mux alc272_nc10_capture_source = {
16868 { "Autoselect Mic", 0x0 },
16869 { "Internal Mic", 0x1 },
16870 { "In-0x02", 0x2 },
16871 { "In-0x03", 0x3 },
16872 { "In-0x04", 0x4 },
16873 { "In-0x05", 0x5 },
16874 { "In-0x06", 0x6 },
16875 { "In-0x07", 0x7 },
16876 { "In-0x08", 0x8 },
16877 { "In-0x09", 0x9 },
16878 { "In-0x0a", 0x0a },
16879 { "In-0x0b", 0x0b },
16880 { "In-0x0c", 0x0c },
16881 { "In-0x0d", 0x0d },
16882 { "In-0x0e", 0x0e },
16883 { "In-0x0f", 0x0f },
16891 static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16898 static const struct hda_verb alc662_3ST_ch2_init[] = {
16899 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16900 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16901 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16902 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16909 static const struct hda_verb alc662_3ST_ch6_init[] = {
16910 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16911 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16912 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16913 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16914 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16915 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16919 static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16920 { 2, alc662_3ST_ch2_init },
16921 { 6, alc662_3ST_ch6_init },
16927 static const struct hda_verb alc662_sixstack_ch6_init[] = {
16928 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16929 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16930 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16937 static const struct hda_verb alc662_sixstack_ch8_init[] = {
16938 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16939 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16940 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16944 static const struct hda_channel_mode alc662_5stack_modes[2] = {
16945 { 2, alc662_sixstack_ch6_init },
16946 { 6, alc662_sixstack_ch8_init },
16949 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16950 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16953 static const struct snd_kcontrol_new alc662_base_mixer[] = {
16954 /* output mixer control */
16955 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
16956 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16957 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
16958 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16959 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16960 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16961 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16962 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16965 /*Input mixer control */
16966 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16967 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16968 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16969 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16970 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16971 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16972 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16973 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
16977 static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16978 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16979 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16981 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16982 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16983 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16984 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16987 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16988 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16992 static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16993 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16994 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16995 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16996 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16997 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16998 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16999 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17000 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17001 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17002 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17003 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17004 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17005 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17008 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17009 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17013 static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17014 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17015 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17016 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17017 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17018 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17019 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17020 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17026 static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17027 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17028 ALC262_HIPPO_MASTER_SWITCH,
17030 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17032 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17034 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17035 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17036 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17040 static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17041 ALC262_HIPPO_MASTER_SWITCH,
17042 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17043 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17044 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17045 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17046 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17047 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17048 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17049 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17050 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17054 static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17055 .ops = &snd_hda_bind_vol,
17057 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17058 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17063 static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17064 .ops = &snd_hda_bind_sw,
17066 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17067 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17072 static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17073 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17074 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17080 static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17081 .ops = &snd_hda_bind_sw,
17083 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17084 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17085 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17090 static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17091 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17092 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17095 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17096 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17101 static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17102 .ops = &snd_hda_bind_sw,
17104 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17105 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17106 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17111 static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17112 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17113 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17116 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17117 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17121 static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17122 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17123 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17124 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17125 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17127 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17128 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17132 static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17133 .ops = &snd_hda_bind_vol,
17135 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17136 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17141 static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17142 .ops = &snd_hda_bind_sw,
17144 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17145 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17150 static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17151 HDA_BIND_VOL("Master Playback Volume",
17152 &alc663_asus_two_bind_master_vol),
17153 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17154 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17155 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17161 static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17162 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17163 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17164 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17165 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17171 static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17172 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17173 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17174 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17175 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17179 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17180 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17181 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17185 static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17186 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17187 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17188 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17192 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17193 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17195 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17199 static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17200 .ops = &snd_hda_bind_sw,
17202 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17203 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17204 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17205 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17206 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17211 static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17212 .ops = &snd_hda_bind_sw,
17214 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17215 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17220 static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17221 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17222 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17223 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17224 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17225 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17226 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17227 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17233 static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17234 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17235 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17236 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17237 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17238 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17240 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17245 static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17247 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17248 .name = "Channel Mode",
17249 .info = alc_ch_mode_info,
17250 .get = alc_ch_mode_get,
17251 .put = alc_ch_mode_put,
17256 static const struct hda_verb alc662_init_verbs[] = {
17257 /* ADC: mute amp left and right */
17258 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17259 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17261 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17263 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17264 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17265 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17266 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17268 /* Front Pin: output 0 (0x0c) */
17269 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17270 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17272 /* Rear Pin: output 1 (0x0d) */
17273 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17274 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17276 /* CLFE Pin: output 2 (0x0e) */
17277 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17278 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17280 /* Mic (rear) pin: input vref at 80% */
17281 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17282 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17283 /* Front Mic pin: input vref at 80% */
17284 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17285 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17286 /* Line In pin: input */
17287 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17288 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17289 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17290 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17291 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17292 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17293 /* CD pin widget for input */
17294 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17296 /* FIXME: use matrix-type input source selection */
17297 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17300 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17305 static const struct hda_verb alc662_eapd_init_verbs[] = {
17306 /* always trun on EAPD */
17307 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17308 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17312 static const struct hda_verb alc662_sue_init_verbs[] = {
17313 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17314 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17318 static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17319 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17320 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17324 /* Set Unsolicited Event*/
17325 static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17326 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17327 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17331 static const struct hda_verb alc663_m51va_init_verbs[] = {
17332 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17333 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17334 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17335 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17336 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17339 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17340 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17344 static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
17345 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17346 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17347 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17348 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17349 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17350 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17351 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17355 static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17356 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17357 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17358 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17359 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17360 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17362 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17363 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17367 static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
17368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17370 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17373 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17374 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17378 static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17379 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17380 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17381 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17382 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17383 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17384 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17385 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17388 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17389 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17390 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17394 static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17395 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17396 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17397 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17398 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17401 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17402 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17403 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17404 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17405 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17406 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17410 static const struct hda_verb alc663_g71v_init_verbs[] = {
17411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17412 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17413 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17415 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17416 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17417 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17419 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17420 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17421 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17425 static const struct hda_verb alc663_g50v_init_verbs[] = {
17426 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17427 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17428 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17430 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17431 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17435 static const struct hda_verb alc662_ecs_init_verbs[] = {
17436 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17438 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17439 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17443 static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
17444 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17445 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17447 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17448 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17449 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17450 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17451 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17453 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17454 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17458 static const struct hda_verb alc272_dell_init_verbs[] = {
17459 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17460 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17462 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17463 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17464 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17465 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17468 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17469 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17473 static const struct hda_verb alc663_mode7_init_verbs[] = {
17474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17475 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17476 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17477 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17478 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17479 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17480 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17481 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17482 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17483 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17484 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17485 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17486 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17487 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17488 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17492 static const struct hda_verb alc663_mode8_init_verbs[] = {
17493 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17496 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17497 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17498 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17499 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17501 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17502 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17503 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17504 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17505 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17506 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17507 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17508 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17512 static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17513 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17514 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17518 static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17519 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17520 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17524 static void alc662_lenovo_101e_setup(struct hda_codec *codec)
17526 struct alc_spec *spec = codec->spec;
17528 spec->autocfg.hp_pins[0] = 0x1b;
17529 spec->autocfg.line_out_pins[0] = 0x14;
17530 spec->autocfg.speaker_pins[0] = 0x15;
17531 spec->automute = 1;
17532 spec->detect_line = 1;
17533 spec->automute_lines = 1;
17534 spec->automute_mode = ALC_AUTOMUTE_AMP;
17537 static void alc662_eeepc_setup(struct hda_codec *codec)
17539 struct alc_spec *spec = codec->spec;
17541 alc262_hippo1_setup(codec);
17542 spec->ext_mic.pin = 0x18;
17543 spec->ext_mic.mux_idx = 0;
17544 spec->int_mic.pin = 0x19;
17545 spec->int_mic.mux_idx = 1;
17546 spec->auto_mic = 1;
17549 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
17551 struct alc_spec *spec = codec->spec;
17553 spec->autocfg.hp_pins[0] = 0x14;
17554 spec->autocfg.speaker_pins[0] = 0x1b;
17555 spec->automute = 1;
17556 spec->automute_mode = ALC_AUTOMUTE_AMP;
17559 static void alc663_m51va_setup(struct hda_codec *codec)
17561 struct alc_spec *spec = codec->spec;
17562 spec->autocfg.hp_pins[0] = 0x21;
17563 spec->autocfg.speaker_pins[0] = 0x14;
17564 spec->automute_mixer_nid[0] = 0x0c;
17565 spec->automute = 1;
17566 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17567 spec->ext_mic.pin = 0x18;
17568 spec->ext_mic.mux_idx = 0;
17569 spec->int_mic.pin = 0x12;
17570 spec->int_mic.mux_idx = 9;
17571 spec->auto_mic = 1;
17574 /* ***************** Mode1 ******************************/
17575 static void alc663_mode1_setup(struct hda_codec *codec)
17577 struct alc_spec *spec = codec->spec;
17578 spec->autocfg.hp_pins[0] = 0x21;
17579 spec->autocfg.speaker_pins[0] = 0x14;
17580 spec->automute_mixer_nid[0] = 0x0c;
17581 spec->automute = 1;
17582 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17583 spec->ext_mic.pin = 0x18;
17584 spec->ext_mic.mux_idx = 0;
17585 spec->int_mic.pin = 0x19;
17586 spec->int_mic.mux_idx = 1;
17587 spec->auto_mic = 1;
17590 /* ***************** Mode2 ******************************/
17591 static void alc662_mode2_setup(struct hda_codec *codec)
17593 struct alc_spec *spec = codec->spec;
17594 spec->autocfg.hp_pins[0] = 0x1b;
17595 spec->autocfg.speaker_pins[0] = 0x14;
17596 spec->automute = 1;
17597 spec->automute_mode = ALC_AUTOMUTE_PIN;
17598 spec->ext_mic.pin = 0x18;
17599 spec->ext_mic.mux_idx = 0;
17600 spec->int_mic.pin = 0x19;
17601 spec->int_mic.mux_idx = 1;
17602 spec->auto_mic = 1;
17605 /* ***************** Mode3 ******************************/
17606 static void alc663_mode3_setup(struct hda_codec *codec)
17608 struct alc_spec *spec = codec->spec;
17609 spec->autocfg.hp_pins[0] = 0x21;
17610 spec->autocfg.hp_pins[0] = 0x15;
17611 spec->autocfg.speaker_pins[0] = 0x14;
17612 spec->automute = 1;
17613 spec->automute_mode = ALC_AUTOMUTE_PIN;
17614 spec->ext_mic.pin = 0x18;
17615 spec->ext_mic.mux_idx = 0;
17616 spec->int_mic.pin = 0x19;
17617 spec->int_mic.mux_idx = 1;
17618 spec->auto_mic = 1;
17621 /* ***************** Mode4 ******************************/
17622 static void alc663_mode4_setup(struct hda_codec *codec)
17624 struct alc_spec *spec = codec->spec;
17625 spec->autocfg.hp_pins[0] = 0x21;
17626 spec->autocfg.speaker_pins[0] = 0x14;
17627 spec->autocfg.speaker_pins[1] = 0x16;
17628 spec->automute_mixer_nid[0] = 0x0c;
17629 spec->automute_mixer_nid[1] = 0x0e;
17630 spec->automute = 1;
17631 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17632 spec->ext_mic.pin = 0x18;
17633 spec->ext_mic.mux_idx = 0;
17634 spec->int_mic.pin = 0x19;
17635 spec->int_mic.mux_idx = 1;
17636 spec->auto_mic = 1;
17639 /* ***************** Mode5 ******************************/
17640 static void alc663_mode5_setup(struct hda_codec *codec)
17642 struct alc_spec *spec = codec->spec;
17643 spec->autocfg.hp_pins[0] = 0x15;
17644 spec->autocfg.speaker_pins[0] = 0x14;
17645 spec->autocfg.speaker_pins[1] = 0x16;
17646 spec->automute_mixer_nid[0] = 0x0c;
17647 spec->automute_mixer_nid[1] = 0x0e;
17648 spec->automute = 1;
17649 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17650 spec->ext_mic.pin = 0x18;
17651 spec->ext_mic.mux_idx = 0;
17652 spec->int_mic.pin = 0x19;
17653 spec->int_mic.mux_idx = 1;
17654 spec->auto_mic = 1;
17657 /* ***************** Mode6 ******************************/
17658 static void alc663_mode6_setup(struct hda_codec *codec)
17660 struct alc_spec *spec = codec->spec;
17661 spec->autocfg.hp_pins[0] = 0x1b;
17662 spec->autocfg.hp_pins[0] = 0x15;
17663 spec->autocfg.speaker_pins[0] = 0x14;
17664 spec->automute_mixer_nid[0] = 0x0c;
17665 spec->automute = 1;
17666 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17667 spec->ext_mic.pin = 0x18;
17668 spec->ext_mic.mux_idx = 0;
17669 spec->int_mic.pin = 0x19;
17670 spec->int_mic.mux_idx = 1;
17671 spec->auto_mic = 1;
17674 /* ***************** Mode7 ******************************/
17675 static void alc663_mode7_setup(struct hda_codec *codec)
17677 struct alc_spec *spec = codec->spec;
17678 spec->autocfg.hp_pins[0] = 0x1b;
17679 spec->autocfg.hp_pins[0] = 0x21;
17680 spec->autocfg.speaker_pins[0] = 0x14;
17681 spec->autocfg.speaker_pins[0] = 0x17;
17682 spec->automute = 1;
17683 spec->automute_mode = ALC_AUTOMUTE_PIN;
17684 spec->ext_mic.pin = 0x18;
17685 spec->ext_mic.mux_idx = 0;
17686 spec->int_mic.pin = 0x19;
17687 spec->int_mic.mux_idx = 1;
17688 spec->auto_mic = 1;
17691 /* ***************** Mode8 ******************************/
17692 static void alc663_mode8_setup(struct hda_codec *codec)
17694 struct alc_spec *spec = codec->spec;
17695 spec->autocfg.hp_pins[0] = 0x21;
17696 spec->autocfg.hp_pins[1] = 0x15;
17697 spec->autocfg.speaker_pins[0] = 0x14;
17698 spec->autocfg.speaker_pins[0] = 0x17;
17699 spec->automute = 1;
17700 spec->automute_mode = ALC_AUTOMUTE_PIN;
17701 spec->ext_mic.pin = 0x18;
17702 spec->ext_mic.mux_idx = 0;
17703 spec->int_mic.pin = 0x12;
17704 spec->int_mic.mux_idx = 9;
17705 spec->auto_mic = 1;
17708 static void alc663_g71v_setup(struct hda_codec *codec)
17710 struct alc_spec *spec = codec->spec;
17711 spec->autocfg.hp_pins[0] = 0x21;
17712 spec->autocfg.line_out_pins[0] = 0x15;
17713 spec->autocfg.speaker_pins[0] = 0x14;
17714 spec->automute = 1;
17715 spec->automute_mode = ALC_AUTOMUTE_AMP;
17716 spec->detect_line = 1;
17717 spec->automute_lines = 1;
17718 spec->ext_mic.pin = 0x18;
17719 spec->ext_mic.mux_idx = 0;
17720 spec->int_mic.pin = 0x12;
17721 spec->int_mic.mux_idx = 9;
17722 spec->auto_mic = 1;
17725 #define alc663_g50v_setup alc663_m51va_setup
17727 static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
17728 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17729 ALC262_HIPPO_MASTER_SWITCH,
17731 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
17732 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17733 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17735 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17736 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17737 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17741 static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
17742 /* Master Playback automatically created from Speaker and Headphone */
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_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17746 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17748 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17750 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17752 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17753 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17754 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17758 #ifdef CONFIG_SND_HDA_POWER_SAVE
17759 #define alc662_loopbacks alc880_loopbacks
17764 * configuration and preset
17766 static const char * const alc662_models[ALC662_MODEL_LAST] = {
17767 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17768 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17769 [ALC662_3ST_6ch] = "3stack-6ch",
17770 [ALC662_5ST_DIG] = "5stack-dig",
17771 [ALC662_LENOVO_101E] = "lenovo-101e",
17772 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
17773 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
17774 [ALC662_ECS] = "ecs",
17775 [ALC663_ASUS_M51VA] = "m51va",
17776 [ALC663_ASUS_G71V] = "g71v",
17777 [ALC663_ASUS_H13] = "h13",
17778 [ALC663_ASUS_G50V] = "g50v",
17779 [ALC663_ASUS_MODE1] = "asus-mode1",
17780 [ALC662_ASUS_MODE2] = "asus-mode2",
17781 [ALC663_ASUS_MODE3] = "asus-mode3",
17782 [ALC663_ASUS_MODE4] = "asus-mode4",
17783 [ALC663_ASUS_MODE5] = "asus-mode5",
17784 [ALC663_ASUS_MODE6] = "asus-mode6",
17785 [ALC663_ASUS_MODE7] = "asus-mode7",
17786 [ALC663_ASUS_MODE8] = "asus-mode8",
17787 [ALC272_DELL] = "dell",
17788 [ALC272_DELL_ZM1] = "dell-zm1",
17789 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
17790 [ALC662_AUTO] = "auto",
17793 static const struct snd_pci_quirk alc662_cfg_tbl[] = {
17794 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
17795 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17796 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17797 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17798 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17799 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17800 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17801 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17802 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
17803 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
17804 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17805 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
17806 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
17807 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17808 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17809 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17810 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17811 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
17812 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
17813 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17814 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
17815 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17816 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17817 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17818 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
17819 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
17820 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17821 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17822 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
17823 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
17824 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17825 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17826 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
17827 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
17828 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
17829 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17830 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17831 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
17832 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17833 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17834 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17835 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17836 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17837 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17838 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17839 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17840 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
17841 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
17842 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17843 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
17844 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
17845 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17846 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17847 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17848 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17849 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
17850 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
17851 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
17852 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
17853 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17854 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17855 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17856 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
17857 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17858 ALC662_3ST_6ch_DIG),
17859 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
17860 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17861 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17862 ALC662_3ST_6ch_DIG),
17863 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17864 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17865 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17866 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
17867 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
17868 ALC662_3ST_6ch_DIG),
17869 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17871 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
17875 static const struct alc_config_preset alc662_presets[] = {
17876 [ALC662_3ST_2ch_DIG] = {
17877 .mixers = { alc662_3ST_2ch_mixer },
17878 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17879 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17880 .dac_nids = alc662_dac_nids,
17881 .dig_out_nid = ALC662_DIGOUT_NID,
17882 .dig_in_nid = ALC662_DIGIN_NID,
17883 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17884 .channel_mode = alc662_3ST_2ch_modes,
17885 .input_mux = &alc662_capture_source,
17887 [ALC662_3ST_6ch_DIG] = {
17888 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17889 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17890 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17891 .dac_nids = alc662_dac_nids,
17892 .dig_out_nid = ALC662_DIGOUT_NID,
17893 .dig_in_nid = ALC662_DIGIN_NID,
17894 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17895 .channel_mode = alc662_3ST_6ch_modes,
17897 .input_mux = &alc662_capture_source,
17899 [ALC662_3ST_6ch] = {
17900 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17901 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17902 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17903 .dac_nids = alc662_dac_nids,
17904 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17905 .channel_mode = alc662_3ST_6ch_modes,
17907 .input_mux = &alc662_capture_source,
17909 [ALC662_5ST_DIG] = {
17910 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
17911 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17912 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17913 .dac_nids = alc662_dac_nids,
17914 .dig_out_nid = ALC662_DIGOUT_NID,
17915 .dig_in_nid = ALC662_DIGIN_NID,
17916 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17917 .channel_mode = alc662_5stack_modes,
17918 .input_mux = &alc662_capture_source,
17920 [ALC662_LENOVO_101E] = {
17921 .mixers = { alc662_lenovo_101e_mixer },
17922 .init_verbs = { alc662_init_verbs,
17923 alc662_eapd_init_verbs,
17924 alc662_sue_init_verbs },
17925 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17926 .dac_nids = alc662_dac_nids,
17927 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17928 .channel_mode = alc662_3ST_2ch_modes,
17929 .input_mux = &alc662_lenovo_101e_capture_source,
17930 .unsol_event = alc_sku_unsol_event,
17931 .setup = alc662_lenovo_101e_setup,
17932 .init_hook = alc_inithook,
17934 [ALC662_ASUS_EEEPC_P701] = {
17935 .mixers = { alc662_eeepc_p701_mixer },
17936 .init_verbs = { alc662_init_verbs,
17937 alc662_eapd_init_verbs,
17938 alc662_eeepc_sue_init_verbs },
17939 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17940 .dac_nids = alc662_dac_nids,
17941 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17942 .channel_mode = alc662_3ST_2ch_modes,
17943 .unsol_event = alc_sku_unsol_event,
17944 .setup = alc662_eeepc_setup,
17945 .init_hook = alc_inithook,
17947 [ALC662_ASUS_EEEPC_EP20] = {
17948 .mixers = { alc662_eeepc_ep20_mixer,
17949 alc662_chmode_mixer },
17950 .init_verbs = { alc662_init_verbs,
17951 alc662_eapd_init_verbs,
17952 alc662_eeepc_ep20_sue_init_verbs },
17953 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17954 .dac_nids = alc662_dac_nids,
17955 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17956 .channel_mode = alc662_3ST_6ch_modes,
17957 .input_mux = &alc662_lenovo_101e_capture_source,
17958 .unsol_event = alc_sku_unsol_event,
17959 .setup = alc662_eeepc_ep20_setup,
17960 .init_hook = alc_inithook,
17963 .mixers = { alc662_ecs_mixer },
17964 .init_verbs = { alc662_init_verbs,
17965 alc662_eapd_init_verbs,
17966 alc662_ecs_init_verbs },
17967 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17968 .dac_nids = alc662_dac_nids,
17969 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17970 .channel_mode = alc662_3ST_2ch_modes,
17971 .unsol_event = alc_sku_unsol_event,
17972 .setup = alc662_eeepc_setup,
17973 .init_hook = alc_inithook,
17975 [ALC663_ASUS_M51VA] = {
17976 .mixers = { alc663_m51va_mixer },
17977 .init_verbs = { alc662_init_verbs,
17978 alc662_eapd_init_verbs,
17979 alc663_m51va_init_verbs },
17980 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17981 .dac_nids = alc662_dac_nids,
17982 .dig_out_nid = ALC662_DIGOUT_NID,
17983 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17984 .channel_mode = alc662_3ST_2ch_modes,
17985 .unsol_event = alc_sku_unsol_event,
17986 .setup = alc663_m51va_setup,
17987 .init_hook = alc_inithook,
17989 [ALC663_ASUS_G71V] = {
17990 .mixers = { alc663_g71v_mixer },
17991 .init_verbs = { alc662_init_verbs,
17992 alc662_eapd_init_verbs,
17993 alc663_g71v_init_verbs },
17994 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17995 .dac_nids = alc662_dac_nids,
17996 .dig_out_nid = ALC662_DIGOUT_NID,
17997 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17998 .channel_mode = alc662_3ST_2ch_modes,
17999 .unsol_event = alc_sku_unsol_event,
18000 .setup = alc663_g71v_setup,
18001 .init_hook = alc_inithook,
18003 [ALC663_ASUS_H13] = {
18004 .mixers = { alc663_m51va_mixer },
18005 .init_verbs = { alc662_init_verbs,
18006 alc662_eapd_init_verbs,
18007 alc663_m51va_init_verbs },
18008 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18009 .dac_nids = alc662_dac_nids,
18010 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18011 .channel_mode = alc662_3ST_2ch_modes,
18012 .setup = alc663_m51va_setup,
18013 .unsol_event = alc_sku_unsol_event,
18014 .init_hook = alc_inithook,
18016 [ALC663_ASUS_G50V] = {
18017 .mixers = { alc663_g50v_mixer },
18018 .init_verbs = { alc662_init_verbs,
18019 alc662_eapd_init_verbs,
18020 alc663_g50v_init_verbs },
18021 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18022 .dac_nids = alc662_dac_nids,
18023 .dig_out_nid = ALC662_DIGOUT_NID,
18024 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18025 .channel_mode = alc662_3ST_6ch_modes,
18026 .input_mux = &alc663_capture_source,
18027 .unsol_event = alc_sku_unsol_event,
18028 .setup = alc663_g50v_setup,
18029 .init_hook = alc_inithook,
18031 [ALC663_ASUS_MODE1] = {
18032 .mixers = { alc663_m51va_mixer },
18033 .cap_mixer = alc662_auto_capture_mixer,
18034 .init_verbs = { alc662_init_verbs,
18035 alc662_eapd_init_verbs,
18036 alc663_21jd_amic_init_verbs },
18037 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18039 .dac_nids = alc662_dac_nids,
18040 .dig_out_nid = ALC662_DIGOUT_NID,
18041 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18042 .channel_mode = alc662_3ST_2ch_modes,
18043 .unsol_event = alc_sku_unsol_event,
18044 .setup = alc663_mode1_setup,
18045 .init_hook = alc_inithook,
18047 [ALC662_ASUS_MODE2] = {
18048 .mixers = { alc662_1bjd_mixer },
18049 .cap_mixer = alc662_auto_capture_mixer,
18050 .init_verbs = { alc662_init_verbs,
18051 alc662_eapd_init_verbs,
18052 alc662_1bjd_amic_init_verbs },
18053 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18054 .dac_nids = alc662_dac_nids,
18055 .dig_out_nid = ALC662_DIGOUT_NID,
18056 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18057 .channel_mode = alc662_3ST_2ch_modes,
18058 .unsol_event = alc_sku_unsol_event,
18059 .setup = alc662_mode2_setup,
18060 .init_hook = alc_inithook,
18062 [ALC663_ASUS_MODE3] = {
18063 .mixers = { alc663_two_hp_m1_mixer },
18064 .cap_mixer = alc662_auto_capture_mixer,
18065 .init_verbs = { alc662_init_verbs,
18066 alc662_eapd_init_verbs,
18067 alc663_two_hp_amic_m1_init_verbs },
18068 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18070 .dac_nids = alc662_dac_nids,
18071 .dig_out_nid = ALC662_DIGOUT_NID,
18072 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18073 .channel_mode = alc662_3ST_2ch_modes,
18074 .unsol_event = alc_sku_unsol_event,
18075 .setup = alc663_mode3_setup,
18076 .init_hook = alc_inithook,
18078 [ALC663_ASUS_MODE4] = {
18079 .mixers = { alc663_asus_21jd_clfe_mixer },
18080 .cap_mixer = alc662_auto_capture_mixer,
18081 .init_verbs = { alc662_init_verbs,
18082 alc662_eapd_init_verbs,
18083 alc663_21jd_amic_init_verbs},
18084 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18086 .dac_nids = alc662_dac_nids,
18087 .dig_out_nid = ALC662_DIGOUT_NID,
18088 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18089 .channel_mode = alc662_3ST_2ch_modes,
18090 .unsol_event = alc_sku_unsol_event,
18091 .setup = alc663_mode4_setup,
18092 .init_hook = alc_inithook,
18094 [ALC663_ASUS_MODE5] = {
18095 .mixers = { alc663_asus_15jd_clfe_mixer },
18096 .cap_mixer = alc662_auto_capture_mixer,
18097 .init_verbs = { alc662_init_verbs,
18098 alc662_eapd_init_verbs,
18099 alc663_15jd_amic_init_verbs },
18100 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18102 .dac_nids = alc662_dac_nids,
18103 .dig_out_nid = ALC662_DIGOUT_NID,
18104 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18105 .channel_mode = alc662_3ST_2ch_modes,
18106 .unsol_event = alc_sku_unsol_event,
18107 .setup = alc663_mode5_setup,
18108 .init_hook = alc_inithook,
18110 [ALC663_ASUS_MODE6] = {
18111 .mixers = { alc663_two_hp_m2_mixer },
18112 .cap_mixer = alc662_auto_capture_mixer,
18113 .init_verbs = { alc662_init_verbs,
18114 alc662_eapd_init_verbs,
18115 alc663_two_hp_amic_m2_init_verbs },
18116 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18118 .dac_nids = alc662_dac_nids,
18119 .dig_out_nid = ALC662_DIGOUT_NID,
18120 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18121 .channel_mode = alc662_3ST_2ch_modes,
18122 .unsol_event = alc_sku_unsol_event,
18123 .setup = alc663_mode6_setup,
18124 .init_hook = alc_inithook,
18126 [ALC663_ASUS_MODE7] = {
18127 .mixers = { alc663_mode7_mixer },
18128 .cap_mixer = alc662_auto_capture_mixer,
18129 .init_verbs = { alc662_init_verbs,
18130 alc662_eapd_init_verbs,
18131 alc663_mode7_init_verbs },
18132 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18134 .dac_nids = alc662_dac_nids,
18135 .dig_out_nid = ALC662_DIGOUT_NID,
18136 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18137 .channel_mode = alc662_3ST_2ch_modes,
18138 .unsol_event = alc_sku_unsol_event,
18139 .setup = alc663_mode7_setup,
18140 .init_hook = alc_inithook,
18142 [ALC663_ASUS_MODE8] = {
18143 .mixers = { alc663_mode8_mixer },
18144 .cap_mixer = alc662_auto_capture_mixer,
18145 .init_verbs = { alc662_init_verbs,
18146 alc662_eapd_init_verbs,
18147 alc663_mode8_init_verbs },
18148 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18150 .dac_nids = alc662_dac_nids,
18151 .dig_out_nid = ALC662_DIGOUT_NID,
18152 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18153 .channel_mode = alc662_3ST_2ch_modes,
18154 .unsol_event = alc_sku_unsol_event,
18155 .setup = alc663_mode8_setup,
18156 .init_hook = alc_inithook,
18159 .mixers = { alc663_m51va_mixer },
18160 .cap_mixer = alc272_auto_capture_mixer,
18161 .init_verbs = { alc662_init_verbs,
18162 alc662_eapd_init_verbs,
18163 alc272_dell_init_verbs },
18164 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18165 .dac_nids = alc272_dac_nids,
18166 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18167 .adc_nids = alc272_adc_nids,
18168 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18169 .capsrc_nids = alc272_capsrc_nids,
18170 .channel_mode = alc662_3ST_2ch_modes,
18171 .unsol_event = alc_sku_unsol_event,
18172 .setup = alc663_m51va_setup,
18173 .init_hook = alc_inithook,
18175 [ALC272_DELL_ZM1] = {
18176 .mixers = { alc663_m51va_mixer },
18177 .cap_mixer = alc662_auto_capture_mixer,
18178 .init_verbs = { alc662_init_verbs,
18179 alc662_eapd_init_verbs,
18180 alc272_dell_zm1_init_verbs },
18181 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18182 .dac_nids = alc272_dac_nids,
18183 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18184 .adc_nids = alc662_adc_nids,
18186 .capsrc_nids = alc662_capsrc_nids,
18187 .channel_mode = alc662_3ST_2ch_modes,
18188 .unsol_event = alc_sku_unsol_event,
18189 .setup = alc663_m51va_setup,
18190 .init_hook = alc_inithook,
18192 [ALC272_SAMSUNG_NC10] = {
18193 .mixers = { alc272_nc10_mixer },
18194 .init_verbs = { alc662_init_verbs,
18195 alc662_eapd_init_verbs,
18196 alc663_21jd_amic_init_verbs },
18197 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18198 .dac_nids = alc272_dac_nids,
18199 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18200 .channel_mode = alc662_3ST_2ch_modes,
18201 /*.input_mux = &alc272_nc10_capture_source,*/
18202 .unsol_event = alc_sku_unsol_event,
18203 .setup = alc663_mode4_setup,
18204 .init_hook = alc_inithook,
18210 * BIOS auto configuration
18213 /* convert from MIX nid to DAC */
18214 static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18219 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18220 for (i = 0; i < num; i++) {
18221 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18227 /* go down to the selector widget before the mixer */
18228 static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18231 int num = snd_hda_get_connections(codec, pin, srcs,
18234 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18239 /* get MIX nid connected to the given pin targeted to DAC */
18240 static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18246 pin = alc_go_down_to_selector(codec, pin);
18247 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18248 for (i = 0; i < num; i++) {
18249 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18255 /* select the connection from pin to DAC if needed */
18256 static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18262 pin = alc_go_down_to_selector(codec, pin);
18263 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18266 for (i = 0; i < num; i++) {
18267 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18268 snd_hda_codec_update_cache(codec, pin, 0,
18269 AC_VERB_SET_CONNECT_SEL, i);
18276 /* look for an empty DAC slot */
18277 static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18279 struct alc_spec *spec = codec->spec;
18283 pin = alc_go_down_to_selector(codec, pin);
18284 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18285 for (i = 0; i < num; i++) {
18286 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18289 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18290 spec->multiout.num_dacs))
18292 if (spec->multiout.hp_nid == nid)
18294 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18295 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18302 static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18304 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18305 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18306 return alc_auto_look_for_dac(codec, pin);
18310 /* fill in the dac_nids table from the parsed pin configuration */
18311 static int alc_auto_fill_dac_nids(struct hda_codec *codec)
18313 struct alc_spec *spec = codec->spec;
18314 const struct auto_pin_cfg *cfg = &spec->autocfg;
18315 bool redone = false;
18319 spec->multiout.num_dacs = 0;
18320 spec->multiout.hp_nid = 0;
18321 spec->multiout.extra_out_nid[0] = 0;
18322 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18323 spec->multiout.dac_nids = spec->private_dac_nids;
18325 /* fill hard-wired DACs first */
18327 for (i = 0; i < cfg->line_outs; i++)
18328 spec->private_dac_nids[i] =
18329 get_dac_if_single(codec, cfg->line_out_pins[i]);
18331 spec->multiout.hp_nid =
18332 get_dac_if_single(codec, cfg->hp_pins[0]);
18333 if (cfg->speaker_outs)
18334 spec->multiout.extra_out_nid[0] =
18335 get_dac_if_single(codec, cfg->speaker_pins[0]);
18338 for (i = 0; i < cfg->line_outs; i++) {
18339 hda_nid_t pin = cfg->line_out_pins[i];
18340 if (spec->private_dac_nids[i])
18342 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18343 if (!spec->private_dac_nids[i] && !redone) {
18344 /* if we can't find primary DACs, re-probe without
18345 * checking the hard-wired DACs
18352 for (i = 0; i < cfg->line_outs; i++) {
18353 if (spec->private_dac_nids[i])
18354 spec->multiout.num_dacs++;
18356 memmove(spec->private_dac_nids + i,
18357 spec->private_dac_nids + i + 1,
18358 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
18361 if (cfg->hp_outs && !spec->multiout.hp_nid)
18362 spec->multiout.hp_nid =
18363 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
18364 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
18365 spec->multiout.extra_out_nid[0] =
18366 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
18371 static int alc_auto_add_vol_ctl(struct hda_codec *codec,
18372 const char *pfx, int cidx,
18373 hda_nid_t nid, unsigned int chs)
18375 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
18376 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18379 #define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
18380 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
18382 /* create a mute-switch for the given mixer widget;
18383 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
18385 static int alc_auto_add_sw_ctl(struct hda_codec *codec,
18386 const char *pfx, int cidx,
18387 hda_nid_t nid, unsigned int chs)
18391 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
18392 type = ALC_CTL_WIDGET_MUTE;
18393 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
18395 type = ALC_CTL_BIND_MUTE;
18396 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
18398 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
18401 #define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
18402 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
18404 /* add playback controls from the parsed DAC table */
18405 static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
18406 const struct auto_pin_cfg *cfg)
18408 struct alc_spec *spec = codec->spec;
18409 hda_nid_t nid, mix, pin;
18410 int i, err, noutputs;
18412 noutputs = cfg->line_outs;
18413 if (spec->multi_ios > 0)
18414 noutputs += spec->multi_ios;
18416 for (i = 0; i < noutputs; i++) {
18419 nid = spec->multiout.dac_nids[i];
18422 if (i >= cfg->line_outs)
18423 pin = spec->multi_io[i - 1].pin;
18425 pin = cfg->line_out_pins[i];
18426 mix = alc_auto_dac_to_mix(codec, pin, nid);
18429 name = alc_get_line_out_pfx(spec, i, true, &index);
18432 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1);
18435 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2);
18438 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1);
18441 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2);
18445 err = alc_auto_add_stereo_vol(codec, name, index, nid);
18448 err = alc_auto_add_stereo_sw(codec, name, index, mix);
18456 /* add playback controls for speaker and HP outputs */
18457 static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18458 hda_nid_t dac, const char *pfx)
18460 struct alc_spec *spec = codec->spec;
18467 /* the corresponding DAC is already occupied */
18468 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18469 return 0; /* no way */
18470 /* create a switch only */
18471 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18472 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18475 mix = alc_auto_dac_to_mix(codec, pin, dac);
18478 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
18481 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix);
18487 static int alc_auto_create_hp_out(struct hda_codec *codec)
18489 struct alc_spec *spec = codec->spec;
18490 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18491 spec->multiout.hp_nid,
18495 static int alc_auto_create_speaker_out(struct hda_codec *codec)
18497 struct alc_spec *spec = codec->spec;
18498 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
18499 spec->multiout.extra_out_nid[0],
18503 static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
18504 hda_nid_t nid, int pin_type,
18509 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18511 alc_set_pin_output(codec, nid, pin_type);
18512 nid = alc_go_down_to_selector(codec, nid);
18513 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18514 for (i = 0; i < num; i++) {
18515 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
18523 /* need the manual connection? */
18525 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18526 /* unmute mixer widget inputs */
18527 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18529 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18531 /* initialize volume */
18532 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18534 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18538 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18542 static void alc_auto_init_multi_out(struct hda_codec *codec)
18544 struct alc_spec *spec = codec->spec;
18545 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18548 for (i = 0; i <= HDA_SIDE; i++) {
18549 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18551 alc_auto_set_output_and_unmute(codec, nid, pin_type,
18552 spec->multiout.dac_nids[i]);
18556 static void alc_auto_init_extra_out(struct hda_codec *codec)
18558 struct alc_spec *spec = codec->spec;
18561 pin = spec->autocfg.hp_pins[0];
18563 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
18564 spec->multiout.hp_nid);
18565 pin = spec->autocfg.speaker_pins[0];
18567 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18568 spec->multiout.extra_out_nid[0]);
18574 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
18575 unsigned int location)
18577 struct alc_spec *spec = codec->spec;
18578 struct auto_pin_cfg *cfg = &spec->autocfg;
18579 int type, i, num_pins = 0;
18581 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
18582 for (i = 0; i < cfg->num_inputs; i++) {
18583 hda_nid_t nid = cfg->inputs[i].pin;
18585 unsigned int defcfg, caps;
18586 if (cfg->inputs[i].type != type)
18588 defcfg = snd_hda_codec_get_pincfg(codec, nid);
18589 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
18591 if (location && get_defcfg_location(defcfg) != location)
18593 caps = snd_hda_query_pin_caps(codec, nid);
18594 if (!(caps & AC_PINCAP_OUT))
18596 dac = alc_auto_look_for_dac(codec, nid);
18599 spec->multi_io[num_pins].pin = nid;
18600 spec->multi_io[num_pins].dac = dac;
18602 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18605 spec->multiout.num_dacs = 1;
18611 static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
18612 struct snd_ctl_elem_info *uinfo)
18614 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18615 struct alc_spec *spec = codec->spec;
18617 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
18619 uinfo->value.enumerated.items = spec->multi_ios + 1;
18620 if (uinfo->value.enumerated.item > spec->multi_ios)
18621 uinfo->value.enumerated.item = spec->multi_ios;
18622 sprintf(uinfo->value.enumerated.name, "%dch",
18623 (uinfo->value.enumerated.item + 1) * 2);
18627 static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
18628 struct snd_ctl_elem_value *ucontrol)
18630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18631 struct alc_spec *spec = codec->spec;
18632 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
18636 static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
18638 struct alc_spec *spec = codec->spec;
18639 hda_nid_t nid = spec->multi_io[idx].pin;
18641 if (!spec->multi_io[idx].ctl_in)
18642 spec->multi_io[idx].ctl_in =
18643 snd_hda_codec_read(codec, nid, 0,
18644 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
18646 snd_hda_codec_update_cache(codec, nid, 0,
18647 AC_VERB_SET_PIN_WIDGET_CONTROL,
18649 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18650 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18652 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
18654 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18655 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18656 HDA_AMP_MUTE, HDA_AMP_MUTE);
18657 snd_hda_codec_update_cache(codec, nid, 0,
18658 AC_VERB_SET_PIN_WIDGET_CONTROL,
18659 spec->multi_io[idx].ctl_in);
18664 static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
18665 struct snd_ctl_elem_value *ucontrol)
18667 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18668 struct alc_spec *spec = codec->spec;
18671 ch = ucontrol->value.enumerated.item[0];
18672 if (ch < 0 || ch > spec->multi_ios)
18674 if (ch == (spec->ext_channel_count - 1) / 2)
18676 spec->ext_channel_count = (ch + 1) * 2;
18677 for (i = 0; i < spec->multi_ios; i++)
18678 alc_set_multi_io(codec, i, i < ch);
18679 spec->multiout.max_channels = spec->ext_channel_count;
18683 static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
18684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
18685 .name = "Channel Mode",
18686 .info = alc_auto_ch_mode_info,
18687 .get = alc_auto_ch_mode_get,
18688 .put = alc_auto_ch_mode_put,
18691 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
18692 int (*fill_dac)(struct hda_codec *))
18694 struct alc_spec *spec = codec->spec;
18695 struct auto_pin_cfg *cfg = &spec->autocfg;
18696 unsigned int location, defcfg;
18699 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
18700 /* use HP as primary out */
18701 cfg->speaker_outs = cfg->line_outs;
18702 memcpy(cfg->speaker_pins, cfg->line_out_pins,
18703 sizeof(cfg->speaker_pins));
18704 cfg->line_outs = cfg->hp_outs;
18705 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
18707 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
18708 cfg->line_out_type = AUTO_PIN_HP_OUT;
18712 if (cfg->line_outs != 1 ||
18713 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18716 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
18717 location = get_defcfg_location(defcfg);
18719 num_pins = alc_auto_fill_multi_ios(codec, location);
18720 if (num_pins > 0) {
18721 struct snd_kcontrol_new *knew;
18723 knew = alc_kcontrol_new(spec);
18726 *knew = alc_auto_channel_mode_enum;
18727 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
18731 spec->multi_ios = num_pins;
18732 spec->ext_channel_count = 2;
18733 spec->multiout.num_dacs = num_pins + 1;
18738 static int alc662_parse_auto_config(struct hda_codec *codec)
18740 struct alc_spec *spec = codec->spec;
18742 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18744 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18748 if (!spec->autocfg.line_outs)
18749 return 0; /* can't find valid BIOS pin config */
18751 err = alc_auto_fill_dac_nids(codec);
18754 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
18757 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
18760 err = alc_auto_create_extra_out(codec,
18761 spec->autocfg.speaker_pins[0],
18762 spec->multiout.extra_out_nid[0],
18766 err = alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18767 spec->multiout.hp_nid,
18771 err = alc_auto_create_input_ctls(codec);
18775 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18777 alc_auto_parse_digital(codec);
18779 if (spec->kctls.list)
18780 add_mixer(spec, spec->kctls.list);
18782 spec->num_mux_defs = 1;
18783 spec->input_mux = &spec->private_imux[0];
18785 if (!spec->dual_adc_switch)
18786 alc_remove_invalid_adc_nids(codec);
18788 err = alc_auto_add_mic_boost(codec);
18792 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18793 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18794 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18796 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
18801 /* additional initialization for auto-configuration model */
18802 static void alc662_auto_init(struct hda_codec *codec)
18804 struct alc_spec *spec = codec->spec;
18805 alc_auto_init_multi_out(codec);
18806 alc_auto_init_extra_out(codec);
18807 alc_auto_init_analog_input(codec);
18808 alc_auto_init_input_src(codec);
18809 alc_auto_init_digital(codec);
18810 if (spec->unsol_event)
18811 alc_inithook(codec);
18814 static void alc272_fixup_mario(struct hda_codec *codec,
18815 const struct alc_fixup *fix, int action)
18817 if (action != ALC_FIXUP_ACT_PROBE)
18819 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
18820 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
18821 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
18822 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
18823 (0 << AC_AMPCAP_MUTE_SHIFT)))
18824 printk(KERN_WARNING
18825 "hda_codec: failed to override amp caps for NID 0x2\n");
18829 ALC662_FIXUP_ASPIRE,
18830 ALC662_FIXUP_IDEAPAD,
18831 ALC272_FIXUP_MARIO,
18832 ALC662_FIXUP_CZC_P10T,
18833 ALC662_FIXUP_SKU_IGNORE,
18836 static const struct alc_fixup alc662_fixups[] = {
18837 [ALC662_FIXUP_ASPIRE] = {
18838 .type = ALC_FIXUP_PINS,
18839 .v.pins = (const struct alc_pincfg[]) {
18840 { 0x15, 0x99130112 }, /* subwoofer */
18844 [ALC662_FIXUP_IDEAPAD] = {
18845 .type = ALC_FIXUP_PINS,
18846 .v.pins = (const struct alc_pincfg[]) {
18847 { 0x17, 0x99130112 }, /* subwoofer */
18851 [ALC272_FIXUP_MARIO] = {
18852 .type = ALC_FIXUP_FUNC,
18853 .v.func = alc272_fixup_mario,
18855 [ALC662_FIXUP_CZC_P10T] = {
18856 .type = ALC_FIXUP_VERBS,
18857 .v.verbs = (const struct hda_verb[]) {
18858 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
18862 [ALC662_FIXUP_SKU_IGNORE] = {
18863 .type = ALC_FIXUP_SKU,
18864 .v.sku = ALC_FIXUP_SKU_IGNORE,
18868 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
18869 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
18870 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
18871 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
18872 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
18873 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
18874 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
18875 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
18879 static const struct alc_model_fixup alc662_fixup_models[] = {
18880 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
18885 static int patch_alc662(struct hda_codec *codec)
18887 struct alc_spec *spec;
18888 int err, board_config;
18891 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18895 codec->spec = spec;
18897 spec->mixer_nid = 0x0b;
18899 alc_auto_parse_customize_define(codec);
18901 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18903 coef = alc_read_coef_idx(codec, 0);
18904 if (coef == 0x8020 || coef == 0x8011)
18905 alc_codec_rename(codec, "ALC661");
18906 else if (coef & (1 << 14) &&
18907 codec->bus->pci->subsystem_vendor == 0x1025 &&
18908 spec->cdefine.platform_type == 1)
18909 alc_codec_rename(codec, "ALC272X");
18910 else if (coef == 0x4011)
18911 alc_codec_rename(codec, "ALC656");
18913 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18916 if (board_config < 0) {
18917 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18919 board_config = ALC662_AUTO;
18922 if (board_config == ALC662_AUTO) {
18923 alc_pick_fixup(codec, alc662_fixup_models,
18924 alc662_fixup_tbl, alc662_fixups);
18925 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
18926 /* automatic parse from the BIOS config */
18927 err = alc662_parse_auto_config(codec);
18933 "hda_codec: Cannot set up configuration "
18934 "from BIOS. Using base mode...\n");
18935 board_config = ALC662_3ST_2ch_DIG;
18939 if (has_cdefine_beep(codec)) {
18940 err = snd_hda_attach_beep_device(codec, 0x1);
18947 if (board_config != ALC662_AUTO)
18948 setup_preset(codec, &alc662_presets[board_config]);
18950 if (!spec->adc_nids) {
18951 alc_auto_fill_adc_caps(codec);
18952 alc_remove_invalid_adc_nids(codec);
18955 if (!spec->cap_mixer)
18956 set_capture_mixer(codec);
18958 if (has_cdefine_beep(codec)) {
18959 switch (codec->vendor_id) {
18961 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18966 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18969 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18973 spec->vmaster_nid = 0x02;
18975 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18977 codec->patch_ops = alc_patch_ops;
18978 if (board_config == ALC662_AUTO)
18979 spec->init_hook = alc662_auto_init;
18980 spec->shutup = alc_eapd_shutup;
18982 alc_init_jacks(codec);
18984 #ifdef CONFIG_SND_HDA_POWER_SAVE
18985 if (!spec->loopback.amplist)
18986 spec->loopback.amplist = alc662_loopbacks;
18992 static int patch_alc888(struct hda_codec *codec)
18994 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18995 kfree(codec->chip_name);
18996 if (codec->vendor_id == 0x10ec0887)
18997 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
18999 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19000 if (!codec->chip_name) {
19004 return patch_alc662(codec);
19006 return patch_alc882(codec);
19009 static int patch_alc899(struct hda_codec *codec)
19011 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19012 kfree(codec->chip_name);
19013 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19015 return patch_alc882(codec);
19021 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19022 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19023 #define alc680_modes alc260_modes
19025 static const hda_nid_t alc680_dac_nids[3] = {
19026 /* Lout1, Lout2, hp */
19030 static const hda_nid_t alc680_adc_nids[3] = {
19032 /* DMIC, MIC, Line-in*/
19037 * Analog capture ADC cgange
19039 static void alc680_rec_autoswitch(struct hda_codec *codec)
19041 struct alc_spec *spec = codec->spec;
19042 struct auto_pin_cfg *cfg = &spec->autocfg;
19044 int type_found = AUTO_PIN_LAST;
19048 for (i = 0; i < cfg->num_inputs; i++) {
19049 nid = cfg->inputs[i].pin;
19050 if (!is_jack_detectable(codec, nid))
19052 if (snd_hda_jack_detect(codec, nid)) {
19053 if (cfg->inputs[i].type < type_found) {
19054 type_found = cfg->inputs[i].type;
19062 snd_hda_get_connections(codec, pin_found, &nid, 1);
19064 if (nid != spec->cur_adc)
19065 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19066 spec->cur_adc = nid;
19067 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19068 spec->cur_adc_format);
19071 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19072 struct hda_codec *codec,
19073 unsigned int stream_tag,
19074 unsigned int format,
19075 struct snd_pcm_substream *substream)
19077 struct alc_spec *spec = codec->spec;
19079 spec->cur_adc = 0x07;
19080 spec->cur_adc_stream_tag = stream_tag;
19081 spec->cur_adc_format = format;
19083 alc680_rec_autoswitch(codec);
19087 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19088 struct hda_codec *codec,
19089 struct snd_pcm_substream *substream)
19091 snd_hda_codec_cleanup_stream(codec, 0x07);
19092 snd_hda_codec_cleanup_stream(codec, 0x08);
19093 snd_hda_codec_cleanup_stream(codec, 0x09);
19097 static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19098 .substreams = 1, /* can be overridden */
19101 /* NID is set in alc_build_pcms */
19103 .prepare = alc680_capture_pcm_prepare,
19104 .cleanup = alc680_capture_pcm_cleanup
19108 static const struct snd_kcontrol_new alc680_base_mixer[] = {
19109 /* output mixer control */
19110 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19111 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19112 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19113 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19114 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19116 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19120 static const struct hda_bind_ctls alc680_bind_cap_vol = {
19121 .ops = &snd_hda_bind_vol,
19123 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19124 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19125 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19130 static const struct hda_bind_ctls alc680_bind_cap_switch = {
19131 .ops = &snd_hda_bind_sw,
19133 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19134 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19135 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19140 static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19141 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19142 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19147 * generic initialization of ADC, input mixers and output mixers
19149 static const struct hda_verb alc680_init_verbs[] = {
19150 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19151 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19152 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19154 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19155 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19157 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19158 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19159 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19161 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19162 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19163 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19164 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19165 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19167 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19168 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19169 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19174 /* toggle speaker-output according to the hp-jack state */
19175 static void alc680_base_setup(struct hda_codec *codec)
19177 struct alc_spec *spec = codec->spec;
19179 spec->autocfg.hp_pins[0] = 0x16;
19180 spec->autocfg.speaker_pins[0] = 0x14;
19181 spec->autocfg.speaker_pins[1] = 0x15;
19182 spec->autocfg.num_inputs = 2;
19183 spec->autocfg.inputs[0].pin = 0x18;
19184 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19185 spec->autocfg.inputs[1].pin = 0x19;
19186 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19187 spec->automute = 1;
19188 spec->automute_mode = ALC_AUTOMUTE_AMP;
19191 static void alc680_unsol_event(struct hda_codec *codec,
19194 if ((res >> 26) == ALC880_HP_EVENT)
19195 alc_hp_automute(codec);
19196 if ((res >> 26) == ALC880_MIC_EVENT)
19197 alc680_rec_autoswitch(codec);
19200 static void alc680_inithook(struct hda_codec *codec)
19202 alc_hp_automute(codec);
19203 alc680_rec_autoswitch(codec);
19206 /* create input playback/capture controls for the given pin */
19207 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19208 const char *ctlname, int idx)
19226 if (spec->multiout.dac_nids[0] != dac &&
19227 spec->multiout.dac_nids[1] != dac) {
19228 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19229 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19234 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19235 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19239 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19245 /* add playback controls from the parsed DAC table */
19246 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19247 const struct auto_pin_cfg *cfg)
19252 spec->multiout.dac_nids = spec->private_dac_nids;
19254 nid = cfg->line_out_pins[0];
19258 name = alc_get_line_out_pfx(spec, 0, true, &index);
19259 err = alc680_new_analog_output(spec, nid, name, 0);
19264 nid = cfg->speaker_pins[0];
19266 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19270 nid = cfg->hp_pins[0];
19272 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19280 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19281 hda_nid_t nid, int pin_type)
19283 alc_set_pin_output(codec, nid, pin_type);
19286 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19288 struct alc_spec *spec = codec->spec;
19289 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19291 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19292 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19296 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19298 struct alc_spec *spec = codec->spec;
19301 pin = spec->autocfg.hp_pins[0];
19303 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19304 pin = spec->autocfg.speaker_pins[0];
19306 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19310 * BIOS auto configuration
19312 static int alc680_parse_auto_config(struct hda_codec *codec)
19314 struct alc_spec *spec = codec->spec;
19316 static const hda_nid_t alc680_ignore[] = { 0 };
19318 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19323 if (!spec->autocfg.line_outs) {
19324 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19325 spec->multiout.max_channels = 2;
19326 spec->no_analog = 1;
19329 return 0; /* can't find valid BIOS pin config */
19331 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19335 spec->multiout.max_channels = 2;
19338 /* digital only support output */
19339 alc_auto_parse_digital(codec);
19340 if (spec->kctls.list)
19341 add_mixer(spec, spec->kctls.list);
19343 err = alc_auto_add_mic_boost(codec);
19350 /* init callback for auto-configuration model -- overriding the default init */
19351 static void alc680_auto_init(struct hda_codec *codec)
19353 struct alc_spec *spec = codec->spec;
19354 alc680_auto_init_multi_out(codec);
19355 alc680_auto_init_hp_out(codec);
19356 alc_auto_init_analog_input(codec);
19357 alc_auto_init_digital(codec);
19358 if (spec->unsol_event)
19359 alc_inithook(codec);
19363 * configuration and preset
19365 static const char * const alc680_models[ALC680_MODEL_LAST] = {
19366 [ALC680_BASE] = "base",
19367 [ALC680_AUTO] = "auto",
19370 static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19371 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19375 static const struct alc_config_preset alc680_presets[] = {
19377 .mixers = { alc680_base_mixer },
19378 .cap_mixer = alc680_master_capture_mixer,
19379 .init_verbs = { alc680_init_verbs },
19380 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19381 .dac_nids = alc680_dac_nids,
19382 .dig_out_nid = ALC680_DIGOUT_NID,
19383 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19384 .channel_mode = alc680_modes,
19385 .unsol_event = alc680_unsol_event,
19386 .setup = alc680_base_setup,
19387 .init_hook = alc680_inithook,
19392 static int patch_alc680(struct hda_codec *codec)
19394 struct alc_spec *spec;
19398 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19402 codec->spec = spec;
19404 /* ALC680 has no aa-loopback mixer */
19406 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19410 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19411 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19413 board_config = ALC680_AUTO;
19416 if (board_config == ALC680_AUTO) {
19417 /* automatic parse from the BIOS config */
19418 err = alc680_parse_auto_config(codec);
19424 "hda_codec: Cannot set up configuration "
19425 "from BIOS. Using base mode...\n");
19426 board_config = ALC680_BASE;
19430 if (board_config != ALC680_AUTO)
19431 setup_preset(codec, &alc680_presets[board_config]);
19433 if (!spec->adc_nids) {
19434 alc_auto_fill_adc_caps(codec);
19435 alc_remove_invalid_adc_nids(codec);
19438 if (!spec->cap_mixer)
19439 set_capture_mixer(codec);
19441 spec->vmaster_nid = 0x02;
19443 codec->patch_ops = alc_patch_ops;
19444 if (board_config == ALC680_AUTO)
19445 spec->init_hook = alc680_auto_init;
19453 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
19454 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
19455 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
19456 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
19457 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
19458 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
19459 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
19460 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
19461 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
19462 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
19463 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
19464 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
19465 .patch = patch_alc861 },
19466 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19467 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19468 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
19469 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
19470 .patch = patch_alc882 },
19471 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19472 .patch = patch_alc662 },
19473 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
19474 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
19475 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
19476 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
19477 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
19478 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
19479 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
19480 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
19481 .patch = patch_alc882 },
19482 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
19483 .patch = patch_alc882 },
19484 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
19485 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
19486 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
19487 .patch = patch_alc882 },
19488 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
19489 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
19490 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
19491 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
19492 {} /* terminator */
19495 MODULE_ALIAS("snd-hda-codec-id:10ec*");
19497 MODULE_LICENSE("GPL");
19498 MODULE_DESCRIPTION("Realtek HD-audio codec");
19500 static struct hda_codec_preset_list realtek_list = {
19501 .preset = snd_hda_preset_realtek,
19502 .owner = THIS_MODULE,
19505 static int __init patch_realtek_init(void)
19507 return snd_hda_add_codec_preset(&realtek_list);
19510 static void __exit patch_realtek_exit(void)
19512 snd_hda_delete_codec_preset(&realtek_list);
19515 module_init(patch_realtek_init)
19516 module_exit(patch_realtek_exit)