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 */
303 /* codec parameterization */
304 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
305 unsigned int num_mixers;
306 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
307 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
309 const struct hda_verb *init_verbs[10]; /* initialization verbs
313 unsigned int num_init_verbs;
315 char stream_name_analog[32]; /* analog PCM stream */
316 struct hda_pcm_stream *stream_analog_playback;
317 struct hda_pcm_stream *stream_analog_capture;
318 struct hda_pcm_stream *stream_analog_alt_playback;
319 struct hda_pcm_stream *stream_analog_alt_capture;
321 char stream_name_digital[32]; /* digital PCM stream */
322 struct hda_pcm_stream *stream_digital_playback;
323 struct hda_pcm_stream *stream_digital_capture;
326 struct hda_multi_out multiout; /* playback set-up
327 * max_channels, dacs must be set
328 * dig_out_nid and hp_nid are optional
330 hda_nid_t alt_dac_nid;
331 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
335 unsigned int num_adc_nids;
337 hda_nid_t *capsrc_nids;
338 hda_nid_t dig_in_nid; /* digital-in NID; optional */
340 /* capture setup for dynamic dual-adc switch */
341 unsigned int cur_adc_idx;
343 unsigned int cur_adc_stream_tag;
344 unsigned int cur_adc_format;
347 unsigned int num_mux_defs;
348 const struct hda_input_mux *input_mux;
349 unsigned int cur_mux[3];
350 struct alc_mic_route ext_mic;
351 struct alc_mic_route int_mic;
354 const struct hda_channel_mode *channel_mode;
355 int num_channel_mode;
357 int const_channel_count;
358 int ext_channel_count;
360 /* PCM information */
361 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
363 /* dynamic controls, init_verbs and input_mux */
364 struct auto_pin_cfg autocfg;
365 struct alc_customize_define cdefine;
366 struct snd_array kctls;
367 struct hda_input_mux private_imux[3];
368 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
369 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
370 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
373 void (*init_hook)(struct hda_codec *codec);
374 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
375 #ifdef CONFIG_SND_HDA_POWER_SAVE
376 void (*power_hook)(struct hda_codec *codec);
378 void (*shutup)(struct hda_codec *codec);
380 /* for pin sensing */
381 unsigned int sense_updated: 1;
382 unsigned int jack_present: 1;
383 unsigned int master_sw: 1;
384 unsigned int auto_mic:1;
387 unsigned int no_analog :1; /* digital I/O only */
388 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
389 unsigned int single_input_src:1;
391 int codec_variant; /* flag for other variants */
393 /* for virtual master */
394 hda_nid_t vmaster_nid;
395 #ifdef CONFIG_SND_HDA_POWER_SAVE
396 struct hda_loopback_check loopback;
401 unsigned int pll_coef_idx, pll_coef_bit;
405 const struct alc_fixup *fixup_list;
406 const char *fixup_name;
410 * configuration template - to be copied to the spec instance
412 struct alc_config_preset {
413 struct snd_kcontrol_new *mixers[5]; /* should be identical size
416 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
417 const struct hda_verb *init_verbs[5];
418 unsigned int num_dacs;
420 hda_nid_t dig_out_nid; /* optional */
421 hda_nid_t hp_nid; /* optional */
422 hda_nid_t *slave_dig_outs;
423 unsigned int num_adc_nids;
425 hda_nid_t *capsrc_nids;
426 hda_nid_t dig_in_nid;
427 unsigned int num_channel_mode;
428 const struct hda_channel_mode *channel_mode;
430 int const_channel_count;
431 unsigned int num_mux_defs;
432 const struct hda_input_mux *input_mux;
433 void (*unsol_event)(struct hda_codec *, unsigned int);
434 void (*setup)(struct hda_codec *);
435 void (*init_hook)(struct hda_codec *);
436 #ifdef CONFIG_SND_HDA_POWER_SAVE
437 struct hda_amp_list *loopbacks;
438 void (*power_hook)(struct hda_codec *codec);
446 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
447 struct snd_ctl_elem_info *uinfo)
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 struct alc_spec *spec = codec->spec;
451 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
452 if (mux_idx >= spec->num_mux_defs)
454 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
456 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
459 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_value *ucontrol)
462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
463 struct alc_spec *spec = codec->spec;
464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
466 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
470 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 struct alc_spec *spec = codec->spec;
475 const struct hda_input_mux *imux;
476 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
477 unsigned int mux_idx;
478 hda_nid_t nid = spec->capsrc_nids ?
479 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
482 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
483 imux = &spec->input_mux[mux_idx];
484 if (!imux->num_items && mux_idx > 0)
485 imux = &spec->input_mux[0];
487 type = get_wcaps_type(get_wcaps(codec, nid));
488 if (type == AC_WID_AUD_MIX) {
489 /* Matrix-mixer style (e.g. ALC882) */
490 unsigned int *cur_val = &spec->cur_mux[adc_idx];
493 idx = ucontrol->value.enumerated.item[0];
494 if (idx >= imux->num_items)
495 idx = imux->num_items - 1;
498 for (i = 0; i < imux->num_items; i++) {
499 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
501 imux->items[i].index,
507 /* MUX style (e.g. ALC880) */
508 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
509 &spec->cur_mux[adc_idx]);
514 * channel mode setting
516 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_info *uinfo)
519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
520 struct alc_spec *spec = codec->spec;
521 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
522 spec->num_channel_mode);
525 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
529 struct alc_spec *spec = codec->spec;
530 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
531 spec->num_channel_mode,
532 spec->ext_channel_count);
535 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
536 struct snd_ctl_elem_value *ucontrol)
538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
539 struct alc_spec *spec = codec->spec;
540 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
541 spec->num_channel_mode,
542 &spec->ext_channel_count);
543 if (err >= 0 && !spec->const_channel_count) {
544 spec->multiout.max_channels = spec->ext_channel_count;
545 if (spec->need_dac_fix)
546 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
552 * Control the mode of pin widget settings via the mixer. "pc" is used
553 * instead of "%" to avoid consequences of accidently treating the % as
554 * being part of a format specifier. Maximum allowed length of a value is
555 * 63 characters plus NULL terminator.
557 * Note: some retasking pin complexes seem to ignore requests for input
558 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
559 * are requested. Therefore order this list so that this behaviour will not
560 * cause problems when mixer clients move through the enum sequentially.
561 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
564 static char *alc_pin_mode_names[] = {
565 "Mic 50pc bias", "Mic 80pc bias",
566 "Line in", "Line out", "Headphone out",
568 static unsigned char alc_pin_mode_values[] = {
569 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
571 /* The control can present all 5 options, or it can limit the options based
572 * in the pin being assumed to be exclusively an input or an output pin. In
573 * addition, "input" pins may or may not process the mic bias option
574 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
575 * accept requests for bias as of chip versions up to March 2006) and/or
576 * wiring in the computer.
578 #define ALC_PIN_DIR_IN 0x00
579 #define ALC_PIN_DIR_OUT 0x01
580 #define ALC_PIN_DIR_INOUT 0x02
581 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
582 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
584 /* Info about the pin modes supported by the different pin direction modes.
585 * For each direction the minimum and maximum values are given.
587 static signed char alc_pin_mode_dir_info[5][2] = {
588 { 0, 2 }, /* ALC_PIN_DIR_IN */
589 { 3, 4 }, /* ALC_PIN_DIR_OUT */
590 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
591 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
592 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
594 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
595 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
596 #define alc_pin_mode_n_items(_dir) \
597 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
599 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
600 struct snd_ctl_elem_info *uinfo)
602 unsigned int item_num = uinfo->value.enumerated.item;
603 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
605 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
607 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
609 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
610 item_num = alc_pin_mode_min(dir);
611 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
615 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
616 struct snd_ctl_elem_value *ucontrol)
619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
620 hda_nid_t nid = kcontrol->private_value & 0xffff;
621 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
622 long *valp = ucontrol->value.integer.value;
623 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
624 AC_VERB_GET_PIN_WIDGET_CONTROL,
627 /* Find enumerated value for current pinctl setting */
628 i = alc_pin_mode_min(dir);
629 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
631 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
635 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *ucontrol)
639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
640 hda_nid_t nid = kcontrol->private_value & 0xffff;
641 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
642 long val = *ucontrol->value.integer.value;
643 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
644 AC_VERB_GET_PIN_WIDGET_CONTROL,
647 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
648 val = alc_pin_mode_min(dir);
650 change = pinctl != alc_pin_mode_values[val];
652 /* Set pin mode to that requested */
653 snd_hda_codec_write_cache(codec, nid, 0,
654 AC_VERB_SET_PIN_WIDGET_CONTROL,
655 alc_pin_mode_values[val]);
657 /* Also enable the retasking pin's input/output as required
658 * for the requested pin mode. Enum values of 2 or less are
661 * Dynamically switching the input/output buffers probably
662 * reduces noise slightly (particularly on input) so we'll
663 * do it. However, having both input and output buffers
664 * enabled simultaneously doesn't seem to be problematic if
665 * this turns out to be necessary in the future.
668 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
669 HDA_AMP_MUTE, HDA_AMP_MUTE);
670 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
673 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
674 HDA_AMP_MUTE, HDA_AMP_MUTE);
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
682 #define ALC_PIN_MODE(xname, nid, dir) \
683 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
684 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
685 .info = alc_pin_mode_info, \
686 .get = alc_pin_mode_get, \
687 .put = alc_pin_mode_put, \
688 .private_value = nid | (dir<<16) }
690 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
691 * together using a mask with more than one bit set. This control is
692 * currently used only by the ALC260 test model. At this stage they are not
693 * needed for any "production" models.
695 #ifdef CONFIG_SND_DEBUG
696 #define alc_gpio_data_info snd_ctl_boolean_mono_info
698 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
699 struct snd_ctl_elem_value *ucontrol)
701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
702 hda_nid_t nid = kcontrol->private_value & 0xffff;
703 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
704 long *valp = ucontrol->value.integer.value;
705 unsigned int val = snd_hda_codec_read(codec, nid, 0,
706 AC_VERB_GET_GPIO_DATA, 0x00);
708 *valp = (val & mask) != 0;
711 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
715 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
716 hda_nid_t nid = kcontrol->private_value & 0xffff;
717 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
718 long val = *ucontrol->value.integer.value;
719 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
720 AC_VERB_GET_GPIO_DATA,
723 /* Set/unset the masked GPIO bit(s) as needed */
724 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
729 snd_hda_codec_write_cache(codec, nid, 0,
730 AC_VERB_SET_GPIO_DATA, gpio_data);
734 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
735 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
737 .info = alc_gpio_data_info, \
738 .get = alc_gpio_data_get, \
739 .put = alc_gpio_data_put, \
740 .private_value = nid | (mask<<16) }
741 #endif /* CONFIG_SND_DEBUG */
743 /* A switch control to allow the enabling of the digital IO pins on the
744 * ALC260. This is incredibly simplistic; the intention of this control is
745 * to provide something in the test model allowing digital outputs to be
746 * identified if present. If models are found which can utilise these
747 * outputs a more complete mixer control can be devised for those models if
750 #ifdef CONFIG_SND_DEBUG
751 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
753 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
754 struct snd_ctl_elem_value *ucontrol)
756 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
757 hda_nid_t nid = kcontrol->private_value & 0xffff;
758 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
759 long *valp = ucontrol->value.integer.value;
760 unsigned int val = snd_hda_codec_read(codec, nid, 0,
761 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
763 *valp = (val & mask) != 0;
766 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
767 struct snd_ctl_elem_value *ucontrol)
770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
771 hda_nid_t nid = kcontrol->private_value & 0xffff;
772 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
773 long val = *ucontrol->value.integer.value;
774 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
775 AC_VERB_GET_DIGI_CONVERT_1,
778 /* Set/unset the masked control bit(s) as needed */
779 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
784 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
789 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
791 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
792 .info = alc_spdif_ctrl_info, \
793 .get = alc_spdif_ctrl_get, \
794 .put = alc_spdif_ctrl_put, \
795 .private_value = nid | (mask<<16) }
796 #endif /* CONFIG_SND_DEBUG */
798 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
799 * Again, this is only used in the ALC26x test models to help identify when
800 * the EAPD line must be asserted for features to work.
802 #ifdef CONFIG_SND_DEBUG
803 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
805 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
806 struct snd_ctl_elem_value *ucontrol)
808 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
809 hda_nid_t nid = kcontrol->private_value & 0xffff;
810 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
811 long *valp = ucontrol->value.integer.value;
812 unsigned int val = snd_hda_codec_read(codec, nid, 0,
813 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
815 *valp = (val & mask) != 0;
819 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
820 struct snd_ctl_elem_value *ucontrol)
823 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
824 hda_nid_t nid = kcontrol->private_value & 0xffff;
825 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
826 long val = *ucontrol->value.integer.value;
827 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
828 AC_VERB_GET_EAPD_BTLENABLE,
831 /* Set/unset the masked control bit(s) as needed */
832 change = (!val ? 0 : mask) != (ctrl_data & mask);
837 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
843 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
844 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
845 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
846 .info = alc_eapd_ctrl_info, \
847 .get = alc_eapd_ctrl_get, \
848 .put = alc_eapd_ctrl_put, \
849 .private_value = nid | (mask<<16) }
850 #endif /* CONFIG_SND_DEBUG */
853 * set up the input pin config (depending on the given auto-pin type)
855 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
858 unsigned int val = PIN_IN;
860 if (auto_pin_type == AUTO_PIN_MIC) {
863 oldval = snd_hda_codec_read(codec, nid, 0,
864 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
865 pincap = snd_hda_query_pin_caps(codec, nid);
866 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
867 /* if the default pin setup is vref50, we give it priority */
868 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
870 else if (pincap & AC_PINCAP_VREF_50)
872 else if (pincap & AC_PINCAP_VREF_100)
874 else if (pincap & AC_PINCAP_VREF_GRD)
877 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
880 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
882 struct alc_spec *spec = codec->spec;
883 struct auto_pin_cfg *cfg = &spec->autocfg;
885 if (!cfg->line_outs) {
886 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
887 cfg->line_out_pins[cfg->line_outs])
890 if (!cfg->speaker_outs) {
891 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
892 cfg->speaker_pins[cfg->speaker_outs])
896 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
897 cfg->hp_pins[cfg->hp_outs])
904 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
906 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
908 spec->mixers[spec->num_mixers++] = mix;
911 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
913 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
915 spec->init_verbs[spec->num_init_verbs++] = verb;
919 * set up from the preset table
921 static void setup_preset(struct hda_codec *codec,
922 const struct alc_config_preset *preset)
924 struct alc_spec *spec = codec->spec;
927 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
928 add_mixer(spec, preset->mixers[i]);
929 spec->cap_mixer = preset->cap_mixer;
930 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
932 add_verb(spec, preset->init_verbs[i]);
934 spec->channel_mode = preset->channel_mode;
935 spec->num_channel_mode = preset->num_channel_mode;
936 spec->need_dac_fix = preset->need_dac_fix;
937 spec->const_channel_count = preset->const_channel_count;
939 if (preset->const_channel_count)
940 spec->multiout.max_channels = preset->const_channel_count;
942 spec->multiout.max_channels = spec->channel_mode[0].channels;
943 spec->ext_channel_count = spec->channel_mode[0].channels;
945 spec->multiout.num_dacs = preset->num_dacs;
946 spec->multiout.dac_nids = preset->dac_nids;
947 spec->multiout.dig_out_nid = preset->dig_out_nid;
948 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
949 spec->multiout.hp_nid = preset->hp_nid;
951 spec->num_mux_defs = preset->num_mux_defs;
952 if (!spec->num_mux_defs)
953 spec->num_mux_defs = 1;
954 spec->input_mux = preset->input_mux;
956 spec->num_adc_nids = preset->num_adc_nids;
957 spec->adc_nids = preset->adc_nids;
958 spec->capsrc_nids = preset->capsrc_nids;
959 spec->dig_in_nid = preset->dig_in_nid;
961 spec->unsol_event = preset->unsol_event;
962 spec->init_hook = preset->init_hook;
963 #ifdef CONFIG_SND_HDA_POWER_SAVE
964 spec->power_hook = preset->power_hook;
965 spec->loopback.amplist = preset->loopbacks;
969 preset->setup(codec);
971 alc_fixup_autocfg_pin_nums(codec);
974 /* Enable GPIO mask and set output */
975 static struct hda_verb alc_gpio1_init_verbs[] = {
976 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
977 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
978 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
982 static struct hda_verb alc_gpio2_init_verbs[] = {
983 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
985 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
989 static struct hda_verb alc_gpio3_init_verbs[] = {
990 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
992 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
997 * Fix hardware PLL issue
998 * On some codecs, the analog PLL gating control must be off while
999 * the default value is 1.
1001 static void alc_fix_pll(struct hda_codec *codec)
1003 struct alc_spec *spec = codec->spec;
1008 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1009 spec->pll_coef_idx);
1010 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1011 AC_VERB_GET_PROC_COEF, 0);
1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1013 spec->pll_coef_idx);
1014 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1015 val & ~(1 << spec->pll_coef_bit));
1018 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1019 unsigned int coef_idx, unsigned int coef_bit)
1021 struct alc_spec *spec = codec->spec;
1022 spec->pll_nid = nid;
1023 spec->pll_coef_idx = coef_idx;
1024 spec->pll_coef_bit = coef_bit;
1028 static int alc_init_jacks(struct hda_codec *codec)
1030 #ifdef CONFIG_SND_HDA_INPUT_JACK
1031 struct alc_spec *spec = codec->spec;
1033 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1034 unsigned int mic_nid = spec->ext_mic.pin;
1037 err = snd_hda_input_jack_add(codec, hp_nid,
1038 SND_JACK_HEADPHONE, NULL);
1041 snd_hda_input_jack_report(codec, hp_nid);
1045 err = snd_hda_input_jack_add(codec, mic_nid,
1046 SND_JACK_MICROPHONE, NULL);
1049 snd_hda_input_jack_report(codec, mic_nid);
1051 #endif /* CONFIG_SND_HDA_INPUT_JACK */
1055 static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1057 struct alc_spec *spec = codec->spec;
1062 spec->jack_present = 0;
1063 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1064 nid = spec->autocfg.hp_pins[i];
1067 snd_hda_input_jack_report(codec, nid);
1068 spec->jack_present |= snd_hda_jack_detect(codec, nid);
1071 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1072 /* Toggle internal speakers muting */
1073 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1074 nid = spec->autocfg.speaker_pins[i];
1078 snd_hda_codec_write(codec, nid, 0,
1079 AC_VERB_SET_PIN_WIDGET_CONTROL,
1080 spec->jack_present ? 0 : PIN_OUT);
1082 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1083 HDA_AMP_MUTE, mute);
1088 static void alc_automute_pin(struct hda_codec *codec)
1090 alc_automute_speaker(codec, 1);
1093 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1096 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1099 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1100 for (i = 0; i < nums; i++)
1106 /* switch the current ADC according to the jack state */
1107 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1109 struct alc_spec *spec = codec->spec;
1110 unsigned int present;
1113 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1115 spec->cur_adc_idx = 1;
1117 spec->cur_adc_idx = 0;
1118 new_adc = spec->adc_nids[spec->cur_adc_idx];
1119 if (spec->cur_adc && spec->cur_adc != new_adc) {
1120 /* stream is running, let's swap the current ADC */
1121 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1122 spec->cur_adc = new_adc;
1123 snd_hda_codec_setup_stream(codec, new_adc,
1124 spec->cur_adc_stream_tag, 0,
1125 spec->cur_adc_format);
1129 static void alc_mic_automute(struct hda_codec *codec)
1131 struct alc_spec *spec = codec->spec;
1132 struct alc_mic_route *dead, *alive;
1133 unsigned int present, type;
1136 if (!spec->auto_mic)
1138 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1140 if (snd_BUG_ON(!spec->adc_nids))
1143 if (spec->dual_adc_switch) {
1144 alc_dual_mic_adc_auto_switch(codec);
1148 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1150 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1152 alive = &spec->ext_mic;
1153 dead = &spec->int_mic;
1155 alive = &spec->int_mic;
1156 dead = &spec->ext_mic;
1159 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1160 if (type == AC_WID_AUD_MIX) {
1161 /* Matrix-mixer style (e.g. ALC882) */
1162 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1165 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1167 HDA_AMP_MUTE, HDA_AMP_MUTE);
1169 /* MUX style (e.g. ALC880) */
1170 snd_hda_codec_write_cache(codec, cap_nid, 0,
1171 AC_VERB_SET_CONNECT_SEL,
1174 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1176 /* FIXME: analog mixer */
1179 /* unsolicited event for HP jack sensing */
1180 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1182 if (codec->vendor_id == 0x10ec0880)
1187 case ALC880_HP_EVENT:
1188 alc_automute_pin(codec);
1190 case ALC880_MIC_EVENT:
1191 alc_mic_automute(codec);
1196 static void alc_inithook(struct hda_codec *codec)
1198 alc_automute_pin(codec);
1199 alc_mic_automute(codec);
1202 /* additional initialization for ALC888 variants */
1203 static void alc888_coef_init(struct hda_codec *codec)
1207 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1208 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1209 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1210 if ((tmp & 0xf0) == 0x20)
1212 snd_hda_codec_read(codec, 0x20, 0,
1213 AC_VERB_SET_PROC_COEF, 0x830);
1216 snd_hda_codec_read(codec, 0x20, 0,
1217 AC_VERB_SET_PROC_COEF, 0x3030);
1220 static void alc889_coef_init(struct hda_codec *codec)
1224 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1225 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1226 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1227 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1230 /* turn on/off EAPD control (only if available) */
1231 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1233 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1235 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1236 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1240 /* turn on/off EAPD controls of the codec */
1241 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1243 /* We currently only handle front, HP */
1244 switch (codec->vendor_id) {
1246 set_eapd(codec, 0x0f, on);
1247 set_eapd(codec, 0x10, on);
1262 set_eapd(codec, 0x14, on);
1263 set_eapd(codec, 0x15, on);
1268 /* generic shutup callback;
1269 * just turning off EPAD and a little pause for avoiding pop-noise
1271 static void alc_eapd_shutup(struct hda_codec *codec)
1273 alc_auto_setup_eapd(codec, false);
1277 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1282 case ALC_INIT_GPIO1:
1283 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1285 case ALC_INIT_GPIO2:
1286 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1288 case ALC_INIT_GPIO3:
1289 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1291 case ALC_INIT_DEFAULT:
1292 alc_auto_setup_eapd(codec, true);
1293 switch (codec->vendor_id) {
1295 snd_hda_codec_write(codec, 0x1a, 0,
1296 AC_VERB_SET_COEF_INDEX, 7);
1297 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1298 AC_VERB_GET_PROC_COEF, 0);
1299 snd_hda_codec_write(codec, 0x1a, 0,
1300 AC_VERB_SET_COEF_INDEX, 7);
1301 snd_hda_codec_write(codec, 0x1a, 0,
1302 AC_VERB_SET_PROC_COEF,
1311 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1312 alc889_coef_init(codec);
1315 alc888_coef_init(codec);
1317 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1320 snd_hda_codec_write(codec, 0x20, 0,
1321 AC_VERB_SET_COEF_INDEX, 7);
1322 tmp = snd_hda_codec_read(codec, 0x20, 0,
1323 AC_VERB_GET_PROC_COEF, 0);
1324 snd_hda_codec_write(codec, 0x20, 0,
1325 AC_VERB_SET_COEF_INDEX, 7);
1326 snd_hda_codec_write(codec, 0x20, 0,
1327 AC_VERB_SET_PROC_COEF,
1336 static void alc_init_auto_hp(struct hda_codec *codec)
1338 struct alc_spec *spec = codec->spec;
1339 struct auto_pin_cfg *cfg = &spec->autocfg;
1342 if (!cfg->hp_pins[0]) {
1343 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1347 if (!cfg->speaker_pins[0]) {
1348 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1350 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1351 sizeof(cfg->speaker_pins));
1352 cfg->speaker_outs = cfg->line_outs;
1355 if (!cfg->hp_pins[0]) {
1356 memcpy(cfg->hp_pins, cfg->line_out_pins,
1357 sizeof(cfg->hp_pins));
1358 cfg->hp_outs = cfg->line_outs;
1361 for (i = 0; i < cfg->hp_outs; i++) {
1362 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1364 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
1365 AC_VERB_SET_UNSOLICITED_ENABLE,
1366 AC_USRSP_EN | ALC880_HP_EVENT);
1368 spec->unsol_event = alc_sku_unsol_event;
1371 static void alc_init_auto_mic(struct hda_codec *codec)
1373 struct alc_spec *spec = codec->spec;
1374 struct auto_pin_cfg *cfg = &spec->autocfg;
1375 hda_nid_t fixed, ext;
1378 /* there must be only two mic inputs exclusively */
1379 for (i = 0; i < cfg->num_inputs; i++)
1380 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
1384 for (i = 0; i < cfg->num_inputs; i++) {
1385 hda_nid_t nid = cfg->inputs[i].pin;
1386 unsigned int defcfg;
1387 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1388 switch (snd_hda_get_input_pin_attr(defcfg)) {
1389 case INPUT_PIN_ATTR_INT:
1391 return; /* already occupied */
1394 case INPUT_PIN_ATTR_UNUSED:
1395 return; /* invalid entry */
1398 return; /* already occupied */
1405 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1406 return; /* no unsol support */
1407 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1409 spec->ext_mic.pin = ext;
1410 spec->int_mic.pin = fixed;
1411 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1412 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1414 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1415 AC_VERB_SET_UNSOLICITED_ENABLE,
1416 AC_USRSP_EN | ALC880_MIC_EVENT);
1417 spec->unsol_event = alc_sku_unsol_event;
1420 /* Could be any non-zero and even value. When used as fixup, tells
1421 * the driver to ignore any present sku defines.
1423 #define ALC_FIXUP_SKU_IGNORE (2)
1425 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1427 unsigned int ass, tmp, i;
1429 struct alc_spec *spec = codec->spec;
1431 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1433 if (spec->cdefine.fixup) {
1434 ass = spec->cdefine.sku_cfg;
1435 if (ass == ALC_FIXUP_SKU_IGNORE)
1440 ass = codec->subsystem_id & 0xffff;
1441 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1445 if (codec->vendor_id == 0x10ec0260)
1447 ass = snd_hda_codec_get_pincfg(codec, nid);
1450 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1451 codec->chip_name, ass);
1457 for (i = 1; i < 16; i++) {
1461 if (((ass >> 16) & 0xf) != tmp)
1464 spec->cdefine.port_connectivity = ass >> 30;
1465 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1466 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1467 spec->cdefine.customization = ass >> 8;
1469 spec->cdefine.sku_cfg = ass;
1470 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1471 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1472 spec->cdefine.swap = (ass & 0x2) >> 1;
1473 spec->cdefine.override = ass & 0x1;
1475 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1476 nid, spec->cdefine.sku_cfg);
1477 snd_printd("SKU: port_connectivity=0x%x\n",
1478 spec->cdefine.port_connectivity);
1479 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1480 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1481 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1482 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1483 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1484 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1485 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1490 /* check subsystem ID and set up device-specific initialization;
1491 * return 1 if initialized, 0 if invalid SSID
1493 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1494 * 31 ~ 16 : Manufacture ID
1496 * 7 ~ 0 : Assembly ID
1497 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1499 static int alc_subsystem_id(struct hda_codec *codec,
1500 hda_nid_t porta, hda_nid_t porte,
1501 hda_nid_t portd, hda_nid_t porti)
1503 unsigned int ass, tmp, i;
1505 struct alc_spec *spec = codec->spec;
1507 if (spec->cdefine.fixup) {
1508 ass = spec->cdefine.sku_cfg;
1509 if (ass == ALC_FIXUP_SKU_IGNORE)
1514 ass = codec->subsystem_id & 0xffff;
1515 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1518 /* invalid SSID, check the special NID pin defcfg instead */
1520 * 31~30 : port connectivity
1523 * 19~16 : Check sum (15:1)
1528 if (codec->vendor_id == 0x10ec0260)
1530 ass = snd_hda_codec_get_pincfg(codec, nid);
1531 snd_printd("realtek: No valid SSID, "
1532 "checking pincfg 0x%08x for NID 0x%x\n",
1536 if ((ass >> 30) != 1) /* no physical connection */
1541 for (i = 1; i < 16; i++) {
1545 if (((ass >> 16) & 0xf) != tmp)
1548 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1549 ass & 0xffff, codec->vendor_id);
1553 * 2 : 0 --> Desktop, 1 --> Laptop
1554 * 3~5 : External Amplifier control
1557 tmp = (ass & 0x38) >> 3; /* external Amp control */
1560 spec->init_amp = ALC_INIT_GPIO1;
1563 spec->init_amp = ALC_INIT_GPIO2;
1566 spec->init_amp = ALC_INIT_GPIO3;
1570 spec->init_amp = ALC_INIT_DEFAULT;
1574 /* is laptop or Desktop and enable the function "Mute internal speaker
1575 * when the external headphone out jack is plugged"
1577 if (!(ass & 0x8000))
1580 * 10~8 : Jack location
1581 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1583 * 15 : 1 --> enable the function "Mute internal speaker
1584 * when the external headphone out jack is plugged"
1586 if (!spec->autocfg.hp_pins[0]) {
1588 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1599 for (i = 0; i < spec->autocfg.line_outs; i++)
1600 if (spec->autocfg.line_out_pins[i] == nid)
1602 spec->autocfg.hp_pins[0] = nid;
1605 alc_init_auto_hp(codec);
1606 alc_init_auto_mic(codec);
1610 static void alc_ssid_check(struct hda_codec *codec,
1611 hda_nid_t porta, hda_nid_t porte,
1612 hda_nid_t portd, hda_nid_t porti)
1614 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1615 struct alc_spec *spec = codec->spec;
1616 snd_printd("realtek: "
1617 "Enable default setup for auto mode as fallback\n");
1618 spec->init_amp = ALC_INIT_DEFAULT;
1619 alc_init_auto_hp(codec);
1620 alc_init_auto_mic(codec);
1625 * Fix-up pin default configurations and add default verbs
1633 struct alc_model_fixup {
1644 const struct alc_pincfg *pins;
1645 const struct hda_verb *verbs;
1646 void (*func)(struct hda_codec *codec,
1647 const struct alc_fixup *fix,
1661 ALC_FIXUP_ACT_PRE_PROBE,
1662 ALC_FIXUP_ACT_PROBE,
1666 static void alc_apply_fixup(struct hda_codec *codec, int action)
1668 struct alc_spec *spec = codec->spec;
1669 int id = spec->fixup_id;
1670 #ifdef CONFIG_SND_DEBUG_VERBOSE
1671 const char *modelname = spec->fixup_name;
1675 if (!spec->fixup_list)
1679 const struct alc_fixup *fix = spec->fixup_list + id;
1680 const struct alc_pincfg *cfg;
1682 switch (fix->type) {
1684 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1686 snd_printdd(KERN_INFO "hda_codec: %s: "
1687 "Apply sku override for %s\n",
1688 codec->chip_name, modelname);
1689 spec->cdefine.sku_cfg = fix->v.sku;
1690 spec->cdefine.fixup = 1;
1692 case ALC_FIXUP_PINS:
1694 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1696 snd_printdd(KERN_INFO "hda_codec: %s: "
1697 "Apply pincfg for %s\n",
1698 codec->chip_name, modelname);
1699 for (; cfg->nid; cfg++)
1700 snd_hda_codec_set_pincfg(codec, cfg->nid,
1703 case ALC_FIXUP_VERBS:
1704 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1706 snd_printdd(KERN_INFO "hda_codec: %s: "
1707 "Apply fix-verbs for %s\n",
1708 codec->chip_name, modelname);
1709 add_verb(codec->spec, fix->v.verbs);
1711 case ALC_FIXUP_FUNC:
1714 snd_printdd(KERN_INFO "hda_codec: %s: "
1715 "Apply fix-func for %s\n",
1716 codec->chip_name, modelname);
1717 fix->v.func(codec, fix, action);
1720 snd_printk(KERN_ERR "hda_codec: %s: "
1721 "Invalid fixup type %d\n",
1722 codec->chip_name, fix->type);
1725 if (!fix[id].chained)
1729 id = fix[id].chain_id;
1733 static void alc_pick_fixup(struct hda_codec *codec,
1734 const struct alc_model_fixup *models,
1735 const struct snd_pci_quirk *quirk,
1736 const struct alc_fixup *fixlist)
1738 struct alc_spec *spec = codec->spec;
1740 const char *name = NULL;
1742 if (codec->modelname && models) {
1743 while (models->name) {
1744 if (!strcmp(codec->modelname, models->name)) {
1746 name = models->name;
1753 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1756 #ifdef CONFIG_SND_DEBUG_VERBOSE
1762 spec->fixup_id = id;
1764 spec->fixup_list = fixlist;
1765 spec->fixup_name = name;
1769 static int alc_read_coef_idx(struct hda_codec *codec,
1770 unsigned int coef_idx)
1773 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1775 val = snd_hda_codec_read(codec, 0x20, 0,
1776 AC_VERB_GET_PROC_COEF, 0);
1780 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1781 unsigned int coef_val)
1783 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1785 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1789 /* set right pin controls for digital I/O */
1790 static void alc_auto_init_digital(struct hda_codec *codec)
1792 struct alc_spec *spec = codec->spec;
1796 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1797 pin = spec->autocfg.dig_out_pins[i];
1799 snd_hda_codec_write(codec, pin, 0,
1800 AC_VERB_SET_PIN_WIDGET_CONTROL,
1804 pin = spec->autocfg.dig_in_pin;
1806 snd_hda_codec_write(codec, pin, 0,
1807 AC_VERB_SET_PIN_WIDGET_CONTROL,
1811 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1812 static void alc_auto_parse_digital(struct hda_codec *codec)
1814 struct alc_spec *spec = codec->spec;
1818 /* support multiple SPDIFs; the secondary is set up as a slave */
1819 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1820 err = snd_hda_get_connections(codec,
1821 spec->autocfg.dig_out_pins[i],
1826 spec->multiout.dig_out_nid = dig_nid;
1827 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1829 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1830 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1832 spec->slave_dig_outs[i - 1] = dig_nid;
1836 if (spec->autocfg.dig_in_pin) {
1837 dig_nid = codec->start_nid;
1838 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1839 unsigned int wcaps = get_wcaps(codec, dig_nid);
1840 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1842 if (!(wcaps & AC_WCAP_DIGITAL))
1844 if (!(wcaps & AC_WCAP_CONN_LIST))
1846 err = get_connection_index(codec, dig_nid,
1847 spec->autocfg.dig_in_pin);
1849 spec->dig_in_nid = dig_nid;
1863 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1864 /* Mic-in jack as mic in */
1865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1867 /* Line-in jack as Line in */
1868 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1869 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1870 /* Line-Out as Front */
1871 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1878 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1879 /* Mic-in jack as mic in */
1880 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1881 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1882 /* Line-in jack as Surround */
1883 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1884 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1885 /* Line-Out as Front */
1886 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1893 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1894 /* Mic-in jack as CLFE */
1895 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1896 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1897 /* Line-in jack as Surround */
1898 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1899 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1900 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1901 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1908 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1909 /* Mic-in jack as CLFE */
1910 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1911 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1912 /* Line-in jack as Surround */
1913 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1914 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1915 /* Line-Out as Side */
1916 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1920 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1921 { 2, alc888_4ST_ch2_intel_init },
1922 { 4, alc888_4ST_ch4_intel_init },
1923 { 6, alc888_4ST_ch6_intel_init },
1924 { 8, alc888_4ST_ch8_intel_init },
1928 * ALC888 Fujitsu Siemens Amillo xa3530
1931 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1932 /* Front Mic: set to PIN_IN (empty by default) */
1933 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1934 /* Connect Internal HP to Front */
1935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1938 /* Connect Bass HP to Front */
1939 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1940 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1941 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1942 /* Connect Line-Out side jack (SPDIF) to Side */
1943 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1944 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1945 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1946 /* Connect Mic jack to CLFE */
1947 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1948 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1949 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1950 /* Connect Line-in jack to Surround */
1951 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1952 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1953 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1954 /* Connect HP out jack to Front */
1955 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1956 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1957 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1958 /* Enable unsolicited event for HP jack and Line-out jack */
1959 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1960 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1964 static void alc_automute_amp(struct hda_codec *codec)
1966 alc_automute_speaker(codec, 0);
1969 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1972 if (codec->vendor_id == 0x10ec0880)
1976 if (res == ALC880_HP_EVENT)
1977 alc_automute_amp(codec);
1980 static void alc889_automute_setup(struct hda_codec *codec)
1982 struct alc_spec *spec = codec->spec;
1984 spec->autocfg.hp_pins[0] = 0x15;
1985 spec->autocfg.speaker_pins[0] = 0x14;
1986 spec->autocfg.speaker_pins[1] = 0x16;
1987 spec->autocfg.speaker_pins[2] = 0x17;
1988 spec->autocfg.speaker_pins[3] = 0x19;
1989 spec->autocfg.speaker_pins[4] = 0x1a;
1992 static void alc889_intel_init_hook(struct hda_codec *codec)
1994 alc889_coef_init(codec);
1995 alc_automute_amp(codec);
1998 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2000 struct alc_spec *spec = codec->spec;
2002 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2003 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2004 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2005 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2009 * ALC888 Acer Aspire 4930G model
2012 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2013 /* Front Mic: set to PIN_IN (empty by default) */
2014 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2015 /* Unselect Front Mic by default in input mixer 3 */
2016 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2017 /* Enable unsolicited event for HP jack */
2018 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2019 /* Connect Internal HP to front */
2020 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2021 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2022 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2023 /* Connect HP out to front */
2024 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2025 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2026 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2027 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2032 * ALC888 Acer Aspire 6530G model
2035 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2036 /* Route to built-in subwoofer as well as speakers */
2037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2039 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2040 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2041 /* Bias voltage on for external mic port */
2042 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2043 /* Front Mic: set to PIN_IN (empty by default) */
2044 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2045 /* Unselect Front Mic by default in input mixer 3 */
2046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2047 /* Enable unsolicited event for HP jack */
2048 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2049 /* Enable speaker output */
2050 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2052 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2053 /* Enable headphone output */
2054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2057 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2062 *ALC888 Acer Aspire 7730G model
2065 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2066 /* Bias voltage on for external mic port */
2067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2068 /* Front Mic: set to PIN_IN (empty by default) */
2069 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2070 /* Unselect Front Mic by default in input mixer 3 */
2071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2072 /* Enable unsolicited event for HP jack */
2073 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2074 /* Enable speaker output */
2075 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2076 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2077 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2078 /* Enable headphone output */
2079 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2080 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2081 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2082 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2083 /*Enable internal subwoofer */
2084 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2085 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2086 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2087 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2092 * ALC889 Acer Aspire 8930G model
2095 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2096 /* Front Mic: set to PIN_IN (empty by default) */
2097 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2098 /* Unselect Front Mic by default in input mixer 3 */
2099 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2100 /* Enable unsolicited event for HP jack */
2101 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2102 /* Connect Internal Front to Front */
2103 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2105 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2106 /* Connect Internal Rear to Rear */
2107 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2108 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2109 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2110 /* Connect Internal CLFE to CLFE */
2111 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2112 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2113 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2114 /* Connect HP out to Front */
2115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2116 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2117 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2118 /* Enable all DACs */
2119 /* DAC DISABLE/MUTE 1? */
2120 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2121 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2122 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2123 /* DAC DISABLE/MUTE 2? */
2124 /* some bit here disables the other DACs. Init=0x4900 */
2125 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2126 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2128 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2129 * which makes the stereo useless. However, either the mic or the ALC889
2130 * makes the signal become a difference/sum signal instead of standard
2131 * stereo, which is annoying. So instead we flip this bit which makes the
2132 * codec replicate the sum signal to both channels, turning it into a
2135 /* DMIC_CONTROL? Init value = 0x0001 */
2136 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2137 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2141 static struct hda_input_mux alc888_2_capture_sources[2] = {
2142 /* Front mic only available on one ADC */
2149 { "Front Mic", 0xb },
2162 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2163 /* Interal mic only available on one ADC */
2170 { "Input Mix", 0xa },
2171 { "Internal Mic", 0xb },
2180 { "Input Mix", 0xa },
2185 static struct hda_input_mux alc889_capture_sources[3] = {
2186 /* Digital mic only available on first "ADC" */
2193 { "Front Mic", 0xb },
2194 { "Input Mix", 0xa },
2203 { "Input Mix", 0xa },
2212 { "Input Mix", 0xa },
2217 static struct snd_kcontrol_new alc888_base_mixer[] = {
2218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2219 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2220 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2221 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2222 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2224 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2225 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2226 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2227 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2228 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2239 static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2241 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2242 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2243 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2244 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2246 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2247 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2248 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2249 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2250 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2251 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2252 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2253 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2254 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2256 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2261 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2262 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2263 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2264 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2265 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2266 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2268 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2269 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2270 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2271 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2272 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2273 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2274 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2275 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2280 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2282 struct alc_spec *spec = codec->spec;
2284 spec->autocfg.hp_pins[0] = 0x15;
2285 spec->autocfg.speaker_pins[0] = 0x14;
2286 spec->autocfg.speaker_pins[1] = 0x16;
2287 spec->autocfg.speaker_pins[2] = 0x17;
2290 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2292 struct alc_spec *spec = codec->spec;
2294 spec->autocfg.hp_pins[0] = 0x15;
2295 spec->autocfg.speaker_pins[0] = 0x14;
2296 spec->autocfg.speaker_pins[1] = 0x16;
2297 spec->autocfg.speaker_pins[2] = 0x17;
2300 static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2302 struct alc_spec *spec = codec->spec;
2304 spec->autocfg.hp_pins[0] = 0x15;
2305 spec->autocfg.speaker_pins[0] = 0x14;
2306 spec->autocfg.speaker_pins[1] = 0x16;
2307 spec->autocfg.speaker_pins[2] = 0x17;
2310 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2312 struct alc_spec *spec = codec->spec;
2314 spec->autocfg.hp_pins[0] = 0x15;
2315 spec->autocfg.speaker_pins[0] = 0x14;
2316 spec->autocfg.speaker_pins[1] = 0x16;
2317 spec->autocfg.speaker_pins[2] = 0x1b;
2321 * ALC880 3-stack model
2323 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2324 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2325 * F-Mic = 0x1b, HP = 0x19
2328 static hda_nid_t alc880_dac_nids[4] = {
2329 /* front, rear, clfe, rear_surr */
2330 0x02, 0x05, 0x04, 0x03
2333 static hda_nid_t alc880_adc_nids[3] = {
2338 /* The datasheet says the node 0x07 is connected from inputs,
2339 * but it shows zero connection in the real implementation on some devices.
2340 * Note: this is a 915GAV bug, fixed on 915GLV
2342 static hda_nid_t alc880_adc_nids_alt[2] = {
2347 #define ALC880_DIGOUT_NID 0x06
2348 #define ALC880_DIGIN_NID 0x0a
2350 static struct hda_input_mux alc880_capture_source = {
2354 { "Front Mic", 0x3 },
2360 /* channel source setting (2/6 channel selection for 3-stack) */
2362 static struct hda_verb alc880_threestack_ch2_init[] = {
2363 /* set line-in to input, mute it */
2364 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2365 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2366 /* set mic-in to input vref 80%, mute it */
2367 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2368 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2373 static struct hda_verb alc880_threestack_ch6_init[] = {
2374 /* set line-in to output, unmute it */
2375 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2376 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2377 /* set mic-in to output, unmute it */
2378 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2379 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2383 static struct hda_channel_mode alc880_threestack_modes[2] = {
2384 { 2, alc880_threestack_ch2_init },
2385 { 6, alc880_threestack_ch6_init },
2388 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2389 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2390 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2391 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2392 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2393 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2394 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2395 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2396 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2397 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2398 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2399 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2400 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2401 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2402 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2403 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2404 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2405 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2407 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2408 .name = "Channel Mode",
2409 .info = alc_ch_mode_info,
2410 .get = alc_ch_mode_get,
2411 .put = alc_ch_mode_put,
2416 /* capture mixer elements */
2417 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2418 struct snd_ctl_elem_info *uinfo)
2420 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2421 struct alc_spec *spec = codec->spec;
2424 mutex_lock(&codec->control_mutex);
2425 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2427 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2428 mutex_unlock(&codec->control_mutex);
2432 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2433 unsigned int size, unsigned int __user *tlv)
2435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2436 struct alc_spec *spec = codec->spec;
2439 mutex_lock(&codec->control_mutex);
2440 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2442 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2443 mutex_unlock(&codec->control_mutex);
2447 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2448 struct snd_ctl_elem_value *ucontrol);
2450 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2451 struct snd_ctl_elem_value *ucontrol,
2454 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2455 struct alc_spec *spec = codec->spec;
2456 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2459 mutex_lock(&codec->control_mutex);
2460 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2462 err = func(kcontrol, ucontrol);
2463 mutex_unlock(&codec->control_mutex);
2467 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2468 struct snd_ctl_elem_value *ucontrol)
2470 return alc_cap_getput_caller(kcontrol, ucontrol,
2471 snd_hda_mixer_amp_volume_get);
2474 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2475 struct snd_ctl_elem_value *ucontrol)
2477 return alc_cap_getput_caller(kcontrol, ucontrol,
2478 snd_hda_mixer_amp_volume_put);
2481 /* capture mixer elements */
2482 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2484 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2485 struct snd_ctl_elem_value *ucontrol)
2487 return alc_cap_getput_caller(kcontrol, ucontrol,
2488 snd_hda_mixer_amp_switch_get);
2491 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2492 struct snd_ctl_elem_value *ucontrol)
2494 return alc_cap_getput_caller(kcontrol, ucontrol,
2495 snd_hda_mixer_amp_switch_put);
2498 #define _DEFINE_CAPMIX(num) \
2500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2501 .name = "Capture Switch", \
2502 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2504 .info = alc_cap_sw_info, \
2505 .get = alc_cap_sw_get, \
2506 .put = alc_cap_sw_put, \
2509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2510 .name = "Capture Volume", \
2511 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2512 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2513 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2515 .info = alc_cap_vol_info, \
2516 .get = alc_cap_vol_get, \
2517 .put = alc_cap_vol_put, \
2518 .tlv = { .c = alc_cap_vol_tlv }, \
2521 #define _DEFINE_CAPSRC(num) \
2523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2524 /* .name = "Capture Source", */ \
2525 .name = "Input Source", \
2527 .info = alc_mux_enum_info, \
2528 .get = alc_mux_enum_get, \
2529 .put = alc_mux_enum_put, \
2532 #define DEFINE_CAPMIX(num) \
2533 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2534 _DEFINE_CAPMIX(num), \
2535 _DEFINE_CAPSRC(num), \
2539 #define DEFINE_CAPMIX_NOSRC(num) \
2540 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2541 _DEFINE_CAPMIX(num), \
2545 /* up to three ADCs */
2549 DEFINE_CAPMIX_NOSRC(1);
2550 DEFINE_CAPMIX_NOSRC(2);
2551 DEFINE_CAPMIX_NOSRC(3);
2554 * ALC880 5-stack model
2556 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2558 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2559 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2562 /* additional mixers to alc880_three_stack_mixer */
2563 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2564 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2565 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2569 /* channel source setting (6/8 channel selection for 5-stack) */
2571 static struct hda_verb alc880_fivestack_ch6_init[] = {
2572 /* set line-in to input, mute it */
2573 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2574 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2579 static struct hda_verb alc880_fivestack_ch8_init[] = {
2580 /* set line-in to output, unmute it */
2581 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2582 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2586 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2587 { 6, alc880_fivestack_ch6_init },
2588 { 8, alc880_fivestack_ch8_init },
2593 * ALC880 6-stack model
2595 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2596 * Side = 0x05 (0x0f)
2597 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2598 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2601 static hda_nid_t alc880_6st_dac_nids[4] = {
2602 /* front, rear, clfe, rear_surr */
2603 0x02, 0x03, 0x04, 0x05
2606 static struct hda_input_mux alc880_6stack_capture_source = {
2610 { "Front Mic", 0x1 },
2616 /* fixed 8-channels */
2617 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2621 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2622 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2623 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2624 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2625 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2626 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2627 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2628 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2629 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2630 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2631 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2632 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2633 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2634 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2635 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2638 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2639 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2641 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2642 .name = "Channel Mode",
2643 .info = alc_ch_mode_info,
2644 .get = alc_ch_mode_get,
2645 .put = alc_ch_mode_put,
2654 * W810 has rear IO for:
2657 * Center/LFE (DAC 04)
2660 * The system also has a pair of internal speakers, and a headphone jack.
2661 * These are both connected to Line2 on the codec, hence to DAC 02.
2663 * There is a variable resistor to control the speaker or headphone
2664 * volume. This is a hardware-only device without a software API.
2666 * Plugging headphones in will disable the internal speakers. This is
2667 * implemented in hardware, not via the driver using jack sense. In
2668 * a similar fashion, plugging into the rear socket marked "front" will
2669 * disable both the speakers and headphones.
2671 * For input, there's a microphone jack, and an "audio in" jack.
2672 * These may not do anything useful with this driver yet, because I
2673 * haven't setup any initialization verbs for these yet...
2676 static hda_nid_t alc880_w810_dac_nids[3] = {
2677 /* front, rear/surround, clfe */
2681 /* fixed 6 channels */
2682 static struct hda_channel_mode alc880_w810_modes[1] = {
2686 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2687 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2688 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2689 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2690 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2691 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2692 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2693 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2694 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2695 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2696 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2704 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2705 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2709 static hda_nid_t alc880_z71v_dac_nids[1] = {
2712 #define ALC880_Z71V_HP_DAC 0x03
2714 /* fixed 2 channels */
2715 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2719 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2720 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2721 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2723 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2724 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2725 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2727 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2733 * ALC880 F1734 model
2735 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2736 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2739 static hda_nid_t alc880_f1734_dac_nids[1] = {
2742 #define ALC880_F1734_HP_DAC 0x02
2744 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2745 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2746 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2747 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2748 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2749 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2750 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2751 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2752 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2756 static struct hda_input_mux alc880_f1734_capture_source = {
2768 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2769 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2770 * Mic = 0x18, Line = 0x1a
2773 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2774 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2776 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2777 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2778 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2779 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2780 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2781 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2782 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2783 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2784 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2785 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2786 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2787 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2788 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2793 .name = "Channel Mode",
2794 .info = alc_ch_mode_info,
2795 .get = alc_ch_mode_get,
2796 .put = alc_ch_mode_put,
2802 * ALC880 ASUS W1V model
2804 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2805 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2806 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2809 /* additional mixers to alc880_asus_mixer */
2810 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2811 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2812 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2817 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2819 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2821 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2822 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2824 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2825 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2826 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2831 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2832 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2833 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2834 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2835 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2836 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2837 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2838 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2839 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2840 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2841 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2842 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2843 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2846 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2847 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2850 .name = "Channel Mode",
2851 .info = alc_ch_mode_info,
2852 .get = alc_ch_mode_get,
2853 .put = alc_ch_mode_put,
2858 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2859 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2860 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2861 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2862 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2863 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2864 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2865 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2866 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2867 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2868 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2872 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2873 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2874 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2875 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2876 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2878 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2883 * virtual master controls
2887 * slave controls for virtual master
2889 static const char * const alc_slave_vols[] = {
2890 "Front Playback Volume",
2891 "Surround Playback Volume",
2892 "Center Playback Volume",
2893 "LFE Playback Volume",
2894 "Side Playback Volume",
2895 "Headphone Playback Volume",
2896 "Speaker Playback Volume",
2897 "Mono Playback Volume",
2898 "Line-Out Playback Volume",
2899 "PCM Playback Volume",
2903 static const char * const alc_slave_sws[] = {
2904 "Front Playback Switch",
2905 "Surround Playback Switch",
2906 "Center Playback Switch",
2907 "LFE Playback Switch",
2908 "Side Playback Switch",
2909 "Headphone Playback Switch",
2910 "Speaker Playback Switch",
2911 "Mono Playback Switch",
2912 "IEC958 Playback Switch",
2913 "Line-Out Playback Switch",
2914 "PCM Playback Switch",
2919 * build control elements
2922 #define NID_MAPPING (-1)
2924 #define SUBDEV_SPEAKER_ (0 << 6)
2925 #define SUBDEV_HP_ (1 << 6)
2926 #define SUBDEV_LINE_ (2 << 6)
2927 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2928 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2929 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2931 static void alc_free_kctls(struct hda_codec *codec);
2933 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2934 /* additional beep mixers; the actual parameters are overwritten at build */
2935 static struct snd_kcontrol_new alc_beep_mixer[] = {
2936 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2937 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2942 static int alc_build_controls(struct hda_codec *codec)
2944 struct alc_spec *spec = codec->spec;
2945 struct snd_kcontrol *kctl = NULL;
2946 struct snd_kcontrol_new *knew;
2951 for (i = 0; i < spec->num_mixers; i++) {
2952 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2956 if (spec->cap_mixer) {
2957 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2961 if (spec->multiout.dig_out_nid) {
2962 err = snd_hda_create_spdif_out_ctls(codec,
2963 spec->multiout.dig_out_nid);
2966 if (!spec->no_analog) {
2967 err = snd_hda_create_spdif_share_sw(codec,
2971 spec->multiout.share_spdif = 1;
2974 if (spec->dig_in_nid) {
2975 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2980 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2981 /* create beep controls if needed */
2982 if (spec->beep_amp) {
2983 struct snd_kcontrol_new *knew;
2984 for (knew = alc_beep_mixer; knew->name; knew++) {
2985 struct snd_kcontrol *kctl;
2986 kctl = snd_ctl_new1(knew, codec);
2989 kctl->private_value = spec->beep_amp;
2990 err = snd_hda_ctl_add(codec, 0, kctl);
2997 /* if we have no master control, let's create it */
2998 if (!spec->no_analog &&
2999 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3000 unsigned int vmaster_tlv[4];
3001 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3002 HDA_OUTPUT, vmaster_tlv);
3003 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3004 vmaster_tlv, alc_slave_vols);
3008 if (!spec->no_analog &&
3009 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3010 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3011 NULL, alc_slave_sws);
3016 /* assign Capture Source enums to NID */
3017 if (spec->capsrc_nids || spec->adc_nids) {
3018 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3020 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3021 for (i = 0; kctl && i < kctl->count; i++) {
3022 hda_nid_t *nids = spec->capsrc_nids;
3024 nids = spec->adc_nids;
3025 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3030 if (spec->cap_mixer) {
3031 const char *kname = kctl ? kctl->id.name : NULL;
3032 for (knew = spec->cap_mixer; knew->name; knew++) {
3033 if (kname && strcmp(knew->name, kname) == 0)
3035 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3036 for (i = 0; kctl && i < kctl->count; i++) {
3037 err = snd_hda_add_nid(codec, kctl, i,
3045 /* other nid->control mapping */
3046 for (i = 0; i < spec->num_mixers; i++) {
3047 for (knew = spec->mixers[i]; knew->name; knew++) {
3048 if (knew->iface != NID_MAPPING)
3050 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3053 u = knew->subdevice;
3054 for (j = 0; j < 4; j++, u >>= 8) {
3059 case SUBDEV_SPEAKER_:
3060 nid = spec->autocfg.speaker_pins[nid];
3063 nid = spec->autocfg.line_out_pins[nid];
3066 nid = spec->autocfg.hp_pins[nid];
3071 err = snd_hda_add_nid(codec, kctl, 0, nid);
3075 u = knew->private_value;
3076 for (j = 0; j < 4; j++, u >>= 8) {
3080 err = snd_hda_add_nid(codec, kctl, 0, nid);
3087 alc_free_kctls(codec); /* no longer needed */
3094 * initialize the codec volumes, etc
3098 * generic initialization of ADC, input mixers and output mixers
3100 static struct hda_verb alc880_volume_init_verbs[] = {
3102 * Unmute ADC0-2 and set the default input to mic-in
3104 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3106 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3107 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3108 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3109 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3111 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3113 * Note: PASD motherboards uses the Line In 2 as the input for front
3116 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3122 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3123 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3126 * Set up output mixers (0x0c - 0x0f)
3128 /* set vol=0 to output mixers */
3129 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3130 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3131 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3132 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3133 /* set up input amps for analog loopback */
3134 /* Amp Indices: DAC = 0, mixer = 1 */
3135 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3137 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3138 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3139 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3140 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3141 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3142 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3148 * 3-stack pin configuration:
3149 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3151 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3153 * preset connection lists of input pins
3154 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3156 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3157 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3158 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3161 * Set pin mode and muting
3163 /* set front pin widgets 0x14 for output */
3164 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3165 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3166 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3167 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3168 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3169 /* Mic2 (as headphone out) for HP output */
3170 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3171 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3172 /* Line In pin widget for input */
3173 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3174 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3175 /* Line2 (as front mic) pin widget for input and vref at 80% */
3176 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3177 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3178 /* CD pin widget for input */
3179 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3185 * 5-stack pin configuration:
3186 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3187 * line-in/side = 0x1a, f-mic = 0x1b
3189 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3191 * preset connection lists of input pins
3192 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3194 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3195 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3198 * Set pin mode and muting
3200 /* set pin widgets 0x14-0x17 for output */
3201 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3203 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3204 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3205 /* unmute pins for output (no gain on this amp) */
3206 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3208 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3209 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3211 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3212 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3214 /* Mic2 (as headphone out) for HP output */
3215 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3216 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3217 /* Line In pin widget for input */
3218 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3220 /* Line2 (as front mic) pin widget for input and vref at 80% */
3221 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3223 /* CD pin widget for input */
3224 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3230 * W810 pin configuration:
3231 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3233 static struct hda_verb alc880_pin_w810_init_verbs[] = {
3234 /* hphone/speaker input selector: front DAC */
3235 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3241 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3242 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3245 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3251 * Z71V pin configuration:
3252 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3254 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
3255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3256 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3260 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3261 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3262 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3263 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3269 * 6-stack pin configuration:
3270 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3271 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3273 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3274 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3276 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3277 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3278 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3279 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3280 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3281 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3282 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3283 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3285 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3286 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3287 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3288 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3289 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3290 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3291 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3292 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3293 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3299 * Uniwill pin configuration:
3300 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3303 static struct hda_verb alc880_uniwill_init_verbs[] = {
3304 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3306 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3307 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3308 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3310 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3311 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3312 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3313 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3314 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3315 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3316 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3317 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3318 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3319 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3321 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3322 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3323 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3324 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3326 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3327 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3328 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3329 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3331 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3332 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3339 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3341 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3342 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3345 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3347 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3348 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3349 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3354 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3357 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3358 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3360 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3361 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3362 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3364 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3365 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3370 static struct hda_verb alc880_beep_init_verbs[] = {
3371 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3375 /* auto-toggle front mic */
3376 static void alc88x_simple_mic_automute(struct hda_codec *codec)
3378 unsigned int present;
3381 present = snd_hda_jack_detect(codec, 0x18);
3382 bits = present ? HDA_AMP_MUTE : 0;
3383 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3386 static void alc880_uniwill_setup(struct hda_codec *codec)
3388 struct alc_spec *spec = codec->spec;
3390 spec->autocfg.hp_pins[0] = 0x14;
3391 spec->autocfg.speaker_pins[0] = 0x15;
3392 spec->autocfg.speaker_pins[0] = 0x16;
3395 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3397 alc_automute_amp(codec);
3398 alc88x_simple_mic_automute(codec);
3401 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3404 /* Looks like the unsol event is incompatible with the standard
3405 * definition. 4bit tag is placed at 28 bit!
3407 switch (res >> 28) {
3408 case ALC880_MIC_EVENT:
3409 alc88x_simple_mic_automute(codec);
3412 alc_automute_amp_unsol_event(codec, res);
3417 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3419 struct alc_spec *spec = codec->spec;
3421 spec->autocfg.hp_pins[0] = 0x14;
3422 spec->autocfg.speaker_pins[0] = 0x15;
3425 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3427 unsigned int present;
3429 present = snd_hda_codec_read(codec, 0x21, 0,
3430 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3431 present &= HDA_AMP_VOLMASK;
3432 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3433 HDA_AMP_VOLMASK, present);
3434 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3435 HDA_AMP_VOLMASK, present);
3438 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3441 /* Looks like the unsol event is incompatible with the standard
3442 * definition. 4bit tag is placed at 28 bit!
3444 if ((res >> 28) == ALC880_DCVOL_EVENT)
3445 alc880_uniwill_p53_dcvol_automute(codec);
3447 alc_automute_amp_unsol_event(codec, res);
3451 * F1734 pin configuration:
3452 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3454 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3455 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3456 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3457 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3458 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3459 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3461 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3462 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3464 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3466 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3467 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3469 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3470 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3472 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3473 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3476 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3477 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3483 * ASUS pin configuration:
3484 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3486 static struct hda_verb alc880_pin_asus_init_verbs[] = {
3487 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3488 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3489 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3490 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3493 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3495 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3496 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3497 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3498 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3503 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3508 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3509 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3514 /* Enable GPIO mask and set output */
3515 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3516 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3517 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3519 /* Clevo m520g init */
3520 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3521 /* headphone output */
3522 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3527 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3531 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3532 /* Mic1 (rear panel) */
3533 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3535 /* Mic2 (front panel) */
3536 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3537 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3539 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3540 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 /* change to EAPD mode */
3542 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3543 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3548 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3549 /* change to EAPD mode */
3550 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3551 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3553 /* Headphone output */
3554 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3556 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3557 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3559 /* Line In pin widget for input */
3560 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3561 /* CD pin widget for input */
3562 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3563 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3564 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3566 /* change to EAPD mode */
3567 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3568 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3574 * LG m1 express dual
3577 * Rear Line-In/Out (blue): 0x14
3578 * Build-in Mic-In: 0x15
3580 * HP-Out (green): 0x1b
3581 * Mic-In/Out (red): 0x19
3585 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3586 static hda_nid_t alc880_lg_dac_nids[3] = {
3590 /* seems analog CD is not working */
3591 static struct hda_input_mux alc880_lg_capture_source = {
3596 { "Internal Mic", 0x6 },
3600 /* 2,4,6 channel modes */
3601 static struct hda_verb alc880_lg_ch2_init[] = {
3602 /* set line-in and mic-in to input */
3603 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3604 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3608 static struct hda_verb alc880_lg_ch4_init[] = {
3609 /* set line-in to out and mic-in to input */
3610 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3611 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3615 static struct hda_verb alc880_lg_ch6_init[] = {
3616 /* set line-in and mic-in to output */
3617 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3618 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3622 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3623 { 2, alc880_lg_ch2_init },
3624 { 4, alc880_lg_ch4_init },
3625 { 6, alc880_lg_ch6_init },
3628 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3629 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3630 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3631 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3632 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3633 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3634 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3635 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3636 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3639 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3640 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3641 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3642 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3644 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3645 .name = "Channel Mode",
3646 .info = alc_ch_mode_info,
3647 .get = alc_ch_mode_get,
3648 .put = alc_ch_mode_put,
3653 static struct hda_verb alc880_lg_init_verbs[] = {
3654 /* set capture source to mic-in */
3655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3657 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3658 /* mute all amp mixer inputs */
3659 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3660 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3661 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3662 /* line-in to input */
3663 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3664 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3666 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3669 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3670 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3671 /* mic-in to input */
3672 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3673 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3674 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3676 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3677 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3678 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3680 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3684 /* toggle speaker-output according to the hp-jack state */
3685 static void alc880_lg_setup(struct hda_codec *codec)
3687 struct alc_spec *spec = codec->spec;
3689 spec->autocfg.hp_pins[0] = 0x1b;
3690 spec->autocfg.speaker_pins[0] = 0x17;
3699 * Built-in Mic-In: 0x19
3705 static struct hda_input_mux alc880_lg_lw_capture_source = {
3709 { "Internal Mic", 0x1 },
3714 #define alc880_lg_lw_modes alc880_threestack_modes
3716 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3717 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3718 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3719 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3720 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3721 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3722 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3723 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3724 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3725 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3726 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3729 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3730 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3733 .name = "Channel Mode",
3734 .info = alc_ch_mode_info,
3735 .get = alc_ch_mode_get,
3736 .put = alc_ch_mode_put,
3741 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3742 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3743 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3744 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3746 /* set capture source to mic-in */
3747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3748 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3749 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3753 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3755 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3757 /* mic-in to input */
3758 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3759 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3761 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3762 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3768 /* toggle speaker-output according to the hp-jack state */
3769 static void alc880_lg_lw_setup(struct hda_codec *codec)
3771 struct alc_spec *spec = codec->spec;
3773 spec->autocfg.hp_pins[0] = 0x1b;
3774 spec->autocfg.speaker_pins[0] = 0x14;
3777 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3778 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3779 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3782 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3783 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3787 static struct hda_input_mux alc880_medion_rim_capture_source = {
3791 { "Internal Mic", 0x1 },
3795 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3796 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3798 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3799 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3801 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3802 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3803 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3804 /* Mic2 (as headphone out) for HP output */
3805 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3806 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3807 /* Internal Speaker */
3808 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3809 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3812 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3818 /* toggle speaker-output according to the hp-jack state */
3819 static void alc880_medion_rim_automute(struct hda_codec *codec)
3821 struct alc_spec *spec = codec->spec;
3822 alc_automute_amp(codec);
3824 if (spec->jack_present)
3825 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3827 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3830 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3833 /* Looks like the unsol event is incompatible with the standard
3834 * definition. 4bit tag is placed at 28 bit!
3836 if ((res >> 28) == ALC880_HP_EVENT)
3837 alc880_medion_rim_automute(codec);
3840 static void alc880_medion_rim_setup(struct hda_codec *codec)
3842 struct alc_spec *spec = codec->spec;
3844 spec->autocfg.hp_pins[0] = 0x14;
3845 spec->autocfg.speaker_pins[0] = 0x1b;
3848 #ifdef CONFIG_SND_HDA_POWER_SAVE
3849 static struct hda_amp_list alc880_loopbacks[] = {
3850 { 0x0b, HDA_INPUT, 0 },
3851 { 0x0b, HDA_INPUT, 1 },
3852 { 0x0b, HDA_INPUT, 2 },
3853 { 0x0b, HDA_INPUT, 3 },
3854 { 0x0b, HDA_INPUT, 4 },
3858 static struct hda_amp_list alc880_lg_loopbacks[] = {
3859 { 0x0b, HDA_INPUT, 1 },
3860 { 0x0b, HDA_INPUT, 6 },
3861 { 0x0b, HDA_INPUT, 7 },
3870 static void alc_init_special_input_src(struct hda_codec *codec);
3872 static int alc_init(struct hda_codec *codec)
3874 struct alc_spec *spec = codec->spec;
3878 alc_auto_init_amp(codec, spec->init_amp);
3880 for (i = 0; i < spec->num_init_verbs; i++)
3881 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3882 alc_init_special_input_src(codec);
3884 if (spec->init_hook)
3885 spec->init_hook(codec);
3887 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3889 hda_call_check_power_status(codec, 0x01);
3893 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3895 struct alc_spec *spec = codec->spec;
3897 if (spec->unsol_event)
3898 spec->unsol_event(codec, res);
3901 #ifdef CONFIG_SND_HDA_POWER_SAVE
3902 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3904 struct alc_spec *spec = codec->spec;
3905 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3910 * Analog playback callbacks
3912 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3913 struct hda_codec *codec,
3914 struct snd_pcm_substream *substream)
3916 struct alc_spec *spec = codec->spec;
3917 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3921 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3922 struct hda_codec *codec,
3923 unsigned int stream_tag,
3924 unsigned int format,
3925 struct snd_pcm_substream *substream)
3927 struct alc_spec *spec = codec->spec;
3928 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3929 stream_tag, format, substream);
3932 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3933 struct hda_codec *codec,
3934 struct snd_pcm_substream *substream)
3936 struct alc_spec *spec = codec->spec;
3937 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3943 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3944 struct hda_codec *codec,
3945 struct snd_pcm_substream *substream)
3947 struct alc_spec *spec = codec->spec;
3948 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3951 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3952 struct hda_codec *codec,
3953 unsigned int stream_tag,
3954 unsigned int format,
3955 struct snd_pcm_substream *substream)
3957 struct alc_spec *spec = codec->spec;
3958 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3959 stream_tag, format, substream);
3962 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3963 struct hda_codec *codec,
3964 struct snd_pcm_substream *substream)
3966 struct alc_spec *spec = codec->spec;
3967 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3970 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3971 struct hda_codec *codec,
3972 struct snd_pcm_substream *substream)
3974 struct alc_spec *spec = codec->spec;
3975 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3981 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3982 struct hda_codec *codec,
3983 unsigned int stream_tag,
3984 unsigned int format,
3985 struct snd_pcm_substream *substream)
3987 struct alc_spec *spec = codec->spec;
3989 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3990 stream_tag, 0, format);
3994 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3995 struct hda_codec *codec,
3996 struct snd_pcm_substream *substream)
3998 struct alc_spec *spec = codec->spec;
4000 snd_hda_codec_cleanup_stream(codec,
4001 spec->adc_nids[substream->number + 1]);
4005 /* analog capture with dynamic dual-adc changes */
4006 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4007 struct hda_codec *codec,
4008 unsigned int stream_tag,
4009 unsigned int format,
4010 struct snd_pcm_substream *substream)
4012 struct alc_spec *spec = codec->spec;
4013 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4014 spec->cur_adc_stream_tag = stream_tag;
4015 spec->cur_adc_format = format;
4016 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4020 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4021 struct hda_codec *codec,
4022 struct snd_pcm_substream *substream)
4024 struct alc_spec *spec = codec->spec;
4025 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4030 static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4034 .nid = 0, /* fill later */
4036 .prepare = dualmic_capture_pcm_prepare,
4037 .cleanup = dualmic_capture_pcm_cleanup
4043 static struct hda_pcm_stream alc880_pcm_analog_playback = {
4047 /* NID is set in alc_build_pcms */
4049 .open = alc880_playback_pcm_open,
4050 .prepare = alc880_playback_pcm_prepare,
4051 .cleanup = alc880_playback_pcm_cleanup
4055 static struct hda_pcm_stream alc880_pcm_analog_capture = {
4059 /* NID is set in alc_build_pcms */
4062 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4066 /* NID is set in alc_build_pcms */
4069 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4070 .substreams = 2, /* can be overridden */
4073 /* NID is set in alc_build_pcms */
4075 .prepare = alc880_alt_capture_pcm_prepare,
4076 .cleanup = alc880_alt_capture_pcm_cleanup
4080 static struct hda_pcm_stream alc880_pcm_digital_playback = {
4084 /* NID is set in alc_build_pcms */
4086 .open = alc880_dig_playback_pcm_open,
4087 .close = alc880_dig_playback_pcm_close,
4088 .prepare = alc880_dig_playback_pcm_prepare,
4089 .cleanup = alc880_dig_playback_pcm_cleanup
4093 static struct hda_pcm_stream alc880_pcm_digital_capture = {
4097 /* NID is set in alc_build_pcms */
4100 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
4101 static struct hda_pcm_stream alc_pcm_null_stream = {
4107 static int alc_build_pcms(struct hda_codec *codec)
4109 struct alc_spec *spec = codec->spec;
4110 struct hda_pcm *info = spec->pcm_rec;
4113 codec->num_pcms = 1;
4114 codec->pcm_info = info;
4116 if (spec->no_analog)
4119 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4120 "%s Analog", codec->chip_name);
4121 info->name = spec->stream_name_analog;
4123 if (spec->stream_analog_playback) {
4124 if (snd_BUG_ON(!spec->multiout.dac_nids))
4126 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4127 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4129 if (spec->stream_analog_capture) {
4130 if (snd_BUG_ON(!spec->adc_nids))
4132 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4133 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4136 if (spec->channel_mode) {
4137 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4138 for (i = 0; i < spec->num_channel_mode; i++) {
4139 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4140 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4146 /* SPDIF for stream index #1 */
4147 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4148 snprintf(spec->stream_name_digital,
4149 sizeof(spec->stream_name_digital),
4150 "%s Digital", codec->chip_name);
4151 codec->num_pcms = 2;
4152 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4153 info = spec->pcm_rec + 1;
4154 info->name = spec->stream_name_digital;
4155 if (spec->dig_out_type)
4156 info->pcm_type = spec->dig_out_type;
4158 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4159 if (spec->multiout.dig_out_nid &&
4160 spec->stream_digital_playback) {
4161 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4162 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4164 if (spec->dig_in_nid &&
4165 spec->stream_digital_capture) {
4166 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4167 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4169 /* FIXME: do we need this for all Realtek codec models? */
4170 codec->spdif_status_reset = 1;
4173 if (spec->no_analog)
4176 /* If the use of more than one ADC is requested for the current
4177 * model, configure a second analog capture-only PCM.
4179 /* Additional Analaog capture for index #2 */
4180 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4181 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4182 codec->num_pcms = 3;
4183 info = spec->pcm_rec + 2;
4184 info->name = spec->stream_name_analog;
4185 if (spec->alt_dac_nid) {
4186 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4187 *spec->stream_analog_alt_playback;
4188 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4191 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4192 alc_pcm_null_stream;
4193 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4195 if (spec->num_adc_nids > 1) {
4196 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4197 *spec->stream_analog_alt_capture;
4198 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4200 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4201 spec->num_adc_nids - 1;
4203 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4204 alc_pcm_null_stream;
4205 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4212 static inline void alc_shutup(struct hda_codec *codec)
4214 struct alc_spec *spec = codec->spec;
4216 if (spec && spec->shutup)
4217 spec->shutup(codec);
4218 snd_hda_shutup_pins(codec);
4221 static void alc_free_kctls(struct hda_codec *codec)
4223 struct alc_spec *spec = codec->spec;
4225 if (spec->kctls.list) {
4226 struct snd_kcontrol_new *kctl = spec->kctls.list;
4228 for (i = 0; i < spec->kctls.used; i++)
4229 kfree(kctl[i].name);
4231 snd_array_free(&spec->kctls);
4234 static void alc_free(struct hda_codec *codec)
4236 struct alc_spec *spec = codec->spec;
4242 snd_hda_input_jack_free(codec);
4243 alc_free_kctls(codec);
4245 snd_hda_detach_beep_device(codec);
4248 #ifdef CONFIG_SND_HDA_POWER_SAVE
4249 static void alc_power_eapd(struct hda_codec *codec)
4251 alc_auto_setup_eapd(codec, false);
4254 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4256 struct alc_spec *spec = codec->spec;
4258 if (spec && spec->power_hook)
4259 spec->power_hook(codec);
4264 #ifdef SND_HDA_NEEDS_RESUME
4265 static int alc_resume(struct hda_codec *codec)
4267 msleep(150); /* to avoid pop noise */
4268 codec->patch_ops.init(codec);
4269 snd_hda_codec_resume_amp(codec);
4270 snd_hda_codec_resume_cache(codec);
4271 hda_call_check_power_status(codec, 0x01);
4278 static struct hda_codec_ops alc_patch_ops = {
4279 .build_controls = alc_build_controls,
4280 .build_pcms = alc_build_pcms,
4283 .unsol_event = alc_unsol_event,
4284 #ifdef SND_HDA_NEEDS_RESUME
4285 .resume = alc_resume,
4287 #ifdef CONFIG_SND_HDA_POWER_SAVE
4288 .suspend = alc_suspend,
4289 .check_power_status = alc_check_power_status,
4291 .reboot_notify = alc_shutup,
4294 /* replace the codec chip_name with the given string */
4295 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4297 kfree(codec->chip_name);
4298 codec->chip_name = kstrdup(name, GFP_KERNEL);
4299 if (!codec->chip_name) {
4307 * Test configuration for debugging
4309 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4312 #ifdef CONFIG_SND_DEBUG
4313 static hda_nid_t alc880_test_dac_nids[4] = {
4314 0x02, 0x03, 0x04, 0x05
4317 static struct hda_input_mux alc880_test_capture_source = {
4326 { "Surround", 0x6 },
4330 static struct hda_channel_mode alc880_test_modes[4] = {
4337 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4338 struct snd_ctl_elem_info *uinfo)
4340 static char *texts[] = {
4341 "N/A", "Line Out", "HP Out",
4342 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4344 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4346 uinfo->value.enumerated.items = 8;
4347 if (uinfo->value.enumerated.item >= 8)
4348 uinfo->value.enumerated.item = 7;
4349 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4353 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4354 struct snd_ctl_elem_value *ucontrol)
4356 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4357 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4358 unsigned int pin_ctl, item = 0;
4360 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4361 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4362 if (pin_ctl & AC_PINCTL_OUT_EN) {
4363 if (pin_ctl & AC_PINCTL_HP_EN)
4367 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4368 switch (pin_ctl & AC_PINCTL_VREFEN) {
4369 case AC_PINCTL_VREF_HIZ: item = 3; break;
4370 case AC_PINCTL_VREF_50: item = 4; break;
4371 case AC_PINCTL_VREF_GRD: item = 5; break;
4372 case AC_PINCTL_VREF_80: item = 6; break;
4373 case AC_PINCTL_VREF_100: item = 7; break;
4376 ucontrol->value.enumerated.item[0] = item;
4380 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4381 struct snd_ctl_elem_value *ucontrol)
4383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4384 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4385 static unsigned int ctls[] = {
4386 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4387 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4388 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4389 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4390 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4391 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4393 unsigned int old_ctl, new_ctl;
4395 old_ctl = snd_hda_codec_read(codec, nid, 0,
4396 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4397 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4398 if (old_ctl != new_ctl) {
4400 snd_hda_codec_write_cache(codec, nid, 0,
4401 AC_VERB_SET_PIN_WIDGET_CONTROL,
4403 val = ucontrol->value.enumerated.item[0] >= 3 ?
4405 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4412 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4413 struct snd_ctl_elem_info *uinfo)
4415 static char *texts[] = {
4416 "Front", "Surround", "CLFE", "Side"
4418 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4420 uinfo->value.enumerated.items = 4;
4421 if (uinfo->value.enumerated.item >= 4)
4422 uinfo->value.enumerated.item = 3;
4423 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4427 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4428 struct snd_ctl_elem_value *ucontrol)
4430 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4431 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4434 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4435 ucontrol->value.enumerated.item[0] = sel & 3;
4439 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4440 struct snd_ctl_elem_value *ucontrol)
4442 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4443 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4446 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4447 if (ucontrol->value.enumerated.item[0] != sel) {
4448 sel = ucontrol->value.enumerated.item[0] & 3;
4449 snd_hda_codec_write_cache(codec, nid, 0,
4450 AC_VERB_SET_CONNECT_SEL, sel);
4456 #define PIN_CTL_TEST(xname,nid) { \
4457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4459 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4460 .info = alc_test_pin_ctl_info, \
4461 .get = alc_test_pin_ctl_get, \
4462 .put = alc_test_pin_ctl_put, \
4463 .private_value = nid \
4466 #define PIN_SRC_TEST(xname,nid) { \
4467 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4469 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4470 .info = alc_test_pin_src_info, \
4471 .get = alc_test_pin_src_get, \
4472 .put = alc_test_pin_src_put, \
4473 .private_value = nid \
4476 static struct snd_kcontrol_new alc880_test_mixer[] = {
4477 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4478 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4479 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4480 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4481 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4482 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4483 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4484 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4485 PIN_CTL_TEST("Front Pin Mode", 0x14),
4486 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4487 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4488 PIN_CTL_TEST("Side Pin Mode", 0x17),
4489 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4490 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4491 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4492 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4493 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4494 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4495 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4496 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4497 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4498 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4499 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4500 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4501 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4502 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4503 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4504 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4505 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4506 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4509 .name = "Channel Mode",
4510 .info = alc_ch_mode_info,
4511 .get = alc_ch_mode_get,
4512 .put = alc_ch_mode_put,
4517 static struct hda_verb alc880_test_init_verbs[] = {
4518 /* Unmute inputs of 0x0c - 0x0f */
4519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4522 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4524 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4525 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4526 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4527 /* Vol output for 0x0c-0x0f */
4528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4529 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4530 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4531 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4532 /* Set output pins 0x14-0x17 */
4533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4534 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4535 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4536 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4537 /* Unmute output pins 0x14-0x17 */
4538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4540 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4541 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4542 /* Set input pins 0x18-0x1c */
4543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4544 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4545 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4548 /* Mute input pins 0x18-0x1b */
4549 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4550 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4551 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4552 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4554 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4555 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4557 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4559 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4560 /* Analog input/passthru */
4561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4562 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4573 static const char * const alc880_models[ALC880_MODEL_LAST] = {
4574 [ALC880_3ST] = "3stack",
4575 [ALC880_TCL_S700] = "tcl",
4576 [ALC880_3ST_DIG] = "3stack-digout",
4577 [ALC880_CLEVO] = "clevo",
4578 [ALC880_5ST] = "5stack",
4579 [ALC880_5ST_DIG] = "5stack-digout",
4580 [ALC880_W810] = "w810",
4581 [ALC880_Z71V] = "z71v",
4582 [ALC880_6ST] = "6stack",
4583 [ALC880_6ST_DIG] = "6stack-digout",
4584 [ALC880_ASUS] = "asus",
4585 [ALC880_ASUS_W1V] = "asus-w1v",
4586 [ALC880_ASUS_DIG] = "asus-dig",
4587 [ALC880_ASUS_DIG2] = "asus-dig2",
4588 [ALC880_UNIWILL_DIG] = "uniwill",
4589 [ALC880_UNIWILL_P53] = "uniwill-p53",
4590 [ALC880_FUJITSU] = "fujitsu",
4591 [ALC880_F1734] = "F1734",
4593 [ALC880_LG_LW] = "lg-lw",
4594 [ALC880_MEDION_RIM] = "medion",
4595 #ifdef CONFIG_SND_DEBUG
4596 [ALC880_TEST] = "test",
4598 [ALC880_AUTO] = "auto",
4601 static struct snd_pci_quirk alc880_cfg_tbl[] = {
4602 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4603 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4604 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4605 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4606 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4607 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4608 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4609 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4610 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4611 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4612 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4613 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4614 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4615 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4616 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4617 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4618 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4619 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4620 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4621 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4622 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4623 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4624 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4625 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4626 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4627 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4628 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4629 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4630 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4631 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4632 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4633 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4634 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4635 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4636 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4637 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4638 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4639 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4640 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4641 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4642 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4643 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4644 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4645 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4646 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4647 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4648 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4649 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4650 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4651 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4652 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4653 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4654 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4655 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4656 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4657 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4658 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4659 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4660 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4661 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4662 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4663 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4664 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4665 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4666 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4667 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4668 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4669 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4670 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4672 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4673 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4674 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4679 * ALC880 codec presets
4681 static struct alc_config_preset alc880_presets[] = {
4683 .mixers = { alc880_three_stack_mixer },
4684 .init_verbs = { alc880_volume_init_verbs,
4685 alc880_pin_3stack_init_verbs },
4686 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4687 .dac_nids = alc880_dac_nids,
4688 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4689 .channel_mode = alc880_threestack_modes,
4691 .input_mux = &alc880_capture_source,
4693 [ALC880_3ST_DIG] = {
4694 .mixers = { alc880_three_stack_mixer },
4695 .init_verbs = { alc880_volume_init_verbs,
4696 alc880_pin_3stack_init_verbs },
4697 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4698 .dac_nids = alc880_dac_nids,
4699 .dig_out_nid = ALC880_DIGOUT_NID,
4700 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4701 .channel_mode = alc880_threestack_modes,
4703 .input_mux = &alc880_capture_source,
4705 [ALC880_TCL_S700] = {
4706 .mixers = { alc880_tcl_s700_mixer },
4707 .init_verbs = { alc880_volume_init_verbs,
4708 alc880_pin_tcl_S700_init_verbs,
4709 alc880_gpio2_init_verbs },
4710 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4711 .dac_nids = alc880_dac_nids,
4712 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4713 .num_adc_nids = 1, /* single ADC */
4715 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4716 .channel_mode = alc880_2_jack_modes,
4717 .input_mux = &alc880_capture_source,
4720 .mixers = { alc880_three_stack_mixer,
4721 alc880_five_stack_mixer},
4722 .init_verbs = { alc880_volume_init_verbs,
4723 alc880_pin_5stack_init_verbs },
4724 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4725 .dac_nids = alc880_dac_nids,
4726 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4727 .channel_mode = alc880_fivestack_modes,
4728 .input_mux = &alc880_capture_source,
4730 [ALC880_5ST_DIG] = {
4731 .mixers = { alc880_three_stack_mixer,
4732 alc880_five_stack_mixer },
4733 .init_verbs = { alc880_volume_init_verbs,
4734 alc880_pin_5stack_init_verbs },
4735 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4736 .dac_nids = alc880_dac_nids,
4737 .dig_out_nid = ALC880_DIGOUT_NID,
4738 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4739 .channel_mode = alc880_fivestack_modes,
4740 .input_mux = &alc880_capture_source,
4743 .mixers = { alc880_six_stack_mixer },
4744 .init_verbs = { alc880_volume_init_verbs,
4745 alc880_pin_6stack_init_verbs },
4746 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4747 .dac_nids = alc880_6st_dac_nids,
4748 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4749 .channel_mode = alc880_sixstack_modes,
4750 .input_mux = &alc880_6stack_capture_source,
4752 [ALC880_6ST_DIG] = {
4753 .mixers = { alc880_six_stack_mixer },
4754 .init_verbs = { alc880_volume_init_verbs,
4755 alc880_pin_6stack_init_verbs },
4756 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4757 .dac_nids = alc880_6st_dac_nids,
4758 .dig_out_nid = ALC880_DIGOUT_NID,
4759 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4760 .channel_mode = alc880_sixstack_modes,
4761 .input_mux = &alc880_6stack_capture_source,
4764 .mixers = { alc880_w810_base_mixer },
4765 .init_verbs = { alc880_volume_init_verbs,
4766 alc880_pin_w810_init_verbs,
4767 alc880_gpio2_init_verbs },
4768 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4769 .dac_nids = alc880_w810_dac_nids,
4770 .dig_out_nid = ALC880_DIGOUT_NID,
4771 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4772 .channel_mode = alc880_w810_modes,
4773 .input_mux = &alc880_capture_source,
4776 .mixers = { alc880_z71v_mixer },
4777 .init_verbs = { alc880_volume_init_verbs,
4778 alc880_pin_z71v_init_verbs },
4779 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4780 .dac_nids = alc880_z71v_dac_nids,
4781 .dig_out_nid = ALC880_DIGOUT_NID,
4783 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4784 .channel_mode = alc880_2_jack_modes,
4785 .input_mux = &alc880_capture_source,
4788 .mixers = { alc880_f1734_mixer },
4789 .init_verbs = { alc880_volume_init_verbs,
4790 alc880_pin_f1734_init_verbs },
4791 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4792 .dac_nids = alc880_f1734_dac_nids,
4794 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4795 .channel_mode = alc880_2_jack_modes,
4796 .input_mux = &alc880_f1734_capture_source,
4797 .unsol_event = alc880_uniwill_p53_unsol_event,
4798 .setup = alc880_uniwill_p53_setup,
4799 .init_hook = alc_automute_amp,
4802 .mixers = { alc880_asus_mixer },
4803 .init_verbs = { alc880_volume_init_verbs,
4804 alc880_pin_asus_init_verbs,
4805 alc880_gpio1_init_verbs },
4806 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4807 .dac_nids = alc880_asus_dac_nids,
4808 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4809 .channel_mode = alc880_asus_modes,
4811 .input_mux = &alc880_capture_source,
4813 [ALC880_ASUS_DIG] = {
4814 .mixers = { alc880_asus_mixer },
4815 .init_verbs = { alc880_volume_init_verbs,
4816 alc880_pin_asus_init_verbs,
4817 alc880_gpio1_init_verbs },
4818 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4819 .dac_nids = alc880_asus_dac_nids,
4820 .dig_out_nid = ALC880_DIGOUT_NID,
4821 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4822 .channel_mode = alc880_asus_modes,
4824 .input_mux = &alc880_capture_source,
4826 [ALC880_ASUS_DIG2] = {
4827 .mixers = { alc880_asus_mixer },
4828 .init_verbs = { alc880_volume_init_verbs,
4829 alc880_pin_asus_init_verbs,
4830 alc880_gpio2_init_verbs }, /* use GPIO2 */
4831 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4832 .dac_nids = alc880_asus_dac_nids,
4833 .dig_out_nid = ALC880_DIGOUT_NID,
4834 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4835 .channel_mode = alc880_asus_modes,
4837 .input_mux = &alc880_capture_source,
4839 [ALC880_ASUS_W1V] = {
4840 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4841 .init_verbs = { alc880_volume_init_verbs,
4842 alc880_pin_asus_init_verbs,
4843 alc880_gpio1_init_verbs },
4844 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4845 .dac_nids = alc880_asus_dac_nids,
4846 .dig_out_nid = ALC880_DIGOUT_NID,
4847 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4848 .channel_mode = alc880_asus_modes,
4850 .input_mux = &alc880_capture_source,
4852 [ALC880_UNIWILL_DIG] = {
4853 .mixers = { alc880_asus_mixer },
4854 .init_verbs = { alc880_volume_init_verbs,
4855 alc880_pin_asus_init_verbs },
4856 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4857 .dac_nids = alc880_asus_dac_nids,
4858 .dig_out_nid = ALC880_DIGOUT_NID,
4859 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4860 .channel_mode = alc880_asus_modes,
4862 .input_mux = &alc880_capture_source,
4864 [ALC880_UNIWILL] = {
4865 .mixers = { alc880_uniwill_mixer },
4866 .init_verbs = { alc880_volume_init_verbs,
4867 alc880_uniwill_init_verbs },
4868 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4869 .dac_nids = alc880_asus_dac_nids,
4870 .dig_out_nid = ALC880_DIGOUT_NID,
4871 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4872 .channel_mode = alc880_threestack_modes,
4874 .input_mux = &alc880_capture_source,
4875 .unsol_event = alc880_uniwill_unsol_event,
4876 .setup = alc880_uniwill_setup,
4877 .init_hook = alc880_uniwill_init_hook,
4879 [ALC880_UNIWILL_P53] = {
4880 .mixers = { alc880_uniwill_p53_mixer },
4881 .init_verbs = { alc880_volume_init_verbs,
4882 alc880_uniwill_p53_init_verbs },
4883 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4884 .dac_nids = alc880_asus_dac_nids,
4885 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4886 .channel_mode = alc880_threestack_modes,
4887 .input_mux = &alc880_capture_source,
4888 .unsol_event = alc880_uniwill_p53_unsol_event,
4889 .setup = alc880_uniwill_p53_setup,
4890 .init_hook = alc_automute_amp,
4892 [ALC880_FUJITSU] = {
4893 .mixers = { alc880_fujitsu_mixer },
4894 .init_verbs = { alc880_volume_init_verbs,
4895 alc880_uniwill_p53_init_verbs,
4896 alc880_beep_init_verbs },
4897 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4898 .dac_nids = alc880_dac_nids,
4899 .dig_out_nid = ALC880_DIGOUT_NID,
4900 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4901 .channel_mode = alc880_2_jack_modes,
4902 .input_mux = &alc880_capture_source,
4903 .unsol_event = alc880_uniwill_p53_unsol_event,
4904 .setup = alc880_uniwill_p53_setup,
4905 .init_hook = alc_automute_amp,
4908 .mixers = { alc880_three_stack_mixer },
4909 .init_verbs = { alc880_volume_init_verbs,
4910 alc880_pin_clevo_init_verbs },
4911 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4912 .dac_nids = alc880_dac_nids,
4914 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4915 .channel_mode = alc880_threestack_modes,
4917 .input_mux = &alc880_capture_source,
4920 .mixers = { alc880_lg_mixer },
4921 .init_verbs = { alc880_volume_init_verbs,
4922 alc880_lg_init_verbs },
4923 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4924 .dac_nids = alc880_lg_dac_nids,
4925 .dig_out_nid = ALC880_DIGOUT_NID,
4926 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4927 .channel_mode = alc880_lg_ch_modes,
4929 .input_mux = &alc880_lg_capture_source,
4930 .unsol_event = alc_automute_amp_unsol_event,
4931 .setup = alc880_lg_setup,
4932 .init_hook = alc_automute_amp,
4933 #ifdef CONFIG_SND_HDA_POWER_SAVE
4934 .loopbacks = alc880_lg_loopbacks,
4938 .mixers = { alc880_lg_lw_mixer },
4939 .init_verbs = { alc880_volume_init_verbs,
4940 alc880_lg_lw_init_verbs },
4941 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4942 .dac_nids = alc880_dac_nids,
4943 .dig_out_nid = ALC880_DIGOUT_NID,
4944 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4945 .channel_mode = alc880_lg_lw_modes,
4946 .input_mux = &alc880_lg_lw_capture_source,
4947 .unsol_event = alc_automute_amp_unsol_event,
4948 .setup = alc880_lg_lw_setup,
4949 .init_hook = alc_automute_amp,
4951 [ALC880_MEDION_RIM] = {
4952 .mixers = { alc880_medion_rim_mixer },
4953 .init_verbs = { alc880_volume_init_verbs,
4954 alc880_medion_rim_init_verbs,
4955 alc_gpio2_init_verbs },
4956 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4957 .dac_nids = alc880_dac_nids,
4958 .dig_out_nid = ALC880_DIGOUT_NID,
4959 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4960 .channel_mode = alc880_2_jack_modes,
4961 .input_mux = &alc880_medion_rim_capture_source,
4962 .unsol_event = alc880_medion_rim_unsol_event,
4963 .setup = alc880_medion_rim_setup,
4964 .init_hook = alc880_medion_rim_automute,
4966 #ifdef CONFIG_SND_DEBUG
4968 .mixers = { alc880_test_mixer },
4969 .init_verbs = { alc880_test_init_verbs },
4970 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4971 .dac_nids = alc880_test_dac_nids,
4972 .dig_out_nid = ALC880_DIGOUT_NID,
4973 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4974 .channel_mode = alc880_test_modes,
4975 .input_mux = &alc880_test_capture_source,
4981 * Automatic parse of I/O pins from the BIOS configuration
4986 ALC_CTL_WIDGET_MUTE,
4989 static struct snd_kcontrol_new alc880_control_templates[] = {
4990 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4991 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4992 HDA_BIND_MUTE(NULL, 0, 0, 0),
4995 /* add dynamic controls */
4996 static int add_control(struct alc_spec *spec, int type, const char *name,
4997 int cidx, unsigned long val)
4999 struct snd_kcontrol_new *knew;
5001 snd_array_init(&spec->kctls, sizeof(*knew), 32);
5002 knew = snd_array_new(&spec->kctls);
5005 *knew = alc880_control_templates[type];
5006 knew->name = kstrdup(name, GFP_KERNEL);
5010 if (get_amp_nid_(val))
5011 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5012 knew->private_value = val;
5016 static int add_control_with_pfx(struct alc_spec *spec, int type,
5017 const char *pfx, const char *dir,
5018 const char *sfx, int cidx, unsigned long val)
5021 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5022 return add_control(spec, type, name, cidx, val);
5025 #define add_pb_vol_ctrl(spec, type, pfx, val) \
5026 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5027 #define add_pb_sw_ctrl(spec, type, pfx, val) \
5028 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5029 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5030 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5031 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5032 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5034 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5035 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5036 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5037 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5038 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
5039 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
5040 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5041 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
5042 #define ALC880_PIN_CD_NID 0x1c
5044 /* fill in the dac_nids table from the parsed pin configuration */
5045 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5046 const struct auto_pin_cfg *cfg)
5052 memset(assigned, 0, sizeof(assigned));
5053 spec->multiout.dac_nids = spec->private_dac_nids;
5055 /* check the pins hardwired to audio widget */
5056 for (i = 0; i < cfg->line_outs; i++) {
5057 nid = cfg->line_out_pins[i];
5058 if (alc880_is_fixed_pin(nid)) {
5059 int idx = alc880_fixed_pin_idx(nid);
5060 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
5064 /* left pins can be connect to any audio widget */
5065 for (i = 0; i < cfg->line_outs; i++) {
5066 nid = cfg->line_out_pins[i];
5067 if (alc880_is_fixed_pin(nid))
5069 /* search for an empty channel */
5070 for (j = 0; j < cfg->line_outs; j++) {
5072 spec->multiout.dac_nids[i] =
5073 alc880_idx_to_dac(j);
5079 spec->multiout.num_dacs = cfg->line_outs;
5083 static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5086 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5089 switch (cfg->line_out_type) {
5090 case AUTO_PIN_SPEAKER_OUT:
5091 if (cfg->line_outs == 1)
5094 case AUTO_PIN_HP_OUT:
5097 if (cfg->line_outs == 1)
5104 /* add playback controls from the parsed DAC table */
5105 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5106 const struct auto_pin_cfg *cfg)
5108 static const char * const chname[4] = {
5109 "Front", "Surround", NULL /*CLFE*/, "Side"
5111 const char *pfx = alc_get_line_out_pfx(cfg, false);
5115 for (i = 0; i < cfg->line_outs; i++) {
5116 if (!spec->multiout.dac_nids[i])
5118 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5119 if (!pfx && i == 2) {
5121 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5123 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5127 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5129 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5133 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5135 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5139 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5141 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5146 const char *name = pfx;
5152 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5154 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5158 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5160 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5169 /* add playback controls for speaker and HP outputs */
5170 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5179 if (alc880_is_fixed_pin(pin)) {
5180 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5181 /* specify the DAC as the extra output */
5182 if (!spec->multiout.hp_nid)
5183 spec->multiout.hp_nid = nid;
5185 spec->multiout.extra_out_nid[0] = nid;
5186 /* control HP volume/switch on the output mixer amp */
5187 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5188 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5189 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5192 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5193 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5196 } else if (alc880_is_multi_pin(pin)) {
5197 /* set manual connection */
5198 /* we have only a switch on HP-out PIN */
5199 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5200 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5207 /* create input playback/capture controls for the given pin */
5208 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5209 const char *ctlname, int ctlidx,
5210 int idx, hda_nid_t mix_nid)
5214 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5215 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5218 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5219 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5225 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5227 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5228 return (pincap & AC_PINCAP_IN) != 0;
5231 /* create playback/capture controls for input pins */
5232 static int alc_auto_create_input_ctls(struct hda_codec *codec,
5233 const struct auto_pin_cfg *cfg,
5235 hda_nid_t cap1, hda_nid_t cap2)
5237 struct alc_spec *spec = codec->spec;
5238 struct hda_input_mux *imux = &spec->private_imux[0];
5239 int i, err, idx, type_idx = 0;
5240 const char *prev_label = NULL;
5242 for (i = 0; i < cfg->num_inputs; i++) {
5246 pin = cfg->inputs[i].pin;
5247 if (!alc_is_input_pin(codec, pin))
5250 label = hda_get_autocfg_input_label(codec, cfg, i);
5251 if (prev_label && !strcmp(label, prev_label))
5258 idx = get_connection_index(codec, mixer, pin);
5260 err = new_analog_input(spec, pin,
5270 idx = get_connection_index(codec, cap1, pin);
5271 if (idx < 0 && cap2)
5272 idx = get_connection_index(codec, cap2, pin);
5274 snd_hda_add_imux_item(imux, label, idx, NULL);
5279 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5280 const struct auto_pin_cfg *cfg)
5282 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5285 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5286 unsigned int pin_type)
5288 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5291 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5295 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5296 hda_nid_t nid, int pin_type,
5299 alc_set_pin_output(codec, nid, pin_type);
5300 /* need the manual connection? */
5301 if (alc880_is_multi_pin(nid)) {
5302 struct alc_spec *spec = codec->spec;
5303 int idx = alc880_multi_pin_idx(nid);
5304 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5305 AC_VERB_SET_CONNECT_SEL,
5306 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5310 static int get_pin_type(int line_out_type)
5312 if (line_out_type == AUTO_PIN_HP_OUT)
5318 static void alc880_auto_init_multi_out(struct hda_codec *codec)
5320 struct alc_spec *spec = codec->spec;
5323 for (i = 0; i < spec->autocfg.line_outs; i++) {
5324 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5325 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5326 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5330 static void alc880_auto_init_extra_out(struct hda_codec *codec)
5332 struct alc_spec *spec = codec->spec;
5335 pin = spec->autocfg.speaker_pins[0];
5336 if (pin) /* connect to front */
5337 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5338 pin = spec->autocfg.hp_pins[0];
5339 if (pin) /* connect to front */
5340 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5343 static void alc880_auto_init_analog_input(struct hda_codec *codec)
5345 struct alc_spec *spec = codec->spec;
5346 struct auto_pin_cfg *cfg = &spec->autocfg;
5349 for (i = 0; i < cfg->num_inputs; i++) {
5350 hda_nid_t nid = cfg->inputs[i].pin;
5351 if (alc_is_input_pin(codec, nid)) {
5352 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5353 if (nid != ALC880_PIN_CD_NID &&
5354 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5355 snd_hda_codec_write(codec, nid, 0,
5356 AC_VERB_SET_AMP_GAIN_MUTE,
5362 static void alc880_auto_init_input_src(struct hda_codec *codec)
5364 struct alc_spec *spec = codec->spec;
5367 for (c = 0; c < spec->num_adc_nids; c++) {
5368 unsigned int mux_idx;
5369 const struct hda_input_mux *imux;
5370 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5371 imux = &spec->input_mux[mux_idx];
5372 if (!imux->num_items && mux_idx > 0)
5373 imux = &spec->input_mux[0];
5375 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5376 AC_VERB_SET_CONNECT_SEL,
5377 imux->items[0].index);
5381 /* parse the BIOS configuration and set up the alc_spec */
5382 /* return 1 if successful, 0 if the proper config is not found,
5383 * or a negative error code
5385 static int alc880_parse_auto_config(struct hda_codec *codec)
5387 struct alc_spec *spec = codec->spec;
5389 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5391 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5395 if (!spec->autocfg.line_outs)
5396 return 0; /* can't find valid BIOS pin config */
5398 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5401 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5404 err = alc880_auto_create_extra_out(spec,
5405 spec->autocfg.speaker_pins[0],
5409 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5413 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5417 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5419 alc_auto_parse_digital(codec);
5421 if (spec->kctls.list)
5422 add_mixer(spec, spec->kctls.list);
5424 add_verb(spec, alc880_volume_init_verbs);
5426 spec->num_mux_defs = 1;
5427 spec->input_mux = &spec->private_imux[0];
5429 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5434 /* additional initialization for auto-configuration model */
5435 static void alc880_auto_init(struct hda_codec *codec)
5437 struct alc_spec *spec = codec->spec;
5438 alc880_auto_init_multi_out(codec);
5439 alc880_auto_init_extra_out(codec);
5440 alc880_auto_init_analog_input(codec);
5441 alc880_auto_init_input_src(codec);
5442 alc_auto_init_digital(codec);
5443 if (spec->unsol_event)
5444 alc_inithook(codec);
5447 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5448 * one of two digital mic pins, e.g. on ALC272
5450 static void fixup_automic_adc(struct hda_codec *codec)
5452 struct alc_spec *spec = codec->spec;
5455 for (i = 0; i < spec->num_adc_nids; i++) {
5456 hda_nid_t cap = spec->capsrc_nids ?
5457 spec->capsrc_nids[i] : spec->adc_nids[i];
5460 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5463 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5466 spec->int_mic.mux_idx = iidx;
5467 spec->ext_mic.mux_idx = eidx;
5468 if (spec->capsrc_nids)
5469 spec->capsrc_nids += i;
5470 spec->adc_nids += i;
5471 spec->num_adc_nids = 1;
5474 snd_printd(KERN_INFO "hda_codec: %s: "
5475 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5476 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5477 spec->auto_mic = 0; /* disable auto-mic to be sure */
5480 /* select or unmute the given capsrc route */
5481 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5484 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5485 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5488 snd_hda_codec_write_cache(codec, cap, 0,
5489 AC_VERB_SET_CONNECT_SEL, idx);
5493 /* set the default connection to that pin */
5494 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5496 struct alc_spec *spec = codec->spec;
5499 for (i = 0; i < spec->num_adc_nids; i++) {
5500 hda_nid_t cap = spec->capsrc_nids ?
5501 spec->capsrc_nids[i] : spec->adc_nids[i];
5504 idx = get_connection_index(codec, cap, pin);
5507 select_or_unmute_capsrc(codec, cap, idx);
5508 return i; /* return the found index */
5510 return -1; /* not found */
5513 /* choose the ADC/MUX containing the input pin and initialize the setup */
5514 static void fixup_single_adc(struct hda_codec *codec)
5516 struct alc_spec *spec = codec->spec;
5517 struct auto_pin_cfg *cfg = &spec->autocfg;
5520 /* search for the input pin; there must be only one */
5521 if (cfg->num_inputs != 1)
5523 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5525 /* use only this ADC */
5526 if (spec->capsrc_nids)
5527 spec->capsrc_nids += i;
5528 spec->adc_nids += i;
5529 spec->num_adc_nids = 1;
5530 spec->single_input_src = 1;
5534 /* initialize dual adcs */
5535 static void fixup_dual_adc_switch(struct hda_codec *codec)
5537 struct alc_spec *spec = codec->spec;
5538 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5539 init_capsrc_for_pin(codec, spec->int_mic.pin);
5542 /* initialize some special cases for input sources */
5543 static void alc_init_special_input_src(struct hda_codec *codec)
5545 struct alc_spec *spec = codec->spec;
5546 if (spec->dual_adc_switch)
5547 fixup_dual_adc_switch(codec);
5548 else if (spec->single_input_src)
5549 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5552 static void set_capture_mixer(struct hda_codec *codec)
5554 struct alc_spec *spec = codec->spec;
5555 static struct snd_kcontrol_new *caps[2][3] = {
5556 { alc_capture_mixer_nosrc1,
5557 alc_capture_mixer_nosrc2,
5558 alc_capture_mixer_nosrc3 },
5559 { alc_capture_mixer1,
5561 alc_capture_mixer3 },
5563 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5565 int num_adcs = spec->num_adc_nids;
5566 if (spec->dual_adc_switch)
5568 else if (spec->auto_mic)
5569 fixup_automic_adc(codec);
5570 else if (spec->input_mux) {
5571 if (spec->input_mux->num_items > 1)
5573 else if (spec->input_mux->num_items == 1)
5574 fixup_single_adc(codec);
5576 spec->cap_mixer = caps[mux][num_adcs - 1];
5580 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5581 static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5584 struct alc_spec *spec = codec->spec;
5585 struct auto_pin_cfg *cfg = &spec->autocfg;
5587 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5589 for (n = 0; n < num_nids; n++) {
5591 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5595 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5598 nconns = snd_hda_get_connections(codec, cap, conn,
5602 nconns = snd_hda_get_connections(codec, cap, conn,
5607 if (!fallback_adc) {
5611 for (i = 0; i < cfg->num_inputs; i++) {
5612 hda_nid_t nid = cfg->inputs[i].pin;
5613 for (j = 0; j < nconns; j++) {
5620 if (i >= cfg->num_inputs) {
5621 int num_adcs = spec->num_adc_nids;
5622 spec->private_adc_nids[num_adcs] = adc;
5623 spec->private_capsrc_nids[num_adcs] = cap;
5624 spec->num_adc_nids++;
5625 spec->adc_nids = spec->private_adc_nids;
5627 spec->capsrc_nids = spec->private_capsrc_nids;
5630 if (!spec->num_adc_nids) {
5631 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5632 " using fallback 0x%x\n",
5633 codec->chip_name, fallback_adc);
5634 spec->private_adc_nids[0] = fallback_adc;
5635 spec->adc_nids = spec->private_adc_nids;
5636 if (fallback_adc != fallback_cap) {
5637 spec->private_capsrc_nids[0] = fallback_cap;
5638 spec->capsrc_nids = spec->private_adc_nids;
5643 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5644 #define set_beep_amp(spec, nid, idx, dir) \
5645 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5647 static struct snd_pci_quirk beep_white_list[] = {
5648 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5649 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5650 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5654 static inline int has_cdefine_beep(struct hda_codec *codec)
5656 struct alc_spec *spec = codec->spec;
5657 const struct snd_pci_quirk *q;
5658 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5661 return spec->cdefine.enable_pcbeep;
5664 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5665 #define has_cdefine_beep(codec) 0
5669 * OK, here we have finally the patch for ALC880
5672 static int patch_alc880(struct hda_codec *codec)
5674 struct alc_spec *spec;
5678 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5684 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5687 if (board_config < 0) {
5688 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5690 board_config = ALC880_AUTO;
5693 if (board_config == ALC880_AUTO) {
5694 /* automatic parse from the BIOS config */
5695 err = alc880_parse_auto_config(codec);
5701 "hda_codec: Cannot set up configuration "
5702 "from BIOS. Using 3-stack mode...\n");
5703 board_config = ALC880_3ST;
5707 err = snd_hda_attach_beep_device(codec, 0x1);
5713 if (board_config != ALC880_AUTO)
5714 setup_preset(codec, &alc880_presets[board_config]);
5716 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5717 spec->stream_analog_capture = &alc880_pcm_analog_capture;
5718 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
5720 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5721 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5723 if (!spec->adc_nids && spec->input_mux) {
5724 /* check whether NID 0x07 is valid */
5725 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
5727 wcap = get_wcaps_type(wcap);
5728 if (wcap != AC_WID_AUD_IN) {
5729 spec->adc_nids = alc880_adc_nids_alt;
5730 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
5732 spec->adc_nids = alc880_adc_nids;
5733 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
5736 set_capture_mixer(codec);
5737 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5739 spec->vmaster_nid = 0x0c;
5741 codec->patch_ops = alc_patch_ops;
5742 if (board_config == ALC880_AUTO)
5743 spec->init_hook = alc880_auto_init;
5744 #ifdef CONFIG_SND_HDA_POWER_SAVE
5745 if (!spec->loopback.amplist)
5746 spec->loopback.amplist = alc880_loopbacks;
5757 static hda_nid_t alc260_dac_nids[1] = {
5762 static hda_nid_t alc260_adc_nids[1] = {
5767 static hda_nid_t alc260_adc_nids_alt[1] = {
5772 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5773 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5775 static hda_nid_t alc260_dual_adc_nids[2] = {
5780 #define ALC260_DIGOUT_NID 0x03
5781 #define ALC260_DIGIN_NID 0x06
5783 static struct hda_input_mux alc260_capture_source = {
5787 { "Front Mic", 0x1 },
5793 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5794 * headphone jack and the internal CD lines since these are the only pins at
5795 * which audio can appear. For flexibility, also allow the option of
5796 * recording the mixer output on the second ADC (ADC0 doesn't have a
5797 * connection to the mixer output).
5799 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5803 { "Mic/Line", 0x0 },
5805 { "Headphone", 0x2 },
5811 { "Mic/Line", 0x0 },
5813 { "Headphone", 0x2 },
5820 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5821 * the Fujitsu S702x, but jacks are marked differently.
5823 static struct hda_input_mux alc260_acer_capture_sources[2] = {
5830 { "Headphone", 0x5 },
5839 { "Headphone", 0x6 },
5845 /* Maxdata Favorit 100XS */
5846 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5850 { "Line/Mic", 0x0 },
5857 { "Line/Mic", 0x0 },
5865 * This is just place-holder, so there's something for alc_build_pcms to look
5866 * at when it calculates the maximum number of channels. ALC260 has no mixer
5867 * element which allows changing the channel mode, so the verb list is
5870 static struct hda_channel_mode alc260_modes[1] = {
5875 /* Mixer combinations
5877 * basic: base_output + input + pc_beep + capture
5878 * HP: base_output + input + capture_alt
5879 * HP_3013: hp_3013 + input + capture
5880 * fujitsu: fujitsu + capture
5881 * acer: acer + capture
5884 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5885 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5886 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5887 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5888 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5889 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5890 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5894 static struct snd_kcontrol_new alc260_input_mixer[] = {
5895 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5896 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5897 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5898 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5899 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5900 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5901 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5902 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5906 /* update HP, line and mono out pins according to the master switch */
5907 static void alc260_hp_master_update(struct hda_codec *codec,
5908 hda_nid_t hp, hda_nid_t line,
5911 struct alc_spec *spec = codec->spec;
5912 unsigned int val = spec->master_sw ? PIN_HP : 0;
5913 /* change HP and line-out pins */
5914 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5916 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5918 /* mono (speaker) depending on the HP jack sense */
5919 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5920 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5924 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5925 struct snd_ctl_elem_value *ucontrol)
5927 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5928 struct alc_spec *spec = codec->spec;
5929 *ucontrol->value.integer.value = spec->master_sw;
5933 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5934 struct snd_ctl_elem_value *ucontrol)
5936 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5937 struct alc_spec *spec = codec->spec;
5938 int val = !!*ucontrol->value.integer.value;
5939 hda_nid_t hp, line, mono;
5941 if (val == spec->master_sw)
5943 spec->master_sw = val;
5944 hp = (kcontrol->private_value >> 16) & 0xff;
5945 line = (kcontrol->private_value >> 8) & 0xff;
5946 mono = kcontrol->private_value & 0xff;
5947 alc260_hp_master_update(codec, hp, line, mono);
5951 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5953 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5954 .name = "Master Playback Switch",
5955 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5956 .info = snd_ctl_boolean_mono_info,
5957 .get = alc260_hp_master_sw_get,
5958 .put = alc260_hp_master_sw_put,
5959 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5961 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5962 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5963 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5964 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5965 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5967 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5971 static struct hda_verb alc260_hp_unsol_verbs[] = {
5972 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5976 static void alc260_hp_automute(struct hda_codec *codec)
5978 struct alc_spec *spec = codec->spec;
5980 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5981 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5984 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5986 if ((res >> 26) == ALC880_HP_EVENT)
5987 alc260_hp_automute(codec);
5990 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5992 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5993 .name = "Master Playback Switch",
5994 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5995 .info = snd_ctl_boolean_mono_info,
5996 .get = alc260_hp_master_sw_get,
5997 .put = alc260_hp_master_sw_put,
5998 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
6000 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6001 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6002 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6003 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6004 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6005 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6006 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6007 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6011 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6012 .ops = &snd_hda_bind_vol,
6014 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6015 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6016 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6021 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6022 .ops = &snd_hda_bind_sw,
6024 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6025 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6030 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6031 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6032 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6033 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6038 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6039 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6043 static void alc260_hp_3013_automute(struct hda_codec *codec)
6045 struct alc_spec *spec = codec->spec;
6047 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
6048 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
6051 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6054 if ((res >> 26) == ALC880_HP_EVENT)
6055 alc260_hp_3013_automute(codec);
6058 static void alc260_hp_3012_automute(struct hda_codec *codec)
6060 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
6062 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6064 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6066 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6070 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6073 if ((res >> 26) == ALC880_HP_EVENT)
6074 alc260_hp_3012_automute(codec);
6077 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6078 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6080 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6081 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6082 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6083 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6084 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6085 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6086 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6087 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6088 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6089 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6090 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6094 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6095 * versions of the ALC260 don't act on requests to enable mic bias from NID
6096 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6097 * datasheet doesn't mention this restriction. At this stage it's not clear
6098 * whether this behaviour is intentional or is a hardware bug in chip
6099 * revisions available in early 2006. Therefore for now allow the
6100 * "Headphone Jack Mode" control to span all choices, but if it turns out
6101 * that the lack of mic bias for this NID is intentional we could change the
6102 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6104 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6105 * don't appear to make the mic bias available from the "line" jack, even
6106 * though the NID used for this jack (0x14) can supply it. The theory is
6107 * that perhaps Acer have included blocking capacitors between the ALC260
6108 * and the output jack. If this turns out to be the case for all such
6109 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6110 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6112 * The C20x Tablet series have a mono internal speaker which is controlled
6113 * via the chip's Mono sum widget and pin complex, so include the necessary
6114 * controls for such models. On models without a "mono speaker" the control
6115 * won't do anything.
6117 static struct snd_kcontrol_new alc260_acer_mixer[] = {
6118 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6119 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6120 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6121 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6123 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6125 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6126 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6128 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6129 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6130 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6131 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6132 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6136 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
6138 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6139 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6140 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6141 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6142 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6143 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6144 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6148 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6149 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6151 static struct snd_kcontrol_new alc260_will_mixer[] = {
6152 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6153 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6155 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6156 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6157 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6158 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6159 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6160 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6161 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6165 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6166 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6168 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6169 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6170 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6171 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6172 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6173 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6174 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6175 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6176 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6177 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6178 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6183 * initialization verbs
6185 static struct hda_verb alc260_init_verbs[] = {
6186 /* Line In pin widget for input */
6187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6188 /* CD pin widget for input */
6189 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6190 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6191 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6192 /* Mic2 (front panel) pin widget for input and vref at 80% */
6193 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6194 /* LINE-2 is used for line-out in rear */
6195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6196 /* select line-out */
6197 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6199 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6201 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6203 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6204 /* mute capture amp left and right */
6205 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6206 /* set connection select to line in (default select for this ADC) */
6207 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6208 /* mute capture amp left and right */
6209 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6210 /* set connection select to line in (default select for this ADC) */
6211 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6212 /* set vol=0 Line-Out mixer amp left and right */
6213 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6214 /* unmute pin widget amp left and right (no gain on this amp) */
6215 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6216 /* set vol=0 HP mixer amp left and right */
6217 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6218 /* unmute pin widget amp left and right (no gain on this amp) */
6219 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6220 /* set vol=0 Mono mixer amp left and right */
6221 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6222 /* unmute pin widget amp left and right (no gain on this amp) */
6223 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6224 /* unmute LINE-2 out pin */
6225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6226 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6229 /* mute analog inputs */
6230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6233 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6234 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6235 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6236 /* mute Front out path */
6237 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6238 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6239 /* mute Headphone out path */
6240 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6241 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6242 /* mute Mono out path */
6243 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6244 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6248 #if 0 /* should be identical with alc260_init_verbs? */
6249 static struct hda_verb alc260_hp_init_verbs[] = {
6250 /* Headphone and output */
6251 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6253 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6254 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6255 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6256 /* Mic2 (front panel) pin widget for input and vref at 80% */
6257 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6258 /* Line In pin widget for input */
6259 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6260 /* Line-2 pin widget for output */
6261 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6262 /* CD pin widget for input */
6263 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6264 /* unmute amp left and right */
6265 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6266 /* set connection select to line in (default select for this ADC) */
6267 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6268 /* unmute Line-Out mixer amp left and right (volume = 0) */
6269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6270 /* mute pin widget amp left and right (no gain on this amp) */
6271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6272 /* unmute HP mixer amp left and right (volume = 0) */
6273 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6274 /* mute pin widget amp left and right (no gain on this amp) */
6275 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6276 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6279 /* mute analog inputs */
6280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6285 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6286 /* Unmute Front out path */
6287 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6288 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6289 /* Unmute Headphone out path */
6290 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6292 /* Unmute Mono out path */
6293 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6294 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6299 static struct hda_verb alc260_hp_3013_init_verbs[] = {
6300 /* Line out and output */
6301 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6303 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6304 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6305 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6306 /* Mic2 (front panel) pin widget for input and vref at 80% */
6307 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6308 /* Line In pin widget for input */
6309 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6310 /* Headphone pin widget for output */
6311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6312 /* CD pin widget for input */
6313 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6314 /* unmute amp left and right */
6315 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6316 /* set connection select to line in (default select for this ADC) */
6317 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6318 /* unmute Line-Out mixer amp left and right (volume = 0) */
6319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6320 /* mute pin widget amp left and right (no gain on this amp) */
6321 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6322 /* unmute HP mixer amp left and right (volume = 0) */
6323 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6324 /* mute pin widget amp left and right (no gain on this amp) */
6325 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6326 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6329 /* mute analog inputs */
6330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6335 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6336 /* Unmute Front out path */
6337 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6338 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6339 /* Unmute Headphone out path */
6340 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6341 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6342 /* Unmute Mono out path */
6343 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6344 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6348 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6349 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6350 * audio = 0x16, internal speaker = 0x10.
6352 static struct hda_verb alc260_fujitsu_init_verbs[] = {
6353 /* Disable all GPIOs */
6354 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6355 /* Internal speaker is connected to headphone pin */
6356 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6357 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6358 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6359 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6360 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6361 /* Ensure all other unused pins are disabled and muted. */
6362 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6363 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6364 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6365 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6366 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6367 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6371 /* Disable digital (SPDIF) pins */
6372 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6373 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6375 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6376 * when acting as an output.
6378 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6380 /* Start with output sum widgets muted and their output gains at min */
6381 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6382 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6384 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6385 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6387 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6388 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6389 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6391 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6392 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6393 /* Unmute Line1 pin widget output buffer since it starts as an output.
6394 * If the pin mode is changed by the user the pin mode control will
6395 * take care of enabling the pin's input/output buffers as needed.
6396 * Therefore there's no need to enable the input buffer at this
6399 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6400 /* Unmute input buffer of pin widget used for Line-in (no equiv
6403 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6405 /* Mute capture amp left and right */
6406 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6407 /* Set ADC connection select to match default mixer setting - line
6410 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6412 /* Do the same for the second ADC: mute capture input amp and
6413 * set ADC connection to line in (on mic1 pin)
6415 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6416 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6418 /* Mute all inputs to mixer widget (even unconnected ones) */
6419 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6421 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6422 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6423 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6426 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6431 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6432 * similar laptops (adapted from Fujitsu init verbs).
6434 static struct hda_verb alc260_acer_init_verbs[] = {
6435 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6436 * the headphone jack. Turn this on and rely on the standard mute
6437 * methods whenever the user wants to turn these outputs off.
6439 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6440 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6441 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6442 /* Internal speaker/Headphone jack is connected to Line-out pin */
6443 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6444 /* Internal microphone/Mic jack is connected to Mic1 pin */
6445 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6446 /* Line In jack is connected to Line1 pin */
6447 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6448 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6449 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6450 /* Ensure all other unused pins are disabled and muted. */
6451 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6452 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6453 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6454 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6455 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6457 /* Disable digital (SPDIF) pins */
6458 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6459 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6461 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6462 * bus when acting as outputs.
6464 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6465 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6467 /* Start with output sum widgets muted and their output gains at min */
6468 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6469 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6470 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6471 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6472 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6473 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6474 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6475 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6476 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6478 /* Unmute Line-out pin widget amp left and right
6479 * (no equiv mixer ctrl)
6481 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6482 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6483 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6484 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6485 * inputs. If the pin mode is changed by the user the pin mode control
6486 * will take care of enabling the pin's input/output buffers as needed.
6487 * Therefore there's no need to enable the input buffer at this
6490 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6491 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6493 /* Mute capture amp left and right */
6494 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6495 /* Set ADC connection select to match default mixer setting - mic
6498 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6500 /* Do similar with the second ADC: mute capture input amp and
6501 * set ADC connection to mic to match ALSA's default state.
6503 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6504 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6506 /* Mute all inputs to mixer widget (even unconnected ones) */
6507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6510 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6511 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6512 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6513 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6514 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6519 /* Initialisation sequence for Maxdata Favorit 100XS
6520 * (adapted from Acer init verbs).
6522 static struct hda_verb alc260_favorit100_init_verbs[] = {
6523 /* GPIO 0 enables the output jack.
6524 * Turn this on and rely on the standard mute
6525 * methods whenever the user wants to turn these outputs off.
6527 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6528 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6529 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6530 /* Line/Mic input jack is connected to Mic1 pin */
6531 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6532 /* Ensure all other unused pins are disabled and muted. */
6533 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6534 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6535 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6536 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6537 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6538 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6539 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6543 /* Disable digital (SPDIF) pins */
6544 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6545 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6547 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6548 * bus when acting as outputs.
6550 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6551 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6553 /* Start with output sum widgets muted and their output gains at min */
6554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6555 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6557 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6560 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6561 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6564 /* Unmute Line-out pin widget amp left and right
6565 * (no equiv mixer ctrl)
6567 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6568 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6569 * inputs. If the pin mode is changed by the user the pin mode control
6570 * will take care of enabling the pin's input/output buffers as needed.
6571 * Therefore there's no need to enable the input buffer at this
6574 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6576 /* Mute capture amp left and right */
6577 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6578 /* Set ADC connection select to match default mixer setting - mic
6581 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6583 /* Do similar with the second ADC: mute capture input amp and
6584 * set ADC connection to mic to match ALSA's default state.
6586 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6587 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6589 /* Mute all inputs to mixer widget (even unconnected ones) */
6590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6596 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6597 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6602 static struct hda_verb alc260_will_verbs[] = {
6603 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6604 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6605 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6606 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6607 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6608 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6612 static struct hda_verb alc260_replacer_672v_verbs[] = {
6613 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6614 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6615 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6617 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6618 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6619 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6621 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6625 /* toggle speaker-output according to the hp-jack state */
6626 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6628 unsigned int present;
6630 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6631 present = snd_hda_jack_detect(codec, 0x0f);
6633 snd_hda_codec_write_cache(codec, 0x01, 0,
6634 AC_VERB_SET_GPIO_DATA, 1);
6635 snd_hda_codec_write_cache(codec, 0x0f, 0,
6636 AC_VERB_SET_PIN_WIDGET_CONTROL,
6639 snd_hda_codec_write_cache(codec, 0x01, 0,
6640 AC_VERB_SET_GPIO_DATA, 0);
6641 snd_hda_codec_write_cache(codec, 0x0f, 0,
6642 AC_VERB_SET_PIN_WIDGET_CONTROL,
6647 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6650 if ((res >> 26) == ALC880_HP_EVENT)
6651 alc260_replacer_672v_automute(codec);
6654 static struct hda_verb alc260_hp_dc7600_verbs[] = {
6655 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6657 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6658 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6659 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6661 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6662 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6663 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6664 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6668 /* Test configuration for debugging, modelled after the ALC880 test
6671 #ifdef CONFIG_SND_DEBUG
6672 static hda_nid_t alc260_test_dac_nids[1] = {
6675 static hda_nid_t alc260_test_adc_nids[2] = {
6678 /* For testing the ALC260, each input MUX needs its own definition since
6679 * the signal assignments are different. This assumes that the first ADC
6682 static struct hda_input_mux alc260_test_capture_sources[2] = {
6686 { "MIC1 pin", 0x0 },
6687 { "MIC2 pin", 0x1 },
6688 { "LINE1 pin", 0x2 },
6689 { "LINE2 pin", 0x3 },
6691 { "LINE-OUT pin", 0x5 },
6692 { "HP-OUT pin", 0x6 },
6698 { "MIC1 pin", 0x0 },
6699 { "MIC2 pin", 0x1 },
6700 { "LINE1 pin", 0x2 },
6701 { "LINE2 pin", 0x3 },
6704 { "LINE-OUT pin", 0x6 },
6705 { "HP-OUT pin", 0x7 },
6709 static struct snd_kcontrol_new alc260_test_mixer[] = {
6710 /* Output driver widgets */
6711 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6712 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6713 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6714 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6715 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6716 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6718 /* Modes for retasking pin widgets
6719 * Note: the ALC260 doesn't seem to act on requests to enable mic
6720 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6721 * mention this restriction. At this stage it's not clear whether
6722 * this behaviour is intentional or is a hardware bug in chip
6723 * revisions available at least up until early 2006. Therefore for
6724 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6725 * choices, but if it turns out that the lack of mic bias for these
6726 * NIDs is intentional we could change their modes from
6727 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6729 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6730 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6731 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6732 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6733 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6734 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6736 /* Loopback mixer controls */
6737 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6738 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6739 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6740 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6741 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6742 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6743 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6744 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6745 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6746 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6747 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6748 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6749 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6750 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6752 /* Controls for GPIO pins, assuming they are configured as outputs */
6753 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6754 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6755 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6756 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6758 /* Switches to allow the digital IO pins to be enabled. The datasheet
6759 * is ambigious as to which NID is which; testing on laptops which
6760 * make this output available should provide clarification.
6762 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6763 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6765 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6766 * this output to turn on an external amplifier.
6768 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6769 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6773 static struct hda_verb alc260_test_init_verbs[] = {
6774 /* Enable all GPIOs as outputs with an initial value of 0 */
6775 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6776 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6777 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6779 /* Enable retasking pins as output, initially without power amp */
6780 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6781 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6782 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6783 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6784 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6785 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6787 /* Disable digital (SPDIF) pins initially, but users can enable
6788 * them via a mixer switch. In the case of SPDIF-out, this initverb
6789 * payload also sets the generation to 0, output to be in "consumer"
6790 * PCM format, copyright asserted, no pre-emphasis and no validity
6793 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6794 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6796 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6797 * OUT1 sum bus when acting as an output.
6799 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6800 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6801 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6802 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6804 /* Start with output sum widgets muted and their output gains at min */
6805 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6806 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6807 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6808 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6809 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6810 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6811 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6812 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6813 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6815 /* Unmute retasking pin widget output buffers since the default
6816 * state appears to be output. As the pin mode is changed by the
6817 * user the pin mode control will take care of enabling the pin's
6818 * input/output buffers as needed.
6820 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6821 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6824 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6825 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6826 /* Also unmute the mono-out pin widget */
6827 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6829 /* Mute capture amp left and right */
6830 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6831 /* Set ADC connection select to match default mixer setting (mic1
6834 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6836 /* Do the same for the second ADC: mute capture input amp and
6837 * set ADC connection to mic1 pin
6839 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6840 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6842 /* Mute all inputs to mixer widget (even unconnected ones) */
6843 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6844 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6845 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6846 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6847 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6848 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6849 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6850 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6856 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6857 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
6859 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
6860 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
6863 * for BIOS auto-configuration
6866 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6867 const char *pfx, int *vol_bits)
6870 unsigned long vol_val, sw_val;
6873 if (nid >= 0x0f && nid < 0x11) {
6874 nid_vol = nid - 0x7;
6875 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6876 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6877 } else if (nid == 0x11) {
6878 nid_vol = nid - 0x7;
6879 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6880 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6881 } else if (nid >= 0x12 && nid <= 0x15) {
6883 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6884 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6888 if (!(*vol_bits & (1 << nid_vol))) {
6889 /* first control for the volume widget */
6890 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6893 *vol_bits |= (1 << nid_vol);
6895 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6901 /* add playback controls from the parsed DAC table */
6902 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6903 const struct auto_pin_cfg *cfg)
6909 spec->multiout.num_dacs = 1;
6910 spec->multiout.dac_nids = spec->private_dac_nids;
6911 spec->multiout.dac_nids[0] = 0x02;
6913 nid = cfg->line_out_pins[0];
6916 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6918 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6922 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6927 nid = cfg->speaker_pins[0];
6929 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6934 nid = cfg->hp_pins[0];
6936 err = alc260_add_playback_controls(spec, nid, "Headphone",
6944 /* create playback/capture controls for input pins */
6945 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6946 const struct auto_pin_cfg *cfg)
6948 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6951 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6952 hda_nid_t nid, int pin_type,
6955 alc_set_pin_output(codec, nid, pin_type);
6956 /* need the manual connection? */
6958 int idx = nid - 0x12;
6959 snd_hda_codec_write(codec, idx + 0x0b, 0,
6960 AC_VERB_SET_CONNECT_SEL, sel_idx);
6964 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6966 struct alc_spec *spec = codec->spec;
6969 nid = spec->autocfg.line_out_pins[0];
6971 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6972 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6975 nid = spec->autocfg.speaker_pins[0];
6977 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6979 nid = spec->autocfg.hp_pins[0];
6981 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6984 #define ALC260_PIN_CD_NID 0x16
6985 static void alc260_auto_init_analog_input(struct hda_codec *codec)
6987 struct alc_spec *spec = codec->spec;
6988 struct auto_pin_cfg *cfg = &spec->autocfg;
6991 for (i = 0; i < cfg->num_inputs; i++) {
6992 hda_nid_t nid = cfg->inputs[i].pin;
6994 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
6995 if (nid != ALC260_PIN_CD_NID &&
6996 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6997 snd_hda_codec_write(codec, nid, 0,
6998 AC_VERB_SET_AMP_GAIN_MUTE,
7004 #define alc260_auto_init_input_src alc880_auto_init_input_src
7007 * generic initialization of ADC, input mixers and output mixers
7009 static struct hda_verb alc260_volume_init_verbs[] = {
7011 * Unmute ADC0-1 and set the default input to mic-in
7013 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7014 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7015 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7016 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7018 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7020 * Note: PASD motherboards uses the Line In 2 as the input for
7021 * front panel mic (mic 2)
7023 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7024 /* mute analog inputs */
7025 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7026 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7028 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7029 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7032 * Set up output mixers (0x08 - 0x0a)
7034 /* set vol=0 to output mixers */
7035 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7036 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7037 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7038 /* set up input amps for analog loopback */
7039 /* Amp Indices: DAC = 0, mixer = 1 */
7040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7041 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7043 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7044 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7045 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7050 static int alc260_parse_auto_config(struct hda_codec *codec)
7052 struct alc_spec *spec = codec->spec;
7054 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7056 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7060 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7063 if (!spec->kctls.list)
7064 return 0; /* can't find valid BIOS pin config */
7065 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7069 spec->multiout.max_channels = 2;
7071 if (spec->autocfg.dig_outs)
7072 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7073 if (spec->kctls.list)
7074 add_mixer(spec, spec->kctls.list);
7076 add_verb(spec, alc260_volume_init_verbs);
7078 spec->num_mux_defs = 1;
7079 spec->input_mux = &spec->private_imux[0];
7081 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7086 /* additional initialization for auto-configuration model */
7087 static void alc260_auto_init(struct hda_codec *codec)
7089 struct alc_spec *spec = codec->spec;
7090 alc260_auto_init_multi_out(codec);
7091 alc260_auto_init_analog_input(codec);
7092 alc260_auto_init_input_src(codec);
7093 alc_auto_init_digital(codec);
7094 if (spec->unsol_event)
7095 alc_inithook(codec);
7098 #ifdef CONFIG_SND_HDA_POWER_SAVE
7099 static struct hda_amp_list alc260_loopbacks[] = {
7100 { 0x07, HDA_INPUT, 0 },
7101 { 0x07, HDA_INPUT, 1 },
7102 { 0x07, HDA_INPUT, 2 },
7103 { 0x07, HDA_INPUT, 3 },
7104 { 0x07, HDA_INPUT, 4 },
7116 static const struct alc_fixup alc260_fixups[] = {
7117 [PINFIX_HP_DC5750] = {
7118 .type = ALC_FIXUP_PINS,
7119 .v.pins = (const struct alc_pincfg[]) {
7120 { 0x11, 0x90130110 }, /* speaker */
7126 static struct snd_pci_quirk alc260_fixup_tbl[] = {
7127 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7132 * ALC260 configurations
7134 static const char * const alc260_models[ALC260_MODEL_LAST] = {
7135 [ALC260_BASIC] = "basic",
7137 [ALC260_HP_3013] = "hp-3013",
7138 [ALC260_HP_DC7600] = "hp-dc7600",
7139 [ALC260_FUJITSU_S702X] = "fujitsu",
7140 [ALC260_ACER] = "acer",
7141 [ALC260_WILL] = "will",
7142 [ALC260_REPLACER_672V] = "replacer",
7143 [ALC260_FAVORIT100] = "favorit100",
7144 #ifdef CONFIG_SND_DEBUG
7145 [ALC260_TEST] = "test",
7147 [ALC260_AUTO] = "auto",
7150 static struct snd_pci_quirk alc260_cfg_tbl[] = {
7151 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7152 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7153 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7154 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7155 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7156 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7157 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7158 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7159 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7160 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7161 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7162 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7163 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7164 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7165 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7166 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7167 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7168 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7169 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7170 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7174 static struct alc_config_preset alc260_presets[] = {
7176 .mixers = { alc260_base_output_mixer,
7177 alc260_input_mixer },
7178 .init_verbs = { alc260_init_verbs },
7179 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7180 .dac_nids = alc260_dac_nids,
7181 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7182 .adc_nids = alc260_dual_adc_nids,
7183 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7184 .channel_mode = alc260_modes,
7185 .input_mux = &alc260_capture_source,
7188 .mixers = { alc260_hp_output_mixer,
7189 alc260_input_mixer },
7190 .init_verbs = { alc260_init_verbs,
7191 alc260_hp_unsol_verbs },
7192 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7193 .dac_nids = alc260_dac_nids,
7194 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7195 .adc_nids = alc260_adc_nids_alt,
7196 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7197 .channel_mode = alc260_modes,
7198 .input_mux = &alc260_capture_source,
7199 .unsol_event = alc260_hp_unsol_event,
7200 .init_hook = alc260_hp_automute,
7202 [ALC260_HP_DC7600] = {
7203 .mixers = { alc260_hp_dc7600_mixer,
7204 alc260_input_mixer },
7205 .init_verbs = { alc260_init_verbs,
7206 alc260_hp_dc7600_verbs },
7207 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7208 .dac_nids = alc260_dac_nids,
7209 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7210 .adc_nids = alc260_adc_nids_alt,
7211 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7212 .channel_mode = alc260_modes,
7213 .input_mux = &alc260_capture_source,
7214 .unsol_event = alc260_hp_3012_unsol_event,
7215 .init_hook = alc260_hp_3012_automute,
7217 [ALC260_HP_3013] = {
7218 .mixers = { alc260_hp_3013_mixer,
7219 alc260_input_mixer },
7220 .init_verbs = { alc260_hp_3013_init_verbs,
7221 alc260_hp_3013_unsol_verbs },
7222 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7223 .dac_nids = alc260_dac_nids,
7224 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7225 .adc_nids = alc260_adc_nids_alt,
7226 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7227 .channel_mode = alc260_modes,
7228 .input_mux = &alc260_capture_source,
7229 .unsol_event = alc260_hp_3013_unsol_event,
7230 .init_hook = alc260_hp_3013_automute,
7232 [ALC260_FUJITSU_S702X] = {
7233 .mixers = { alc260_fujitsu_mixer },
7234 .init_verbs = { alc260_fujitsu_init_verbs },
7235 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7236 .dac_nids = alc260_dac_nids,
7237 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7238 .adc_nids = alc260_dual_adc_nids,
7239 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7240 .channel_mode = alc260_modes,
7241 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7242 .input_mux = alc260_fujitsu_capture_sources,
7245 .mixers = { alc260_acer_mixer },
7246 .init_verbs = { alc260_acer_init_verbs },
7247 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7248 .dac_nids = alc260_dac_nids,
7249 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7250 .adc_nids = alc260_dual_adc_nids,
7251 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7252 .channel_mode = alc260_modes,
7253 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7254 .input_mux = alc260_acer_capture_sources,
7256 [ALC260_FAVORIT100] = {
7257 .mixers = { alc260_favorit100_mixer },
7258 .init_verbs = { alc260_favorit100_init_verbs },
7259 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7260 .dac_nids = alc260_dac_nids,
7261 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7262 .adc_nids = alc260_dual_adc_nids,
7263 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7264 .channel_mode = alc260_modes,
7265 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7266 .input_mux = alc260_favorit100_capture_sources,
7269 .mixers = { alc260_will_mixer },
7270 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7271 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7272 .dac_nids = alc260_dac_nids,
7273 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7274 .adc_nids = alc260_adc_nids,
7275 .dig_out_nid = ALC260_DIGOUT_NID,
7276 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7277 .channel_mode = alc260_modes,
7278 .input_mux = &alc260_capture_source,
7280 [ALC260_REPLACER_672V] = {
7281 .mixers = { alc260_replacer_672v_mixer },
7282 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7283 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7284 .dac_nids = alc260_dac_nids,
7285 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7286 .adc_nids = alc260_adc_nids,
7287 .dig_out_nid = ALC260_DIGOUT_NID,
7288 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7289 .channel_mode = alc260_modes,
7290 .input_mux = &alc260_capture_source,
7291 .unsol_event = alc260_replacer_672v_unsol_event,
7292 .init_hook = alc260_replacer_672v_automute,
7294 #ifdef CONFIG_SND_DEBUG
7296 .mixers = { alc260_test_mixer },
7297 .init_verbs = { alc260_test_init_verbs },
7298 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7299 .dac_nids = alc260_test_dac_nids,
7300 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7301 .adc_nids = alc260_test_adc_nids,
7302 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7303 .channel_mode = alc260_modes,
7304 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7305 .input_mux = alc260_test_capture_sources,
7310 static int patch_alc260(struct hda_codec *codec)
7312 struct alc_spec *spec;
7313 int err, board_config;
7315 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7321 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7324 if (board_config < 0) {
7325 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7327 board_config = ALC260_AUTO;
7330 if (board_config == ALC260_AUTO) {
7331 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7332 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7335 if (board_config == ALC260_AUTO) {
7336 /* automatic parse from the BIOS config */
7337 err = alc260_parse_auto_config(codec);
7343 "hda_codec: Cannot set up configuration "
7344 "from BIOS. Using base mode...\n");
7345 board_config = ALC260_BASIC;
7349 err = snd_hda_attach_beep_device(codec, 0x1);
7355 if (board_config != ALC260_AUTO)
7356 setup_preset(codec, &alc260_presets[board_config]);
7358 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7359 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7360 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7362 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7363 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7365 if (!spec->adc_nids && spec->input_mux) {
7366 /* check whether NID 0x04 is valid */
7367 unsigned int wcap = get_wcaps(codec, 0x04);
7368 wcap = get_wcaps_type(wcap);
7370 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7371 spec->adc_nids = alc260_adc_nids_alt;
7372 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7374 spec->adc_nids = alc260_adc_nids;
7375 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7378 set_capture_mixer(codec);
7379 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7381 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7383 spec->vmaster_nid = 0x08;
7385 codec->patch_ops = alc_patch_ops;
7386 if (board_config == ALC260_AUTO)
7387 spec->init_hook = alc260_auto_init;
7388 spec->shutup = alc_eapd_shutup;
7389 #ifdef CONFIG_SND_HDA_POWER_SAVE
7390 if (!spec->loopback.amplist)
7391 spec->loopback.amplist = alc260_loopbacks;
7399 * ALC882/883/885/888/889 support
7401 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7402 * configuration. Each pin widget can choose any input DACs and a mixer.
7403 * Each ADC is connected from a mixer of all inputs. This makes possible
7404 * 6-channel independent captures.
7406 * In addition, an independent DAC for the multi-playback (not used in this
7409 #define ALC882_DIGOUT_NID 0x06
7410 #define ALC882_DIGIN_NID 0x0a
7411 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7412 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7413 #define ALC1200_DIGOUT_NID 0x10
7416 static struct hda_channel_mode alc882_ch_modes[1] = {
7421 static hda_nid_t alc882_dac_nids[4] = {
7422 /* front, rear, clfe, rear_surr */
7423 0x02, 0x03, 0x04, 0x05
7425 #define alc883_dac_nids alc882_dac_nids
7428 #define alc882_adc_nids alc880_adc_nids
7429 #define alc882_adc_nids_alt alc880_adc_nids_alt
7430 #define alc883_adc_nids alc882_adc_nids_alt
7431 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7432 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7433 #define alc889_adc_nids alc880_adc_nids
7435 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7436 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7437 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7438 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7439 #define alc889_capsrc_nids alc882_capsrc_nids
7442 /* FIXME: should be a matrix-type input source selection */
7444 static struct hda_input_mux alc882_capture_source = {
7448 { "Front Mic", 0x1 },
7454 #define alc883_capture_source alc882_capture_source
7456 static struct hda_input_mux alc889_capture_source = {
7459 { "Front Mic", 0x0 },
7465 static struct hda_input_mux mb5_capture_source = {
7474 static struct hda_input_mux macmini3_capture_source = {
7482 static struct hda_input_mux alc883_3stack_6ch_intel = {
7486 { "Front Mic", 0x0 },
7492 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7500 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7504 { "Internal Mic", 0x1 },
7510 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7514 { "Internal Mic", 0x1 },
7518 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7522 { "Front Mic", 0x1 },
7527 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7535 static struct hda_input_mux alc889A_mb31_capture_source = {
7539 /* Front Mic (0x01) unused */
7541 /* Line 2 (0x03) unused */
7542 /* CD (0x04) unused? */
7546 static struct hda_input_mux alc889A_imac91_capture_source = {
7550 { "Line", 0x2 }, /* Not sure! */
7557 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7564 static struct hda_verb alc882_3ST_ch2_init[] = {
7565 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7566 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7567 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7568 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7575 static struct hda_verb alc882_3ST_ch4_init[] = {
7576 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7577 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7578 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7579 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7580 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7587 static struct hda_verb alc882_3ST_ch6_init[] = {
7588 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7589 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7590 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7591 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7592 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7593 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7597 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7598 { 2, alc882_3ST_ch2_init },
7599 { 4, alc882_3ST_ch4_init },
7600 { 6, alc882_3ST_ch6_init },
7603 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7608 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7609 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7610 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7611 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7612 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7613 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7620 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7621 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7622 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7623 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7624 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7625 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7626 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7633 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7634 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7635 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7636 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7637 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7638 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7639 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7640 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7644 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7645 { 2, alc883_3ST_ch2_clevo_init },
7646 { 4, alc883_3ST_ch4_clevo_init },
7647 { 6, alc883_3ST_ch6_clevo_init },
7654 static struct hda_verb alc882_sixstack_ch6_init[] = {
7655 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7656 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7657 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7658 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7665 static struct hda_verb alc882_sixstack_ch8_init[] = {
7666 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7667 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7668 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7669 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7673 static struct hda_channel_mode alc882_sixstack_modes[2] = {
7674 { 6, alc882_sixstack_ch6_init },
7675 { 8, alc882_sixstack_ch8_init },
7679 /* Macbook Air 2,1 */
7681 static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7686 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7692 static struct hda_verb alc885_mbp_ch2_init[] = {
7693 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7694 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7695 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7702 static struct hda_verb alc885_mbp_ch4_init[] = {
7703 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7704 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7705 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7706 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7707 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7711 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7712 { 2, alc885_mbp_ch2_init },
7713 { 4, alc885_mbp_ch4_init },
7718 * Speakers/Woofer/HP = Front
7721 static struct hda_verb alc885_mb5_ch2_init[] = {
7722 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7723 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7729 * Speakers/HP = Front
7733 static struct hda_verb alc885_mb5_ch6_init[] = {
7734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7736 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7740 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7741 { 2, alc885_mb5_ch2_init },
7742 { 6, alc885_mb5_ch6_init },
7745 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7750 static struct hda_verb alc883_4ST_ch2_init[] = {
7751 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7753 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7754 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7755 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7756 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7763 static struct hda_verb alc883_4ST_ch4_init[] = {
7764 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7765 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7766 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7767 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7768 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7769 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7770 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7777 static struct hda_verb alc883_4ST_ch6_init[] = {
7778 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7780 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7781 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7782 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7783 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7784 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7785 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7792 static struct hda_verb alc883_4ST_ch8_init[] = {
7793 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7794 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7795 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7796 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7797 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7798 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7799 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7800 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7801 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7805 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7806 { 2, alc883_4ST_ch2_init },
7807 { 4, alc883_4ST_ch4_init },
7808 { 6, alc883_4ST_ch6_init },
7809 { 8, alc883_4ST_ch8_init },
7816 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7817 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7818 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7819 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7820 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7827 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7828 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7829 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7830 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7831 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7832 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7839 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7840 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7841 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7842 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7843 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7844 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7845 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7849 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7850 { 2, alc883_3ST_ch2_intel_init },
7851 { 4, alc883_3ST_ch4_intel_init },
7852 { 6, alc883_3ST_ch6_intel_init },
7858 static struct hda_verb alc889_ch2_intel_init[] = {
7859 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7860 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7861 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7862 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7871 static struct hda_verb alc889_ch6_intel_init[] = {
7872 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7873 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7874 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7875 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7876 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7877 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7884 static struct hda_verb alc889_ch8_intel_init[] = {
7885 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7886 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7887 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7888 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7889 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7890 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7891 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7895 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7896 { 2, alc889_ch2_intel_init },
7897 { 6, alc889_ch6_intel_init },
7898 { 8, alc889_ch8_intel_init },
7904 static struct hda_verb alc883_sixstack_ch6_init[] = {
7905 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7906 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7915 static struct hda_verb alc883_sixstack_ch8_init[] = {
7916 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7917 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7918 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7919 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7923 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7924 { 6, alc883_sixstack_ch6_init },
7925 { 8, alc883_sixstack_ch8_init },
7929 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7930 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7932 static struct snd_kcontrol_new alc882_base_mixer[] = {
7933 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7934 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7935 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7936 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7937 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7938 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7939 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7940 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7941 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7942 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7944 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7945 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7957 /* Macbook Air 2,1 same control for HP and internal Speaker */
7959 static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7960 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7961 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7966 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7967 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7968 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7969 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7970 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7971 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7972 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7973 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7975 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7976 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
7981 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7983 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7985 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7986 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7987 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7988 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7989 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7991 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7993 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7994 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7995 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
7999 static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8000 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8001 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8002 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8003 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8004 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8005 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8006 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8007 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8009 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8010 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8014 static struct snd_kcontrol_new alc885_imac91_mixer[] = {
8015 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8016 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8021 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8022 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8023 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8024 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8025 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8026 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8027 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8028 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8029 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8034 static struct snd_kcontrol_new alc882_targa_mixer[] = {
8035 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8036 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8037 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8038 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8039 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8040 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8041 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8042 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8043 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8044 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8045 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8046 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8047 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8051 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8052 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8054 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8055 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8056 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8057 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8058 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8059 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8060 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8061 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8062 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8063 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8064 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8067 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8071 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8072 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8073 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8074 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8075 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8076 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8077 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8078 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8079 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8080 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8081 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8085 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8088 .name = "Channel Mode",
8089 .info = alc_ch_mode_info,
8090 .get = alc_ch_mode_get,
8091 .put = alc_ch_mode_put,
8096 static struct hda_verb alc882_base_init_verbs[] = {
8097 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8101 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8102 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8104 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8105 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8107 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8108 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8110 /* Front Pin: output 0 (0x0c) */
8111 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8112 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8113 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8114 /* Rear Pin: output 1 (0x0d) */
8115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8116 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8117 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8118 /* CLFE Pin: output 2 (0x0e) */
8119 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8120 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8121 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8122 /* Side Pin: output 3 (0x0f) */
8123 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8124 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8125 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8126 /* Mic (rear) pin: input vref at 80% */
8127 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8129 /* Front Mic pin: input vref at 80% */
8130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8131 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8132 /* Line In pin: input */
8133 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8134 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8135 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8136 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8137 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8138 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8139 /* CD pin widget for input */
8140 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8142 /* FIXME: use matrix-type input source selection */
8143 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8148 /* ADC2: mute amp left and right */
8149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8150 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8151 /* ADC3: mute amp left and right */
8152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8153 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8158 static struct hda_verb alc882_adc1_init_verbs[] = {
8159 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8160 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8161 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8162 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8163 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8164 /* ADC1: mute amp left and right */
8165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8166 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8170 static struct hda_verb alc882_eapd_verbs[] = {
8171 /* change to EAPD mode */
8172 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8173 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8177 static struct hda_verb alc889_eapd_verbs[] = {
8178 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8179 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8183 static struct hda_verb alc_hp15_unsol_verbs[] = {
8184 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8185 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8189 static struct hda_verb alc885_init_verbs[] = {
8190 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8191 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8192 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8194 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8195 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8197 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8201 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8203 /* Front HP Pin: output 0 (0x0c) */
8204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8206 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8207 /* Front Pin: output 0 (0x0c) */
8208 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8210 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8211 /* Rear Pin: output 1 (0x0d) */
8212 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8213 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8214 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8215 /* CLFE Pin: output 2 (0x0e) */
8216 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8217 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8218 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8219 /* Side Pin: output 3 (0x0f) */
8220 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8221 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8222 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8223 /* Mic (rear) pin: input vref at 80% */
8224 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8225 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8226 /* Front Mic pin: input vref at 80% */
8227 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8228 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8229 /* Line In pin: input */
8230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8231 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8233 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8235 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8237 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8240 /* ADC2: mute amp left and right */
8241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8242 /* ADC3: mute amp left and right */
8243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8248 static struct hda_verb alc885_init_input_verbs[] = {
8249 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8251 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8256 /* Unmute Selector 24h and set the default input to front mic */
8257 static struct hda_verb alc889_init_input_verbs[] = {
8258 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8259 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8264 #define alc883_init_verbs alc882_base_init_verbs
8267 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8268 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8269 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8270 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8271 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8272 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8273 /* FIXME: this looks suspicious...
8274 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8275 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8280 static struct hda_verb alc882_macpro_init_verbs[] = {
8281 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8282 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8284 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8285 /* Front Pin: output 0 (0x0c) */
8286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8287 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8288 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8289 /* Front Mic pin: input vref at 80% */
8290 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8291 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8292 /* Speaker: output */
8293 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8294 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8295 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8296 /* Headphone output (output 0 - 0x0c) */
8297 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8298 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8299 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8301 /* FIXME: use matrix-type input source selection */
8302 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8303 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8305 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8311 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8318 /* ADC1: mute amp left and right */
8319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8320 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8321 /* ADC2: mute amp left and right */
8322 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8323 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8324 /* ADC3: mute amp left and right */
8325 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8332 static struct hda_verb alc885_mb5_init_verbs[] = {
8334 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8335 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8336 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8337 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8340 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8341 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8342 /* Surround mixer */
8343 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8344 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8345 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8349 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8351 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8353 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8354 /* Front Pin (0x0c) */
8355 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8356 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8357 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8358 /* LFE Pin (0x0e) */
8359 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8360 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8361 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8365 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8366 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8367 /* Front Mic pin: input vref at 80% */
8368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8369 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8374 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8381 static struct hda_verb alc885_macmini3_init_verbs[] = {
8383 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8384 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8386 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8388 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8389 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8390 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8391 /* Surround mixer */
8392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8398 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8400 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8401 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8403 /* Front Pin (0x0c) */
8404 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8405 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8406 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8407 /* LFE Pin (0x0e) */
8408 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8409 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8413 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8414 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8415 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8417 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8418 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8420 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8421 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8422 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8423 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8428 static struct hda_verb alc885_mba21_init_verbs[] = {
8429 /*Internal and HP Speaker Mixer*/
8430 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8431 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8433 /*Internal Speaker Pin (0x0c)*/
8434 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8435 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8436 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8437 /* HP Pin: output 0 (0x0e) */
8438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8440 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8441 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8442 /* Line in (is hp when jack connected)*/
8443 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8450 /* Macbook Pro rev3 */
8451 static struct hda_verb alc885_mbp3_init_verbs[] = {
8452 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8453 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8455 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8457 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8458 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8462 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8463 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8464 /* Front Pin: output 0 (0x0c) */
8465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8466 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8467 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8468 /* HP Pin: output 0 (0x0e) */
8469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8471 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8472 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8473 /* Mic (rear) pin: input vref at 80% */
8474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8475 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8476 /* Front Mic pin: input vref at 80% */
8477 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8478 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8479 /* Line In pin: use output 1 when in LineOut mode */
8480 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8481 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8482 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8484 /* FIXME: use matrix-type input source selection */
8485 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8486 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8487 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8488 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8489 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8490 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8493 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8494 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8495 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8500 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8501 /* ADC1: mute amp left and right */
8502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8503 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8504 /* ADC2: mute amp left and right */
8505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8506 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8507 /* ADC3: mute amp left and right */
8508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8509 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8515 static struct hda_verb alc885_imac91_init_verbs[] = {
8516 /* Internal Speaker Pin (0x0c) */
8517 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8518 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8519 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8520 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8521 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8522 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8527 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8530 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8531 /* Front Mic pin: input vref at 80% */
8532 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8533 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8538 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8542 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8544 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8546 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8547 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8548 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8549 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8550 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8551 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8552 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8553 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8554 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8555 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8556 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8557 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8558 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8559 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8560 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8562 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8563 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8564 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8565 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8569 /* iMac 24 mixer. */
8570 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8571 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8572 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8576 /* iMac 24 init verbs. */
8577 static struct hda_verb alc885_imac24_init_verbs[] = {
8578 /* Internal speakers: output 0 (0x0c) */
8579 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8581 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8582 /* Internal speakers: output 0 (0x0c) */
8583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8585 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8586 /* Headphone: output 0 (0x0c) */
8587 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8589 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8590 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8591 /* Front Mic: input vref at 80% */
8592 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8593 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8597 /* Toggle speaker-output according to the hp-jack state */
8598 static void alc885_imac24_setup(struct hda_codec *codec)
8600 struct alc_spec *spec = codec->spec;
8602 spec->autocfg.hp_pins[0] = 0x14;
8603 spec->autocfg.speaker_pins[0] = 0x18;
8604 spec->autocfg.speaker_pins[1] = 0x1a;
8607 #define alc885_mb5_setup alc885_imac24_setup
8608 #define alc885_macmini3_setup alc885_imac24_setup
8610 /* Macbook Air 2,1 */
8611 static void alc885_mba21_setup(struct hda_codec *codec)
8613 struct alc_spec *spec = codec->spec;
8615 spec->autocfg.hp_pins[0] = 0x14;
8616 spec->autocfg.speaker_pins[0] = 0x18;
8621 static void alc885_mbp3_setup(struct hda_codec *codec)
8623 struct alc_spec *spec = codec->spec;
8625 spec->autocfg.hp_pins[0] = 0x15;
8626 spec->autocfg.speaker_pins[0] = 0x14;
8629 static void alc885_imac91_setup(struct hda_codec *codec)
8631 struct alc_spec *spec = codec->spec;
8633 spec->autocfg.hp_pins[0] = 0x14;
8634 spec->autocfg.speaker_pins[0] = 0x18;
8635 spec->autocfg.speaker_pins[1] = 0x1a;
8638 static struct hda_verb alc882_targa_verbs[] = {
8639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8642 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8643 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8645 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8646 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8647 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8649 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8653 /* toggle speaker-output according to the hp-jack state */
8654 static void alc882_targa_automute(struct hda_codec *codec)
8656 struct alc_spec *spec = codec->spec;
8657 alc_automute_amp(codec);
8658 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8659 spec->jack_present ? 1 : 3);
8662 static void alc882_targa_setup(struct hda_codec *codec)
8664 struct alc_spec *spec = codec->spec;
8666 spec->autocfg.hp_pins[0] = 0x14;
8667 spec->autocfg.speaker_pins[0] = 0x1b;
8670 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8672 if ((res >> 26) == ALC880_HP_EVENT)
8673 alc882_targa_automute(codec);
8676 static struct hda_verb alc882_asus_a7j_verbs[] = {
8677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8681 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8684 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8685 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8686 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8688 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8689 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8690 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8694 static struct hda_verb alc882_asus_a7m_verbs[] = {
8695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8699 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8700 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8702 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8703 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8704 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8706 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8707 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8708 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8712 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8714 unsigned int gpiostate, gpiomask, gpiodir;
8716 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8717 AC_VERB_GET_GPIO_DATA, 0);
8720 gpiostate |= (1 << pin);
8722 gpiostate &= ~(1 << pin);
8724 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8725 AC_VERB_GET_GPIO_MASK, 0);
8726 gpiomask |= (1 << pin);
8728 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8729 AC_VERB_GET_GPIO_DIRECTION, 0);
8730 gpiodir |= (1 << pin);
8733 snd_hda_codec_write(codec, codec->afg, 0,
8734 AC_VERB_SET_GPIO_MASK, gpiomask);
8735 snd_hda_codec_write(codec, codec->afg, 0,
8736 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8740 snd_hda_codec_write(codec, codec->afg, 0,
8741 AC_VERB_SET_GPIO_DATA, gpiostate);
8744 /* set up GPIO at initialization */
8745 static void alc885_macpro_init_hook(struct hda_codec *codec)
8747 alc882_gpio_mute(codec, 0, 0);
8748 alc882_gpio_mute(codec, 1, 0);
8751 /* set up GPIO and update auto-muting at initialization */
8752 static void alc885_imac24_init_hook(struct hda_codec *codec)
8754 alc885_macpro_init_hook(codec);
8755 alc_automute_amp(codec);
8759 * generic initialization of ADC, input mixers and output mixers
8761 static struct hda_verb alc883_auto_init_verbs[] = {
8763 * Unmute ADC0-2 and set the default input to mic-in
8765 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8766 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8767 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8768 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8771 * Set up output mixers (0x0c - 0x0f)
8773 /* set vol=0 to output mixers */
8774 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8775 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8776 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8777 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8778 /* set up input amps for analog loopback */
8779 /* Amp Indices: DAC = 0, mixer = 1 */
8780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8782 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8783 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8785 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8786 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8787 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8788 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8789 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8791 /* FIXME: use matrix-type input source selection */
8792 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8794 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8796 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8800 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8801 static struct hda_verb alc889A_mb31_ch2_init[] = {
8802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8804 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8805 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8809 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8810 static struct hda_verb alc889A_mb31_ch4_init[] = {
8811 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8812 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8813 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8814 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8818 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8819 static struct hda_verb alc889A_mb31_ch5_init[] = {
8820 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8821 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8822 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8823 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8827 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8828 static struct hda_verb alc889A_mb31_ch6_init[] = {
8829 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8831 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8832 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8836 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8837 { 2, alc889A_mb31_ch2_init },
8838 { 4, alc889A_mb31_ch4_init },
8839 { 5, alc889A_mb31_ch5_init },
8840 { 6, alc889A_mb31_ch6_init },
8843 static struct hda_verb alc883_medion_eapd_verbs[] = {
8844 /* eanable EAPD on medion laptop */
8845 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8846 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8850 #define alc883_base_mixer alc882_base_mixer
8852 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8853 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8854 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8855 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8856 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8857 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8858 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8861 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8863 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8864 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8865 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8869 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8870 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8871 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8872 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8873 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8875 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8876 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8877 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8878 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8879 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8883 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8885 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8886 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8887 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8888 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8889 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8891 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8892 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8893 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8897 static struct snd_kcontrol_new alc883_3ST_2ch_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_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8901 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8902 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8903 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8904 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
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 struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8917 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8918 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8919 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8920 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8921 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8922 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8923 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8924 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8925 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8926 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8927 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8929 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8930 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8931 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8932 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8933 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8937 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8938 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8939 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8940 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8941 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8942 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8947 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8948 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8949 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8950 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8951 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8953 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8954 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8955 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8956 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8957 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8961 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8962 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8963 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8964 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8965 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8966 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8968 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8969 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8970 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8971 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8972 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8973 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
8978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8980 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8981 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8985 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8988 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8989 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8990 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8992 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8993 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8994 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8995 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8996 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8998 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9002 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9003 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9004 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9008 static struct snd_kcontrol_new alc883_targa_mixer[] = {
9009 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9010 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9012 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9013 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9014 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9015 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9016 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9017 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9018 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9019 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9020 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9021 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9022 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9024 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9029 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9030 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9031 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9032 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9033 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9034 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9035 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9037 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9039 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9040 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9041 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9045 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9046 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9047 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9048 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9049 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9050 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9054 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9055 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9056 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9057 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9058 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9061 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9066 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9067 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9068 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9069 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9070 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9071 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9072 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9073 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9074 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9075 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9079 static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9080 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9081 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9082 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9084 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9085 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9089 static struct hda_verb alc883_medion_wim2160_verbs[] = {
9090 /* Unmute front mixer */
9091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9094 /* Set speaker pin to front mixer */
9095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9097 /* Init headphone pin */
9098 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9099 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9100 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9101 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9106 /* toggle speaker-output according to the hp-jack state */
9107 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9109 struct alc_spec *spec = codec->spec;
9111 spec->autocfg.hp_pins[0] = 0x1a;
9112 spec->autocfg.speaker_pins[0] = 0x15;
9115 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9116 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9117 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9118 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9119 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9120 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9122 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9127 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9128 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9129 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9130 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9131 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9132 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9133 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9135 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9136 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9140 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9141 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9142 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9143 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9144 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9145 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9146 0x0d, 1, 0x0, HDA_OUTPUT),
9147 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9148 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9149 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9150 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9151 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9154 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9155 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9157 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9159 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9160 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9161 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9165 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9167 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9168 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9169 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9170 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9171 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9173 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9174 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9175 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9176 /* Output switches */
9177 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9178 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9179 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9181 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9182 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9185 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9191 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9196 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9201 static struct hda_bind_ctls alc883_bind_cap_vol = {
9202 .ops = &snd_hda_bind_vol,
9204 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9205 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9210 static struct hda_bind_ctls alc883_bind_cap_switch = {
9211 .ops = &snd_hda_bind_sw,
9213 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9214 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9219 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9222 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9223 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9224 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9226 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9227 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9231 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9232 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9233 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9235 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9236 /* .name = "Capture Source", */
9237 .name = "Input Source",
9239 .info = alc_mux_enum_info,
9240 .get = alc_mux_enum_get,
9241 .put = alc_mux_enum_put,
9246 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9248 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9249 .name = "Channel Mode",
9250 .info = alc_ch_mode_info,
9251 .get = alc_ch_mode_get,
9252 .put = alc_ch_mode_put,
9257 /* toggle speaker-output according to the hp-jack state */
9258 static void alc883_mitac_setup(struct hda_codec *codec)
9260 struct alc_spec *spec = codec->spec;
9262 spec->autocfg.hp_pins[0] = 0x15;
9263 spec->autocfg.speaker_pins[0] = 0x14;
9264 spec->autocfg.speaker_pins[1] = 0x17;
9267 static struct hda_verb alc883_mitac_verbs[] = {
9269 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9272 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9273 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9275 /* enable unsolicited event */
9276 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9277 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9282 static struct hda_verb alc883_clevo_m540r_verbs[] = {
9284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9285 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9287 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9289 /* enable unsolicited event */
9291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9292 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9298 static struct hda_verb alc883_clevo_m720_verbs[] = {
9300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9303 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9304 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9306 /* enable unsolicited event */
9307 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9308 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9313 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9315 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9318 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9319 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9321 /* enable unsolicited event */
9322 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9327 static struct hda_verb alc883_targa_verbs[] = {
9328 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9332 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9334 /* Connect Line-Out side jack (SPDIF) to Side */
9335 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9337 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9338 /* Connect Mic jack to CLFE */
9339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9341 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9342 /* Connect Line-in jack to Surround */
9343 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9345 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9346 /* Connect HP out jack to Front */
9347 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9348 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9349 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9351 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9356 static struct hda_verb alc883_lenovo_101e_verbs[] = {
9357 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9358 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9359 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9363 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9364 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9365 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9366 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9367 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9371 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9374 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9375 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9376 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9380 static struct hda_verb alc883_haier_w66_verbs[] = {
9381 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9386 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9388 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9389 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9393 static struct hda_verb alc888_lenovo_sky_verbs[] = {
9394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9395 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9398 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9399 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9400 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9401 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9405 static struct hda_verb alc888_6st_dell_verbs[] = {
9406 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9410 static struct hda_verb alc883_vaiott_verbs[] = {
9412 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9415 /* enable unsolicited event */
9416 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9421 static void alc888_3st_hp_setup(struct hda_codec *codec)
9423 struct alc_spec *spec = codec->spec;
9425 spec->autocfg.hp_pins[0] = 0x1b;
9426 spec->autocfg.speaker_pins[0] = 0x14;
9427 spec->autocfg.speaker_pins[1] = 0x16;
9428 spec->autocfg.speaker_pins[2] = 0x18;
9431 static struct hda_verb alc888_3st_hp_verbs[] = {
9432 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9433 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9434 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9435 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9442 static struct hda_verb alc888_3st_hp_2ch_init[] = {
9443 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9444 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9445 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9446 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9453 static struct hda_verb alc888_3st_hp_4ch_init[] = {
9454 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9455 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9456 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9457 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9458 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9465 static struct hda_verb alc888_3st_hp_6ch_init[] = {
9466 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9467 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9468 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9469 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9470 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9471 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9475 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
9476 { 2, alc888_3st_hp_2ch_init },
9477 { 4, alc888_3st_hp_4ch_init },
9478 { 6, alc888_3st_hp_6ch_init },
9481 /* toggle front-jack and RCA according to the hp-jack state */
9482 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9484 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
9486 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9487 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9488 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9489 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9492 /* toggle RCA according to the front-jack state */
9493 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9495 unsigned int present = snd_hda_jack_detect(codec, 0x14);
9497 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9498 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9501 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9504 if ((res >> 26) == ALC880_HP_EVENT)
9505 alc888_lenovo_ms7195_front_automute(codec);
9506 if ((res >> 26) == ALC880_FRONT_EVENT)
9507 alc888_lenovo_ms7195_rca_automute(codec);
9510 /* toggle speaker-output according to the hp-jack state */
9511 static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9513 struct alc_spec *spec = codec->spec;
9515 spec->autocfg.hp_pins[0] = 0x14;
9516 spec->autocfg.speaker_pins[0] = 0x15;
9519 /* toggle speaker-output according to the hp-jack state */
9520 #define alc883_targa_init_hook alc882_targa_init_hook
9521 #define alc883_targa_unsol_event alc882_targa_unsol_event
9523 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9525 struct alc_spec *spec = codec->spec;
9527 spec->autocfg.hp_pins[0] = 0x15;
9528 spec->autocfg.speaker_pins[0] = 0x14;
9531 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9533 alc_automute_amp(codec);
9534 alc88x_simple_mic_automute(codec);
9537 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9540 switch (res >> 26) {
9541 case ALC880_MIC_EVENT:
9542 alc88x_simple_mic_automute(codec);
9545 alc_automute_amp_unsol_event(codec, res);
9550 /* toggle speaker-output according to the hp-jack state */
9551 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9553 struct alc_spec *spec = codec->spec;
9555 spec->autocfg.hp_pins[0] = 0x14;
9556 spec->autocfg.speaker_pins[0] = 0x15;
9559 static void alc883_haier_w66_setup(struct hda_codec *codec)
9561 struct alc_spec *spec = codec->spec;
9563 spec->autocfg.hp_pins[0] = 0x1b;
9564 spec->autocfg.speaker_pins[0] = 0x14;
9567 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9569 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
9571 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9572 HDA_AMP_MUTE, bits);
9575 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9577 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9579 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9580 HDA_AMP_MUTE, bits);
9581 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9582 HDA_AMP_MUTE, bits);
9585 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9588 if ((res >> 26) == ALC880_HP_EVENT)
9589 alc883_lenovo_101e_all_automute(codec);
9590 if ((res >> 26) == ALC880_FRONT_EVENT)
9591 alc883_lenovo_101e_ispeaker_automute(codec);
9594 /* toggle speaker-output according to the hp-jack state */
9595 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9597 struct alc_spec *spec = codec->spec;
9599 spec->autocfg.hp_pins[0] = 0x14;
9600 spec->autocfg.speaker_pins[0] = 0x15;
9601 spec->autocfg.speaker_pins[1] = 0x16;
9604 static struct hda_verb alc883_acer_eapd_verbs[] = {
9605 /* HP Pin: output 0 (0x0c) */
9606 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9607 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9608 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9609 /* Front Pin: output 0 (0x0c) */
9610 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9612 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9613 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9614 /* eanable EAPD on medion laptop */
9615 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9616 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9617 /* enable unsolicited event */
9618 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9622 static void alc888_6st_dell_setup(struct hda_codec *codec)
9624 struct alc_spec *spec = codec->spec;
9626 spec->autocfg.hp_pins[0] = 0x1b;
9627 spec->autocfg.speaker_pins[0] = 0x14;
9628 spec->autocfg.speaker_pins[1] = 0x15;
9629 spec->autocfg.speaker_pins[2] = 0x16;
9630 spec->autocfg.speaker_pins[3] = 0x17;
9633 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9635 struct alc_spec *spec = codec->spec;
9637 spec->autocfg.hp_pins[0] = 0x1b;
9638 spec->autocfg.speaker_pins[0] = 0x14;
9639 spec->autocfg.speaker_pins[1] = 0x15;
9640 spec->autocfg.speaker_pins[2] = 0x16;
9641 spec->autocfg.speaker_pins[3] = 0x17;
9642 spec->autocfg.speaker_pins[4] = 0x1a;
9645 static void alc883_vaiott_setup(struct hda_codec *codec)
9647 struct alc_spec *spec = codec->spec;
9649 spec->autocfg.hp_pins[0] = 0x15;
9650 spec->autocfg.speaker_pins[0] = 0x14;
9651 spec->autocfg.speaker_pins[1] = 0x17;
9654 static struct hda_verb alc888_asus_m90v_verbs[] = {
9655 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9658 /* enable unsolicited event */
9659 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9660 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9664 static void alc883_mode2_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->ext_mic.pin = 0x18;
9673 spec->int_mic.pin = 0x19;
9674 spec->ext_mic.mux_idx = 0;
9675 spec->int_mic.mux_idx = 1;
9679 static struct hda_verb alc888_asus_eee1601_verbs[] = {
9680 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9681 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9682 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9683 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9684 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9685 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9686 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9687 /* enable unsolicited event */
9688 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9692 static void alc883_eee1601_inithook(struct hda_codec *codec)
9694 struct alc_spec *spec = codec->spec;
9696 spec->autocfg.hp_pins[0] = 0x14;
9697 spec->autocfg.speaker_pins[0] = 0x1b;
9698 alc_automute_pin(codec);
9701 static struct hda_verb alc889A_mb31_verbs[] = {
9702 /* Init rear pin (used as headphone output) */
9703 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9704 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9705 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9706 /* Init line pin (used as output in 4ch and 6ch mode) */
9707 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9708 /* Init line 2 pin (used as headphone out by default) */
9709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9714 /* Mute speakers according to the headphone jack state */
9715 static void alc889A_mb31_automute(struct hda_codec *codec)
9717 unsigned int present;
9719 /* Mute only in 2ch or 4ch mode */
9720 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9722 present = snd_hda_jack_detect(codec, 0x15);
9723 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9724 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9725 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9726 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9730 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9732 if ((res >> 26) == ALC880_HP_EVENT)
9733 alc889A_mb31_automute(codec);
9737 #ifdef CONFIG_SND_HDA_POWER_SAVE
9738 #define alc882_loopbacks alc880_loopbacks
9741 /* pcm configuration: identical with ALC880 */
9742 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9743 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9744 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9745 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9747 static hda_nid_t alc883_slave_dig_outs[] = {
9748 ALC1200_DIGOUT_NID, 0,
9751 static hda_nid_t alc1200_slave_dig_outs[] = {
9752 ALC883_DIGOUT_NID, 0,
9756 * configuration and preset
9758 static const char * const alc882_models[ALC882_MODEL_LAST] = {
9759 [ALC882_3ST_DIG] = "3stack-dig",
9760 [ALC882_6ST_DIG] = "6stack-dig",
9761 [ALC882_ARIMA] = "arima",
9762 [ALC882_W2JC] = "w2jc",
9763 [ALC882_TARGA] = "targa",
9764 [ALC882_ASUS_A7J] = "asus-a7j",
9765 [ALC882_ASUS_A7M] = "asus-a7m",
9766 [ALC885_MACPRO] = "macpro",
9767 [ALC885_MB5] = "mb5",
9768 [ALC885_MACMINI3] = "macmini3",
9769 [ALC885_MBA21] = "mba21",
9770 [ALC885_MBP3] = "mbp3",
9771 [ALC885_IMAC24] = "imac24",
9772 [ALC885_IMAC91] = "imac91",
9773 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9774 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9775 [ALC883_3ST_6ch] = "3stack-6ch",
9776 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9777 [ALC883_TARGA_DIG] = "targa-dig",
9778 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9779 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9780 [ALC883_ACER] = "acer",
9781 [ALC883_ACER_ASPIRE] = "acer-aspire",
9782 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9783 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9784 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9785 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9786 [ALC883_MEDION] = "medion",
9787 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9788 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9789 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9790 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9791 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9792 [ALC888_LENOVO_SKY] = "lenovo-sky",
9793 [ALC883_HAIER_W66] = "haier-w66",
9794 [ALC888_3ST_HP] = "3stack-hp",
9795 [ALC888_6ST_DELL] = "6stack-dell",
9796 [ALC883_MITAC] = "mitac",
9797 [ALC883_CLEVO_M540R] = "clevo-m540r",
9798 [ALC883_CLEVO_M720] = "clevo-m720",
9799 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9800 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9801 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9802 [ALC889A_INTEL] = "intel-alc889a",
9803 [ALC889_INTEL] = "intel-x58",
9804 [ALC1200_ASUS_P5Q] = "asus-p5q",
9805 [ALC889A_MB31] = "mb31",
9806 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9807 [ALC882_AUTO] = "auto",
9810 static struct snd_pci_quirk alc882_cfg_tbl[] = {
9811 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9813 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9814 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9815 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9816 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9817 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9818 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9819 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9820 ALC888_ACER_ASPIRE_4930G),
9821 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9822 ALC888_ACER_ASPIRE_4930G),
9823 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9824 ALC888_ACER_ASPIRE_8930G),
9825 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9826 ALC888_ACER_ASPIRE_8930G),
9827 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9828 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9829 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9830 ALC888_ACER_ASPIRE_6530G),
9831 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9832 ALC888_ACER_ASPIRE_6530G),
9833 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9834 ALC888_ACER_ASPIRE_7730G),
9835 /* default Acer -- disabled as it causes more problems.
9836 * model=auto should work fine now
9838 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9840 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9842 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9843 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9844 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9845 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9846 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9847 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9849 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9850 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9851 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9852 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9853 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9854 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9855 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9856 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9857 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9858 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9859 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9861 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9862 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9863 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9864 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9865 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9866 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9867 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9868 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9870 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9871 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9872 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9873 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9874 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9875 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9876 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9877 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9878 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9879 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9880 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9881 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9882 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9883 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9884 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9885 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9886 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9887 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9888 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9889 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9890 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9891 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9892 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9893 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9894 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9895 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9896 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9897 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9898 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9899 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9900 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9902 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9903 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9904 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9905 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9906 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9907 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9908 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9909 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9910 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9911 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9912 ALC883_FUJITSU_PI2515),
9913 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9914 ALC888_FUJITSU_XA3530),
9915 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9916 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9917 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9918 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9919 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9920 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9921 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9922 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9924 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9925 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9926 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9927 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9928 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9929 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9930 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9935 /* codec SSID table for Intel Mac */
9936 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9937 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9938 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9939 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9940 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9941 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9942 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9943 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9944 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9945 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9946 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9947 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9948 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9949 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9950 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9951 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9952 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9953 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
9954 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9955 * so apparently no perfect solution yet
9957 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9958 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9959 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9963 static struct alc_config_preset alc882_presets[] = {
9964 [ALC882_3ST_DIG] = {
9965 .mixers = { alc882_base_mixer },
9966 .init_verbs = { alc882_base_init_verbs,
9967 alc882_adc1_init_verbs },
9968 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9969 .dac_nids = alc882_dac_nids,
9970 .dig_out_nid = ALC882_DIGOUT_NID,
9971 .dig_in_nid = ALC882_DIGIN_NID,
9972 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9973 .channel_mode = alc882_ch_modes,
9975 .input_mux = &alc882_capture_source,
9977 [ALC882_6ST_DIG] = {
9978 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9979 .init_verbs = { alc882_base_init_verbs,
9980 alc882_adc1_init_verbs },
9981 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9982 .dac_nids = alc882_dac_nids,
9983 .dig_out_nid = ALC882_DIGOUT_NID,
9984 .dig_in_nid = ALC882_DIGIN_NID,
9985 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9986 .channel_mode = alc882_sixstack_modes,
9987 .input_mux = &alc882_capture_source,
9990 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9991 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9992 alc882_eapd_verbs },
9993 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9994 .dac_nids = alc882_dac_nids,
9995 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9996 .channel_mode = alc882_sixstack_modes,
9997 .input_mux = &alc882_capture_source,
10000 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10001 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10002 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10003 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10004 .dac_nids = alc882_dac_nids,
10005 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10006 .channel_mode = alc880_threestack_modes,
10008 .input_mux = &alc882_capture_source,
10009 .dig_out_nid = ALC882_DIGOUT_NID,
10012 .mixers = { alc885_mba21_mixer },
10013 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10015 .dac_nids = alc882_dac_nids,
10016 .channel_mode = alc885_mba21_ch_modes,
10017 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10018 .input_mux = &alc882_capture_source,
10019 .unsol_event = alc_automute_amp_unsol_event,
10020 .setup = alc885_mba21_setup,
10021 .init_hook = alc_automute_amp,
10024 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10025 .init_verbs = { alc885_mbp3_init_verbs,
10026 alc880_gpio1_init_verbs },
10028 .dac_nids = alc882_dac_nids,
10030 .channel_mode = alc885_mbp_4ch_modes,
10031 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10032 .input_mux = &alc882_capture_source,
10033 .dig_out_nid = ALC882_DIGOUT_NID,
10034 .dig_in_nid = ALC882_DIGIN_NID,
10035 .unsol_event = alc_automute_amp_unsol_event,
10036 .setup = alc885_mbp3_setup,
10037 .init_hook = alc_automute_amp,
10040 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10041 .init_verbs = { alc885_mb5_init_verbs,
10042 alc880_gpio1_init_verbs },
10043 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10044 .dac_nids = alc882_dac_nids,
10045 .channel_mode = alc885_mb5_6ch_modes,
10046 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10047 .input_mux = &mb5_capture_source,
10048 .dig_out_nid = ALC882_DIGOUT_NID,
10049 .dig_in_nid = ALC882_DIGIN_NID,
10050 .unsol_event = alc_automute_amp_unsol_event,
10051 .setup = alc885_mb5_setup,
10052 .init_hook = alc_automute_amp,
10054 [ALC885_MACMINI3] = {
10055 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10056 .init_verbs = { alc885_macmini3_init_verbs,
10057 alc880_gpio1_init_verbs },
10058 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10059 .dac_nids = alc882_dac_nids,
10060 .channel_mode = alc885_macmini3_6ch_modes,
10061 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10062 .input_mux = &macmini3_capture_source,
10063 .dig_out_nid = ALC882_DIGOUT_NID,
10064 .dig_in_nid = ALC882_DIGIN_NID,
10065 .unsol_event = alc_automute_amp_unsol_event,
10066 .setup = alc885_macmini3_setup,
10067 .init_hook = alc_automute_amp,
10069 [ALC885_MACPRO] = {
10070 .mixers = { alc882_macpro_mixer },
10071 .init_verbs = { alc882_macpro_init_verbs },
10072 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10073 .dac_nids = alc882_dac_nids,
10074 .dig_out_nid = ALC882_DIGOUT_NID,
10075 .dig_in_nid = ALC882_DIGIN_NID,
10076 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10077 .channel_mode = alc882_ch_modes,
10078 .input_mux = &alc882_capture_source,
10079 .init_hook = alc885_macpro_init_hook,
10081 [ALC885_IMAC24] = {
10082 .mixers = { alc885_imac24_mixer },
10083 .init_verbs = { alc885_imac24_init_verbs },
10084 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10085 .dac_nids = alc882_dac_nids,
10086 .dig_out_nid = ALC882_DIGOUT_NID,
10087 .dig_in_nid = ALC882_DIGIN_NID,
10088 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10089 .channel_mode = alc882_ch_modes,
10090 .input_mux = &alc882_capture_source,
10091 .unsol_event = alc_automute_amp_unsol_event,
10092 .setup = alc885_imac24_setup,
10093 .init_hook = alc885_imac24_init_hook,
10095 [ALC885_IMAC91] = {
10096 .mixers = {alc885_imac91_mixer},
10097 .init_verbs = { alc885_imac91_init_verbs,
10098 alc880_gpio1_init_verbs },
10099 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10100 .dac_nids = alc882_dac_nids,
10101 .channel_mode = alc885_mba21_ch_modes,
10102 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10103 .input_mux = &alc889A_imac91_capture_source,
10104 .dig_out_nid = ALC882_DIGOUT_NID,
10105 .dig_in_nid = ALC882_DIGIN_NID,
10106 .unsol_event = alc_automute_amp_unsol_event,
10107 .setup = alc885_imac91_setup,
10108 .init_hook = alc_automute_amp,
10111 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10112 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10113 alc880_gpio3_init_verbs, alc882_targa_verbs},
10114 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10115 .dac_nids = alc882_dac_nids,
10116 .dig_out_nid = ALC882_DIGOUT_NID,
10117 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10118 .adc_nids = alc882_adc_nids,
10119 .capsrc_nids = alc882_capsrc_nids,
10120 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10121 .channel_mode = alc882_3ST_6ch_modes,
10123 .input_mux = &alc882_capture_source,
10124 .unsol_event = alc882_targa_unsol_event,
10125 .setup = alc882_targa_setup,
10126 .init_hook = alc882_targa_automute,
10128 [ALC882_ASUS_A7J] = {
10129 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10130 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10131 alc882_asus_a7j_verbs},
10132 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10133 .dac_nids = alc882_dac_nids,
10134 .dig_out_nid = ALC882_DIGOUT_NID,
10135 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10136 .adc_nids = alc882_adc_nids,
10137 .capsrc_nids = alc882_capsrc_nids,
10138 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10139 .channel_mode = alc882_3ST_6ch_modes,
10141 .input_mux = &alc882_capture_source,
10143 [ALC882_ASUS_A7M] = {
10144 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10145 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10146 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10147 alc882_asus_a7m_verbs },
10148 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10149 .dac_nids = alc882_dac_nids,
10150 .dig_out_nid = ALC882_DIGOUT_NID,
10151 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10152 .channel_mode = alc880_threestack_modes,
10154 .input_mux = &alc882_capture_source,
10156 [ALC883_3ST_2ch_DIG] = {
10157 .mixers = { alc883_3ST_2ch_mixer },
10158 .init_verbs = { alc883_init_verbs },
10159 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10160 .dac_nids = alc883_dac_nids,
10161 .dig_out_nid = ALC883_DIGOUT_NID,
10162 .dig_in_nid = ALC883_DIGIN_NID,
10163 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10164 .channel_mode = alc883_3ST_2ch_modes,
10165 .input_mux = &alc883_capture_source,
10167 [ALC883_3ST_6ch_DIG] = {
10168 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10169 .init_verbs = { alc883_init_verbs },
10170 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10171 .dac_nids = alc883_dac_nids,
10172 .dig_out_nid = ALC883_DIGOUT_NID,
10173 .dig_in_nid = ALC883_DIGIN_NID,
10174 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10175 .channel_mode = alc883_3ST_6ch_modes,
10177 .input_mux = &alc883_capture_source,
10179 [ALC883_3ST_6ch] = {
10180 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10181 .init_verbs = { alc883_init_verbs },
10182 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10183 .dac_nids = alc883_dac_nids,
10184 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10185 .channel_mode = alc883_3ST_6ch_modes,
10187 .input_mux = &alc883_capture_source,
10189 [ALC883_3ST_6ch_INTEL] = {
10190 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10191 .init_verbs = { alc883_init_verbs },
10192 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10193 .dac_nids = alc883_dac_nids,
10194 .dig_out_nid = ALC883_DIGOUT_NID,
10195 .dig_in_nid = ALC883_DIGIN_NID,
10196 .slave_dig_outs = alc883_slave_dig_outs,
10197 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10198 .channel_mode = alc883_3ST_6ch_intel_modes,
10200 .input_mux = &alc883_3stack_6ch_intel,
10202 [ALC889A_INTEL] = {
10203 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10204 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10205 alc_hp15_unsol_verbs },
10206 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10207 .dac_nids = alc883_dac_nids,
10208 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10209 .adc_nids = alc889_adc_nids,
10210 .dig_out_nid = ALC883_DIGOUT_NID,
10211 .dig_in_nid = ALC883_DIGIN_NID,
10212 .slave_dig_outs = alc883_slave_dig_outs,
10213 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10214 .channel_mode = alc889_8ch_intel_modes,
10215 .capsrc_nids = alc889_capsrc_nids,
10216 .input_mux = &alc889_capture_source,
10217 .setup = alc889_automute_setup,
10218 .init_hook = alc_automute_amp,
10219 .unsol_event = alc_automute_amp_unsol_event,
10223 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10224 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10225 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10226 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10227 .dac_nids = alc883_dac_nids,
10228 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10229 .adc_nids = alc889_adc_nids,
10230 .dig_out_nid = ALC883_DIGOUT_NID,
10231 .dig_in_nid = ALC883_DIGIN_NID,
10232 .slave_dig_outs = alc883_slave_dig_outs,
10233 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10234 .channel_mode = alc889_8ch_intel_modes,
10235 .capsrc_nids = alc889_capsrc_nids,
10236 .input_mux = &alc889_capture_source,
10237 .setup = alc889_automute_setup,
10238 .init_hook = alc889_intel_init_hook,
10239 .unsol_event = alc_automute_amp_unsol_event,
10242 [ALC883_6ST_DIG] = {
10243 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10244 .init_verbs = { alc883_init_verbs },
10245 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10246 .dac_nids = alc883_dac_nids,
10247 .dig_out_nid = ALC883_DIGOUT_NID,
10248 .dig_in_nid = ALC883_DIGIN_NID,
10249 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10250 .channel_mode = alc883_sixstack_modes,
10251 .input_mux = &alc883_capture_source,
10253 [ALC883_TARGA_DIG] = {
10254 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10255 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10256 alc883_targa_verbs},
10257 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10258 .dac_nids = alc883_dac_nids,
10259 .dig_out_nid = ALC883_DIGOUT_NID,
10260 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10261 .channel_mode = alc883_3ST_6ch_modes,
10263 .input_mux = &alc883_capture_source,
10264 .unsol_event = alc883_targa_unsol_event,
10265 .setup = alc882_targa_setup,
10266 .init_hook = alc882_targa_automute,
10268 [ALC883_TARGA_2ch_DIG] = {
10269 .mixers = { alc883_targa_2ch_mixer},
10270 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10271 alc883_targa_verbs},
10272 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10273 .dac_nids = alc883_dac_nids,
10274 .adc_nids = alc883_adc_nids_alt,
10275 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10276 .capsrc_nids = alc883_capsrc_nids,
10277 .dig_out_nid = ALC883_DIGOUT_NID,
10278 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10279 .channel_mode = alc883_3ST_2ch_modes,
10280 .input_mux = &alc883_capture_source,
10281 .unsol_event = alc883_targa_unsol_event,
10282 .setup = alc882_targa_setup,
10283 .init_hook = alc882_targa_automute,
10285 [ALC883_TARGA_8ch_DIG] = {
10286 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10287 alc883_chmode_mixer },
10288 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10289 alc883_targa_verbs },
10290 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10291 .dac_nids = alc883_dac_nids,
10292 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10293 .adc_nids = alc883_adc_nids_rev,
10294 .capsrc_nids = alc883_capsrc_nids_rev,
10295 .dig_out_nid = ALC883_DIGOUT_NID,
10296 .dig_in_nid = ALC883_DIGIN_NID,
10297 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10298 .channel_mode = alc883_4ST_8ch_modes,
10300 .input_mux = &alc883_capture_source,
10301 .unsol_event = alc883_targa_unsol_event,
10302 .setup = alc882_targa_setup,
10303 .init_hook = alc882_targa_automute,
10306 .mixers = { alc883_base_mixer },
10307 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10308 * and the headphone jack. Turn this on and rely on the
10309 * standard mute methods whenever the user wants to turn
10310 * these outputs off.
10312 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10313 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10314 .dac_nids = alc883_dac_nids,
10315 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10316 .channel_mode = alc883_3ST_2ch_modes,
10317 .input_mux = &alc883_capture_source,
10319 [ALC883_ACER_ASPIRE] = {
10320 .mixers = { alc883_acer_aspire_mixer },
10321 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10322 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10323 .dac_nids = alc883_dac_nids,
10324 .dig_out_nid = ALC883_DIGOUT_NID,
10325 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10326 .channel_mode = alc883_3ST_2ch_modes,
10327 .input_mux = &alc883_capture_source,
10328 .unsol_event = alc_automute_amp_unsol_event,
10329 .setup = alc883_acer_aspire_setup,
10330 .init_hook = alc_automute_amp,
10332 [ALC888_ACER_ASPIRE_4930G] = {
10333 .mixers = { alc888_acer_aspire_4930g_mixer,
10334 alc883_chmode_mixer },
10335 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10336 alc888_acer_aspire_4930g_verbs },
10337 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10338 .dac_nids = alc883_dac_nids,
10339 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10340 .adc_nids = alc883_adc_nids_rev,
10341 .capsrc_nids = alc883_capsrc_nids_rev,
10342 .dig_out_nid = ALC883_DIGOUT_NID,
10343 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10344 .channel_mode = alc883_3ST_6ch_modes,
10346 .const_channel_count = 6,
10348 ARRAY_SIZE(alc888_2_capture_sources),
10349 .input_mux = alc888_2_capture_sources,
10350 .unsol_event = alc_automute_amp_unsol_event,
10351 .setup = alc888_acer_aspire_4930g_setup,
10352 .init_hook = alc_automute_amp,
10354 [ALC888_ACER_ASPIRE_6530G] = {
10355 .mixers = { alc888_acer_aspire_6530_mixer },
10356 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10357 alc888_acer_aspire_6530g_verbs },
10358 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10359 .dac_nids = alc883_dac_nids,
10360 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10361 .adc_nids = alc883_adc_nids_rev,
10362 .capsrc_nids = alc883_capsrc_nids_rev,
10363 .dig_out_nid = ALC883_DIGOUT_NID,
10364 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10365 .channel_mode = alc883_3ST_2ch_modes,
10367 ARRAY_SIZE(alc888_2_capture_sources),
10368 .input_mux = alc888_acer_aspire_6530_sources,
10369 .unsol_event = alc_automute_amp_unsol_event,
10370 .setup = alc888_acer_aspire_6530g_setup,
10371 .init_hook = alc_automute_amp,
10373 [ALC888_ACER_ASPIRE_8930G] = {
10374 .mixers = { alc889_acer_aspire_8930g_mixer,
10375 alc883_chmode_mixer },
10376 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10377 alc889_acer_aspire_8930g_verbs,
10378 alc889_eapd_verbs},
10379 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10380 .dac_nids = alc883_dac_nids,
10381 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10382 .adc_nids = alc889_adc_nids,
10383 .capsrc_nids = alc889_capsrc_nids,
10384 .dig_out_nid = ALC883_DIGOUT_NID,
10385 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10386 .channel_mode = alc883_3ST_6ch_modes,
10388 .const_channel_count = 6,
10390 ARRAY_SIZE(alc889_capture_sources),
10391 .input_mux = alc889_capture_sources,
10392 .unsol_event = alc_automute_amp_unsol_event,
10393 .setup = alc889_acer_aspire_8930g_setup,
10394 .init_hook = alc_automute_amp,
10395 #ifdef CONFIG_SND_HDA_POWER_SAVE
10396 .power_hook = alc_power_eapd,
10399 [ALC888_ACER_ASPIRE_7730G] = {
10400 .mixers = { alc883_3ST_6ch_mixer,
10401 alc883_chmode_mixer },
10402 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10403 alc888_acer_aspire_7730G_verbs },
10404 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10405 .dac_nids = alc883_dac_nids,
10406 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10407 .adc_nids = alc883_adc_nids_rev,
10408 .capsrc_nids = alc883_capsrc_nids_rev,
10409 .dig_out_nid = ALC883_DIGOUT_NID,
10410 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10411 .channel_mode = alc883_3ST_6ch_modes,
10413 .const_channel_count = 6,
10414 .input_mux = &alc883_capture_source,
10415 .unsol_event = alc_automute_amp_unsol_event,
10416 .setup = alc888_acer_aspire_7730g_setup,
10417 .init_hook = alc_automute_amp,
10419 [ALC883_MEDION] = {
10420 .mixers = { alc883_fivestack_mixer,
10421 alc883_chmode_mixer },
10422 .init_verbs = { alc883_init_verbs,
10423 alc883_medion_eapd_verbs },
10424 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10425 .dac_nids = alc883_dac_nids,
10426 .adc_nids = alc883_adc_nids_alt,
10427 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10428 .capsrc_nids = alc883_capsrc_nids,
10429 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10430 .channel_mode = alc883_sixstack_modes,
10431 .input_mux = &alc883_capture_source,
10433 [ALC883_MEDION_WIM2160] = {
10434 .mixers = { alc883_medion_wim2160_mixer },
10435 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10436 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10437 .dac_nids = alc883_dac_nids,
10438 .dig_out_nid = ALC883_DIGOUT_NID,
10439 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10440 .adc_nids = alc883_adc_nids,
10441 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10442 .channel_mode = alc883_3ST_2ch_modes,
10443 .input_mux = &alc883_capture_source,
10444 .unsol_event = alc_automute_amp_unsol_event,
10445 .setup = alc883_medion_wim2160_setup,
10446 .init_hook = alc_automute_amp,
10448 [ALC883_LAPTOP_EAPD] = {
10449 .mixers = { alc883_base_mixer },
10450 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10451 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10452 .dac_nids = alc883_dac_nids,
10453 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10454 .channel_mode = alc883_3ST_2ch_modes,
10455 .input_mux = &alc883_capture_source,
10457 [ALC883_CLEVO_M540R] = {
10458 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10459 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10460 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10461 .dac_nids = alc883_dac_nids,
10462 .dig_out_nid = ALC883_DIGOUT_NID,
10463 .dig_in_nid = ALC883_DIGIN_NID,
10464 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10465 .channel_mode = alc883_3ST_6ch_clevo_modes,
10467 .input_mux = &alc883_capture_source,
10468 /* This machine has the hardware HP auto-muting, thus
10469 * we need no software mute via unsol event
10472 [ALC883_CLEVO_M720] = {
10473 .mixers = { alc883_clevo_m720_mixer },
10474 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10475 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10476 .dac_nids = alc883_dac_nids,
10477 .dig_out_nid = ALC883_DIGOUT_NID,
10478 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10479 .channel_mode = alc883_3ST_2ch_modes,
10480 .input_mux = &alc883_capture_source,
10481 .unsol_event = alc883_clevo_m720_unsol_event,
10482 .setup = alc883_clevo_m720_setup,
10483 .init_hook = alc883_clevo_m720_init_hook,
10485 [ALC883_LENOVO_101E_2ch] = {
10486 .mixers = { alc883_lenovo_101e_2ch_mixer},
10487 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10488 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10489 .dac_nids = alc883_dac_nids,
10490 .adc_nids = alc883_adc_nids_alt,
10491 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10492 .capsrc_nids = alc883_capsrc_nids,
10493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10494 .channel_mode = alc883_3ST_2ch_modes,
10495 .input_mux = &alc883_lenovo_101e_capture_source,
10496 .unsol_event = alc883_lenovo_101e_unsol_event,
10497 .init_hook = alc883_lenovo_101e_all_automute,
10499 [ALC883_LENOVO_NB0763] = {
10500 .mixers = { alc883_lenovo_nb0763_mixer },
10501 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10502 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10503 .dac_nids = alc883_dac_nids,
10504 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10505 .channel_mode = alc883_3ST_2ch_modes,
10507 .input_mux = &alc883_lenovo_nb0763_capture_source,
10508 .unsol_event = alc_automute_amp_unsol_event,
10509 .setup = alc883_lenovo_nb0763_setup,
10510 .init_hook = alc_automute_amp,
10512 [ALC888_LENOVO_MS7195_DIG] = {
10513 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10514 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10515 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10516 .dac_nids = alc883_dac_nids,
10517 .dig_out_nid = ALC883_DIGOUT_NID,
10518 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10519 .channel_mode = alc883_3ST_6ch_modes,
10521 .input_mux = &alc883_capture_source,
10522 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10523 .init_hook = alc888_lenovo_ms7195_front_automute,
10525 [ALC883_HAIER_W66] = {
10526 .mixers = { alc883_targa_2ch_mixer},
10527 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10528 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10529 .dac_nids = alc883_dac_nids,
10530 .dig_out_nid = ALC883_DIGOUT_NID,
10531 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10532 .channel_mode = alc883_3ST_2ch_modes,
10533 .input_mux = &alc883_capture_source,
10534 .unsol_event = alc_automute_amp_unsol_event,
10535 .setup = alc883_haier_w66_setup,
10536 .init_hook = alc_automute_amp,
10538 [ALC888_3ST_HP] = {
10539 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10540 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10541 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10542 .dac_nids = alc883_dac_nids,
10543 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10544 .channel_mode = alc888_3st_hp_modes,
10546 .input_mux = &alc883_capture_source,
10547 .unsol_event = alc_automute_amp_unsol_event,
10548 .setup = alc888_3st_hp_setup,
10549 .init_hook = alc_automute_amp,
10551 [ALC888_6ST_DELL] = {
10552 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10553 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10554 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10555 .dac_nids = alc883_dac_nids,
10556 .dig_out_nid = ALC883_DIGOUT_NID,
10557 .dig_in_nid = ALC883_DIGIN_NID,
10558 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10559 .channel_mode = alc883_sixstack_modes,
10560 .input_mux = &alc883_capture_source,
10561 .unsol_event = alc_automute_amp_unsol_event,
10562 .setup = alc888_6st_dell_setup,
10563 .init_hook = alc_automute_amp,
10566 .mixers = { alc883_mitac_mixer },
10567 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10568 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10569 .dac_nids = alc883_dac_nids,
10570 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10571 .channel_mode = alc883_3ST_2ch_modes,
10572 .input_mux = &alc883_capture_source,
10573 .unsol_event = alc_automute_amp_unsol_event,
10574 .setup = alc883_mitac_setup,
10575 .init_hook = alc_automute_amp,
10577 [ALC883_FUJITSU_PI2515] = {
10578 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10579 .init_verbs = { alc883_init_verbs,
10580 alc883_2ch_fujitsu_pi2515_verbs},
10581 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10582 .dac_nids = alc883_dac_nids,
10583 .dig_out_nid = ALC883_DIGOUT_NID,
10584 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10585 .channel_mode = alc883_3ST_2ch_modes,
10586 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10587 .unsol_event = alc_automute_amp_unsol_event,
10588 .setup = alc883_2ch_fujitsu_pi2515_setup,
10589 .init_hook = alc_automute_amp,
10591 [ALC888_FUJITSU_XA3530] = {
10592 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10593 .init_verbs = { alc883_init_verbs,
10594 alc888_fujitsu_xa3530_verbs },
10595 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10596 .dac_nids = alc883_dac_nids,
10597 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10598 .adc_nids = alc883_adc_nids_rev,
10599 .capsrc_nids = alc883_capsrc_nids_rev,
10600 .dig_out_nid = ALC883_DIGOUT_NID,
10601 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10602 .channel_mode = alc888_4ST_8ch_intel_modes,
10604 ARRAY_SIZE(alc888_2_capture_sources),
10605 .input_mux = alc888_2_capture_sources,
10606 .unsol_event = alc_automute_amp_unsol_event,
10607 .setup = alc888_fujitsu_xa3530_setup,
10608 .init_hook = alc_automute_amp,
10610 [ALC888_LENOVO_SKY] = {
10611 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10612 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10613 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10614 .dac_nids = alc883_dac_nids,
10615 .dig_out_nid = ALC883_DIGOUT_NID,
10616 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10617 .channel_mode = alc883_sixstack_modes,
10619 .input_mux = &alc883_lenovo_sky_capture_source,
10620 .unsol_event = alc_automute_amp_unsol_event,
10621 .setup = alc888_lenovo_sky_setup,
10622 .init_hook = alc_automute_amp,
10624 [ALC888_ASUS_M90V] = {
10625 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10626 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10627 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10628 .dac_nids = alc883_dac_nids,
10629 .dig_out_nid = ALC883_DIGOUT_NID,
10630 .dig_in_nid = ALC883_DIGIN_NID,
10631 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10632 .channel_mode = alc883_3ST_6ch_modes,
10634 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10635 .unsol_event = alc_sku_unsol_event,
10636 .setup = alc883_mode2_setup,
10637 .init_hook = alc_inithook,
10639 [ALC888_ASUS_EEE1601] = {
10640 .mixers = { alc883_asus_eee1601_mixer },
10641 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10642 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10643 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10644 .dac_nids = alc883_dac_nids,
10645 .dig_out_nid = ALC883_DIGOUT_NID,
10646 .dig_in_nid = ALC883_DIGIN_NID,
10647 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10648 .channel_mode = alc883_3ST_2ch_modes,
10650 .input_mux = &alc883_asus_eee1601_capture_source,
10651 .unsol_event = alc_sku_unsol_event,
10652 .init_hook = alc883_eee1601_inithook,
10654 [ALC1200_ASUS_P5Q] = {
10655 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10656 .init_verbs = { alc883_init_verbs },
10657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10658 .dac_nids = alc883_dac_nids,
10659 .dig_out_nid = ALC1200_DIGOUT_NID,
10660 .dig_in_nid = ALC883_DIGIN_NID,
10661 .slave_dig_outs = alc1200_slave_dig_outs,
10662 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10663 .channel_mode = alc883_sixstack_modes,
10664 .input_mux = &alc883_capture_source,
10667 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10668 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10669 alc880_gpio1_init_verbs },
10670 .adc_nids = alc883_adc_nids,
10671 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10672 .capsrc_nids = alc883_capsrc_nids,
10673 .dac_nids = alc883_dac_nids,
10674 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10675 .channel_mode = alc889A_mb31_6ch_modes,
10676 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10677 .input_mux = &alc889A_mb31_capture_source,
10678 .dig_out_nid = ALC883_DIGOUT_NID,
10679 .unsol_event = alc889A_mb31_unsol_event,
10680 .init_hook = alc889A_mb31_automute,
10682 [ALC883_SONY_VAIO_TT] = {
10683 .mixers = { alc883_vaiott_mixer },
10684 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10685 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10686 .dac_nids = alc883_dac_nids,
10687 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10688 .channel_mode = alc883_3ST_2ch_modes,
10689 .input_mux = &alc883_capture_source,
10690 .unsol_event = alc_automute_amp_unsol_event,
10691 .setup = alc883_vaiott_setup,
10692 .init_hook = alc_automute_amp,
10701 PINFIX_ABIT_AW9D_MAX,
10702 PINFIX_LENOVO_Y530,
10704 PINFIX_ACER_ASPIRE_7736,
10705 PINFIX_GIGABYTE_880GM,
10708 static const struct alc_fixup alc882_fixups[] = {
10709 [PINFIX_ABIT_AW9D_MAX] = {
10710 .type = ALC_FIXUP_PINS,
10711 .v.pins = (const struct alc_pincfg[]) {
10712 { 0x15, 0x01080104 }, /* side */
10713 { 0x16, 0x01011012 }, /* rear */
10714 { 0x17, 0x01016011 }, /* clfe */
10718 [PINFIX_LENOVO_Y530] = {
10719 .type = ALC_FIXUP_PINS,
10720 .v.pins = (const struct alc_pincfg[]) {
10721 { 0x15, 0x99130112 }, /* rear int speakers */
10722 { 0x16, 0x99130111 }, /* subwoofer */
10726 [PINFIX_PB_M5210] = {
10727 .type = ALC_FIXUP_VERBS,
10728 .v.verbs = (const struct hda_verb[]) {
10729 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10733 [PINFIX_ACER_ASPIRE_7736] = {
10734 .type = ALC_FIXUP_SKU,
10735 .v.sku = ALC_FIXUP_SKU_IGNORE,
10737 [PINFIX_GIGABYTE_880GM] = {
10738 .type = ALC_FIXUP_PINS,
10739 .v.pins = (const struct alc_pincfg[]) {
10740 { 0x14, 0x1114410 }, /* set as speaker */
10746 static struct snd_pci_quirk alc882_fixup_tbl[] = {
10747 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10748 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
10749 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10750 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10751 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM),
10756 * BIOS auto configuration
10758 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10759 const struct auto_pin_cfg *cfg)
10761 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10764 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10765 hda_nid_t nid, int pin_type,
10770 /* set as output */
10771 alc_set_pin_output(codec, nid, pin_type);
10775 else if (dac >= 0x02 && dac <= 0x05)
10779 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10782 static void alc882_auto_init_multi_out(struct hda_codec *codec)
10784 struct alc_spec *spec = codec->spec;
10787 for (i = 0; i <= HDA_SIDE; i++) {
10788 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10789 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10791 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10792 spec->multiout.dac_nids[i]);
10796 static void alc882_auto_init_hp_out(struct hda_codec *codec)
10798 struct alc_spec *spec = codec->spec;
10799 hda_nid_t pin, dac;
10802 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
10803 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10804 pin = spec->autocfg.hp_pins[i];
10807 dac = spec->multiout.hp_nid;
10809 dac = spec->multiout.dac_nids[0]; /* to front */
10810 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10814 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
10815 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10816 pin = spec->autocfg.speaker_pins[i];
10819 dac = spec->multiout.extra_out_nid[0];
10821 dac = spec->multiout.dac_nids[0]; /* to front */
10822 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10827 static void alc882_auto_init_analog_input(struct hda_codec *codec)
10829 struct alc_spec *spec = codec->spec;
10830 struct auto_pin_cfg *cfg = &spec->autocfg;
10833 for (i = 0; i < cfg->num_inputs; i++) {
10834 hda_nid_t nid = cfg->inputs[i].pin;
10835 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
10836 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10837 snd_hda_codec_write(codec, nid, 0,
10838 AC_VERB_SET_AMP_GAIN_MUTE,
10843 static void alc882_auto_init_input_src(struct hda_codec *codec)
10845 struct alc_spec *spec = codec->spec;
10848 for (c = 0; c < spec->num_adc_nids; c++) {
10849 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10850 hda_nid_t nid = spec->capsrc_nids[c];
10851 unsigned int mux_idx;
10852 const struct hda_input_mux *imux;
10853 int conns, mute, idx, item;
10856 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
10857 AC_VERB_SET_AMP_GAIN_MUTE,
10860 conns = snd_hda_get_connections(codec, nid, conn_list,
10861 ARRAY_SIZE(conn_list));
10864 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10865 imux = &spec->input_mux[mux_idx];
10866 if (!imux->num_items && mux_idx > 0)
10867 imux = &spec->input_mux[0];
10868 for (idx = 0; idx < conns; idx++) {
10869 /* if the current connection is the selected one,
10870 * unmute it as default - otherwise mute it
10872 mute = AMP_IN_MUTE(idx);
10873 for (item = 0; item < imux->num_items; item++) {
10874 if (imux->items[item].index == idx) {
10875 if (spec->cur_mux[c] == item)
10876 mute = AMP_IN_UNMUTE(idx);
10880 /* check if we have a selector or mixer
10881 * we could check for the widget type instead, but
10882 * just check for Amp-In presence (in case of mixer
10883 * without amp-in there is something wrong, this
10884 * function shouldn't be used or capsrc nid is wrong)
10886 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
10887 snd_hda_codec_write(codec, nid, 0,
10888 AC_VERB_SET_AMP_GAIN_MUTE,
10890 else if (mute != AMP_IN_MUTE(idx))
10891 snd_hda_codec_write(codec, nid, 0,
10892 AC_VERB_SET_CONNECT_SEL,
10898 /* add mic boosts if needed */
10899 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10901 struct alc_spec *spec = codec->spec;
10902 struct auto_pin_cfg *cfg = &spec->autocfg;
10906 const char *prev_label = NULL;
10908 for (i = 0; i < cfg->num_inputs; i++) {
10909 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10911 nid = cfg->inputs[i].pin;
10912 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10914 char boost_label[32];
10916 label = hda_get_autocfg_input_label(codec, cfg, i);
10917 if (prev_label && !strcmp(label, prev_label))
10921 prev_label = label;
10923 snprintf(boost_label, sizeof(boost_label),
10924 "%s Boost Volume", label);
10925 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10926 boost_label, type_idx,
10927 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10935 /* almost identical with ALC880 parser... */
10936 static int alc882_parse_auto_config(struct hda_codec *codec)
10938 struct alc_spec *spec = codec->spec;
10939 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10942 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10946 if (!spec->autocfg.line_outs)
10947 return 0; /* can't find valid BIOS pin config */
10949 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10952 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10955 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10959 err = alc880_auto_create_extra_out(spec,
10960 spec->autocfg.speaker_pins[0],
10964 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10968 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10970 alc_auto_parse_digital(codec);
10972 if (spec->kctls.list)
10973 add_mixer(spec, spec->kctls.list);
10975 add_verb(spec, alc883_auto_init_verbs);
10976 /* if ADC 0x07 is available, initialize it, too */
10977 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10978 add_verb(spec, alc882_adc1_init_verbs);
10980 spec->num_mux_defs = 1;
10981 spec->input_mux = &spec->private_imux[0];
10983 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10985 err = alc_auto_add_mic_boost(codec);
10989 return 1; /* config found */
10992 /* additional initialization for auto-configuration model */
10993 static void alc882_auto_init(struct hda_codec *codec)
10995 struct alc_spec *spec = codec->spec;
10996 alc882_auto_init_multi_out(codec);
10997 alc882_auto_init_hp_out(codec);
10998 alc882_auto_init_analog_input(codec);
10999 alc882_auto_init_input_src(codec);
11000 alc_auto_init_digital(codec);
11001 if (spec->unsol_event)
11002 alc_inithook(codec);
11005 static int patch_alc882(struct hda_codec *codec)
11007 struct alc_spec *spec;
11008 int err, board_config;
11010 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11014 codec->spec = spec;
11016 switch (codec->vendor_id) {
11021 /* ALC883 and variants */
11022 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11026 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11030 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11031 board_config = snd_hda_check_board_codec_sid_config(codec,
11032 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11034 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11035 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11037 board_config = ALC882_AUTO;
11040 if (board_config == ALC882_AUTO) {
11041 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11042 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11045 alc_auto_parse_customize_define(codec);
11047 if (board_config == ALC882_AUTO) {
11048 /* automatic parse from the BIOS config */
11049 err = alc882_parse_auto_config(codec);
11055 "hda_codec: Cannot set up configuration "
11056 "from BIOS. Using base mode...\n");
11057 board_config = ALC882_3ST_DIG;
11061 if (has_cdefine_beep(codec)) {
11062 err = snd_hda_attach_beep_device(codec, 0x1);
11069 if (board_config != ALC882_AUTO)
11070 setup_preset(codec, &alc882_presets[board_config]);
11072 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11073 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11074 /* FIXME: setup DAC5 */
11075 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11076 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11078 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11079 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11081 if (!spec->adc_nids && spec->input_mux) {
11083 spec->num_adc_nids = 0;
11084 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11085 const struct hda_input_mux *imux = spec->input_mux;
11087 hda_nid_t items[16];
11088 hda_nid_t nid = alc882_adc_nids[i];
11089 unsigned int wcap = get_wcaps(codec, nid);
11091 wcap = get_wcaps_type(wcap);
11092 if (wcap != AC_WID_AUD_IN)
11094 spec->private_adc_nids[spec->num_adc_nids] = nid;
11095 err = snd_hda_get_connections(codec, nid, &cap, 1);
11098 err = snd_hda_get_connections(codec, cap, items,
11099 ARRAY_SIZE(items));
11102 for (j = 0; j < imux->num_items; j++)
11103 if (imux->items[j].index >= err)
11105 if (j < imux->num_items)
11107 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11108 spec->num_adc_nids++;
11110 spec->adc_nids = spec->private_adc_nids;
11111 spec->capsrc_nids = spec->private_capsrc_nids;
11114 set_capture_mixer(codec);
11116 if (has_cdefine_beep(codec))
11117 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11119 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11121 spec->vmaster_nid = 0x0c;
11123 codec->patch_ops = alc_patch_ops;
11124 if (board_config == ALC882_AUTO)
11125 spec->init_hook = alc882_auto_init;
11127 alc_init_jacks(codec);
11128 #ifdef CONFIG_SND_HDA_POWER_SAVE
11129 if (!spec->loopback.amplist)
11130 spec->loopback.amplist = alc882_loopbacks;
11141 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11142 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
11144 #define alc262_dac_nids alc260_dac_nids
11145 #define alc262_adc_nids alc882_adc_nids
11146 #define alc262_adc_nids_alt alc882_adc_nids_alt
11147 #define alc262_capsrc_nids alc882_capsrc_nids
11148 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11150 #define alc262_modes alc260_modes
11151 #define alc262_capture_source alc882_capture_source
11153 static hda_nid_t alc262_dmic_adc_nids[1] = {
11158 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11160 static struct snd_kcontrol_new alc262_base_mixer[] = {
11161 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11162 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11163 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11164 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11165 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11166 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11170 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11171 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11175 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11176 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11180 /* update HP, line and mono-out pins according to the master switch */
11181 static void alc262_hp_master_update(struct hda_codec *codec)
11183 struct alc_spec *spec = codec->spec;
11184 int val = spec->master_sw;
11186 /* HP & line-out */
11187 snd_hda_codec_write_cache(codec, 0x1b, 0,
11188 AC_VERB_SET_PIN_WIDGET_CONTROL,
11190 snd_hda_codec_write_cache(codec, 0x15, 0,
11191 AC_VERB_SET_PIN_WIDGET_CONTROL,
11193 /* mono (speaker) depending on the HP jack sense */
11194 val = val && !spec->jack_present;
11195 snd_hda_codec_write_cache(codec, 0x16, 0,
11196 AC_VERB_SET_PIN_WIDGET_CONTROL,
11197 val ? PIN_OUT : 0);
11200 static void alc262_hp_bpc_automute(struct hda_codec *codec)
11202 struct alc_spec *spec = codec->spec;
11204 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11205 alc262_hp_master_update(codec);
11208 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11210 if ((res >> 26) != ALC880_HP_EVENT)
11212 alc262_hp_bpc_automute(codec);
11215 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11217 struct alc_spec *spec = codec->spec;
11219 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11220 alc262_hp_master_update(codec);
11223 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11226 if ((res >> 26) != ALC880_HP_EVENT)
11228 alc262_hp_wildwest_automute(codec);
11231 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11233 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11234 struct snd_ctl_elem_value *ucontrol)
11236 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11237 struct alc_spec *spec = codec->spec;
11238 int val = !!*ucontrol->value.integer.value;
11240 if (val == spec->master_sw)
11242 spec->master_sw = val;
11243 alc262_hp_master_update(codec);
11247 #define ALC262_HP_MASTER_SWITCH \
11249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11250 .name = "Master Playback Switch", \
11251 .info = snd_ctl_boolean_mono_info, \
11252 .get = alc262_hp_master_sw_get, \
11253 .put = alc262_hp_master_sw_put, \
11256 .iface = NID_MAPPING, \
11257 .name = "Master Playback Switch", \
11258 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11262 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11263 ALC262_HP_MASTER_SWITCH,
11264 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11265 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11267 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11269 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
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("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11278 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11279 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11280 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11281 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11282 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11286 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11287 ALC262_HP_MASTER_SWITCH,
11288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11289 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11292 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11294 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11296 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11297 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11298 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11299 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11300 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11306 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11307 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11308 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11309 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11313 /* mute/unmute internal speaker according to the hp jack and mute state */
11314 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11316 struct alc_spec *spec = codec->spec;
11318 spec->autocfg.hp_pins[0] = 0x15;
11319 spec->autocfg.speaker_pins[0] = 0x14;
11322 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11323 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11324 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11325 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11329 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11333 static struct hda_verb alc262_hp_t5735_verbs[] = {
11334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11341 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11342 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11343 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11344 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11345 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11346 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11347 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11351 static struct hda_verb alc262_hp_rp5700_verbs[] = {
11352 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11353 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11356 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11357 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11365 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11372 /* bind hp and internal speaker mute (with plug check) as master switch */
11373 static void alc262_hippo_master_update(struct hda_codec *codec)
11375 struct alc_spec *spec = codec->spec;
11376 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11377 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11378 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11382 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11383 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11384 HDA_AMP_MUTE, mute);
11385 /* mute internal speaker per jack sense */
11386 if (spec->jack_present)
11387 mute = HDA_AMP_MUTE;
11389 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11390 HDA_AMP_MUTE, mute);
11391 if (speaker_nid && speaker_nid != line_nid)
11392 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
11393 HDA_AMP_MUTE, mute);
11396 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11398 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11399 struct snd_ctl_elem_value *ucontrol)
11401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11402 struct alc_spec *spec = codec->spec;
11403 int val = !!*ucontrol->value.integer.value;
11405 if (val == spec->master_sw)
11407 spec->master_sw = val;
11408 alc262_hippo_master_update(codec);
11412 #define ALC262_HIPPO_MASTER_SWITCH \
11414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11415 .name = "Master Playback Switch", \
11416 .info = snd_ctl_boolean_mono_info, \
11417 .get = alc262_hippo_master_sw_get, \
11418 .put = alc262_hippo_master_sw_put, \
11421 .iface = NID_MAPPING, \
11422 .name = "Master Playback Switch", \
11423 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11424 (SUBDEV_SPEAKER(0) << 16), \
11427 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11428 ALC262_HIPPO_MASTER_SWITCH,
11429 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11430 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11431 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11432 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11433 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11434 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11435 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11436 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11437 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11438 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11439 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11444 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11445 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11446 ALC262_HIPPO_MASTER_SWITCH,
11447 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11448 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11449 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11450 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11453 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11456 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11460 /* mute/unmute internal speaker according to the hp jack and mute state */
11461 static void alc262_hippo_automute(struct hda_codec *codec)
11463 struct alc_spec *spec = codec->spec;
11464 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11466 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
11467 alc262_hippo_master_update(codec);
11470 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11472 if ((res >> 26) != ALC880_HP_EVENT)
11474 alc262_hippo_automute(codec);
11477 static void alc262_hippo_setup(struct hda_codec *codec)
11479 struct alc_spec *spec = codec->spec;
11481 spec->autocfg.hp_pins[0] = 0x15;
11482 spec->autocfg.speaker_pins[0] = 0x14;
11485 static void alc262_hippo1_setup(struct hda_codec *codec)
11487 struct alc_spec *spec = codec->spec;
11489 spec->autocfg.hp_pins[0] = 0x1b;
11490 spec->autocfg.speaker_pins[0] = 0x14;
11494 static struct snd_kcontrol_new alc262_sony_mixer[] = {
11495 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11496 ALC262_HIPPO_MASTER_SWITCH,
11497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11498 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11499 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11500 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11504 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11505 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11506 ALC262_HIPPO_MASTER_SWITCH,
11507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11510 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11511 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11515 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11516 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11517 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11518 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11519 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11524 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11525 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11526 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11527 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11531 static struct hda_verb alc262_tyan_verbs[] = {
11532 /* Headphone automute */
11533 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11534 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11535 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11537 /* P11 AUX_IN, white 4-pin connector */
11538 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11539 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11540 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11541 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11546 /* unsolicited event for HP jack sensing */
11547 static void alc262_tyan_setup(struct hda_codec *codec)
11549 struct alc_spec *spec = codec->spec;
11551 spec->autocfg.hp_pins[0] = 0x1b;
11552 spec->autocfg.speaker_pins[0] = 0x15;
11556 #define alc262_capture_mixer alc882_capture_mixer
11557 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11560 * generic initialization of ADC, input mixers and output mixers
11562 static struct hda_verb alc262_init_verbs[] = {
11564 * Unmute ADC0-2 and set the default input to mic-in
11566 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11568 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11570 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11571 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11573 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11575 * Note: PASD motherboards uses the Line In 2 as the input for
11576 * front panel mic (mic 2)
11578 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11586 * Set up output mixers (0x0c - 0x0e)
11588 /* set vol=0 to output mixers */
11589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11590 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11591 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11592 /* set up input amps for analog loopback */
11593 /* Amp Indices: DAC = 0, mixer = 1 */
11594 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11596 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11597 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11598 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11599 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11602 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11603 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11604 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11605 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11606 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11608 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11610 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11611 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11612 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11614 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11617 /* FIXME: use matrix-type input source selection */
11618 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11619 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11620 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11621 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11622 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11623 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11625 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11627 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11630 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11631 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11632 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11633 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11638 static struct hda_verb alc262_eapd_verbs[] = {
11639 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11640 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11644 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11645 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11646 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11647 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11649 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11650 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11654 static struct hda_verb alc262_sony_unsol_verbs[] = {
11655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11659 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11664 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11665 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11666 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11667 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11673 static struct hda_verb alc262_toshiba_s06_verbs[] = {
11674 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11677 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11678 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11679 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11680 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11681 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11685 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11687 struct alc_spec *spec = codec->spec;
11689 spec->autocfg.hp_pins[0] = 0x15;
11690 spec->autocfg.speaker_pins[0] = 0x14;
11691 spec->ext_mic.pin = 0x18;
11692 spec->ext_mic.mux_idx = 0;
11693 spec->int_mic.pin = 0x12;
11694 spec->int_mic.mux_idx = 9;
11695 spec->auto_mic = 1;
11701 * 0x16 = internal speaker
11702 * 0x18 = external mic
11705 static struct snd_kcontrol_new alc262_nec_mixer[] = {
11706 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11707 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11711 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11713 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11718 static struct hda_verb alc262_nec_verbs[] = {
11719 /* Unmute Speaker */
11720 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11723 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11726 /* External mic to headphone */
11727 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11728 /* External mic to speaker */
11729 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11735 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11736 * 0x1b = port replicator headphone out
11739 #define ALC_HP_EVENT 0x37
11741 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11742 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11744 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11745 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11749 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11750 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11751 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11755 static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11756 /* Front Mic pin: input vref at 50% */
11757 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11762 static struct hda_input_mux alc262_fujitsu_capture_source = {
11766 { "Internal Mic", 0x1 },
11771 static struct hda_input_mux alc262_HP_capture_source = {
11775 { "Front Mic", 0x1 },
11782 static struct hda_input_mux alc262_HP_D7000_capture_source = {
11786 { "Front Mic", 0x2 },
11792 /* mute/unmute internal speaker according to the hp jacks and mute state */
11793 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11795 struct alc_spec *spec = codec->spec;
11798 if (force || !spec->sense_updated) {
11799 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11800 snd_hda_jack_detect(codec, 0x1b);
11801 spec->sense_updated = 1;
11803 /* unmute internal speaker only if both HPs are unplugged and
11804 * master switch is on
11806 if (spec->jack_present)
11807 mute = HDA_AMP_MUTE;
11809 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11810 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11811 HDA_AMP_MUTE, mute);
11814 /* unsolicited event for HP jack sensing */
11815 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11818 if ((res >> 26) != ALC_HP_EVENT)
11820 alc262_fujitsu_automute(codec, 1);
11823 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11825 alc262_fujitsu_automute(codec, 1);
11828 /* bind volumes of both NID 0x0c and 0x0d */
11829 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11830 .ops = &snd_hda_bind_vol,
11832 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11833 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11838 /* mute/unmute internal speaker according to the hp jack and mute state */
11839 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11841 struct alc_spec *spec = codec->spec;
11844 if (force || !spec->sense_updated) {
11845 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11846 spec->sense_updated = 1;
11848 if (spec->jack_present) {
11849 /* mute internal speaker */
11850 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11851 HDA_AMP_MUTE, HDA_AMP_MUTE);
11852 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11853 HDA_AMP_MUTE, HDA_AMP_MUTE);
11855 /* unmute internal speaker if necessary */
11856 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11857 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11858 HDA_AMP_MUTE, mute);
11859 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11860 HDA_AMP_MUTE, mute);
11864 /* unsolicited event for HP jack sensing */
11865 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11868 if ((res >> 26) != ALC_HP_EVENT)
11870 alc262_lenovo_3000_automute(codec, 1);
11873 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11874 int dir, int idx, long *valp)
11878 for (i = 0; i < 2; i++, valp++)
11879 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11881 *valp ? 0 : HDA_AMP_MUTE);
11885 /* bind hp and internal speaker mute (with plug check) */
11886 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11887 struct snd_ctl_elem_value *ucontrol)
11889 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11890 long *valp = ucontrol->value.integer.value;
11893 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11894 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11896 alc262_fujitsu_automute(codec, 0);
11900 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11901 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11904 .name = "Master Playback Switch",
11905 .subdevice = HDA_SUBDEV_AMP_FLAG,
11906 .info = snd_hda_mixer_amp_switch_info,
11907 .get = snd_hda_mixer_amp_switch_get,
11908 .put = alc262_fujitsu_master_sw_put,
11909 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11912 .iface = NID_MAPPING,
11913 .name = "Master Playback Switch",
11914 .private_value = 0x1b,
11916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11918 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11922 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11923 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11927 /* bind hp and internal speaker mute (with plug check) */
11928 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11929 struct snd_ctl_elem_value *ucontrol)
11931 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11932 long *valp = ucontrol->value.integer.value;
11935 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11937 alc262_lenovo_3000_automute(codec, 0);
11941 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11942 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11945 .name = "Master Playback Switch",
11946 .subdevice = HDA_SUBDEV_AMP_FLAG,
11947 .info = snd_hda_mixer_amp_switch_info,
11948 .get = snd_hda_mixer_amp_switch_get,
11949 .put = alc262_lenovo_3000_master_sw_put,
11950 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11952 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11953 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11955 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11956 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11957 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11958 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11959 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11963 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11964 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11965 ALC262_HIPPO_MASTER_SWITCH,
11966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11968 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11969 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11970 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11971 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11975 /* additional init verbs for Benq laptops */
11976 static struct hda_verb alc262_EAPD_verbs[] = {
11977 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11978 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11982 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11984 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11986 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11987 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11991 /* Samsung Q1 Ultra Vista model setup */
11992 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11993 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11994 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11997 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11998 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12002 static struct hda_verb alc262_ultra_verbs[] = {
12004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12006 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12008 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12009 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12010 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12011 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12013 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12014 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12016 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12017 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12019 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12021 /* ADC, choose mic */
12022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12030 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12031 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12035 /* mute/unmute internal speaker according to the hp jack and mute state */
12036 static void alc262_ultra_automute(struct hda_codec *codec)
12038 struct alc_spec *spec = codec->spec;
12042 /* auto-mute only when HP is used as HP */
12043 if (!spec->cur_mux[0]) {
12044 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12045 if (spec->jack_present)
12046 mute = HDA_AMP_MUTE;
12048 /* mute/unmute internal speaker */
12049 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12050 HDA_AMP_MUTE, mute);
12051 /* mute/unmute HP */
12052 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12053 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12056 /* unsolicited event for HP jack sensing */
12057 static void alc262_ultra_unsol_event(struct hda_codec *codec,
12060 if ((res >> 26) != ALC880_HP_EVENT)
12062 alc262_ultra_automute(codec);
12065 static struct hda_input_mux alc262_ultra_capture_source = {
12069 { "Headphone", 0x7 },
12073 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12074 struct snd_ctl_elem_value *ucontrol)
12076 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12077 struct alc_spec *spec = codec->spec;
12080 ret = alc_mux_enum_put(kcontrol, ucontrol);
12083 /* reprogram the HP pin as mic or HP according to the input source */
12084 snd_hda_codec_write_cache(codec, 0x15, 0,
12085 AC_VERB_SET_PIN_WIDGET_CONTROL,
12086 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12087 alc262_ultra_automute(codec); /* mute/unmute HP */
12091 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12092 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12093 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12096 .name = "Capture Source",
12097 .info = alc_mux_enum_info,
12098 .get = alc_mux_enum_get,
12099 .put = alc262_ultra_mux_enum_put,
12102 .iface = NID_MAPPING,
12103 .name = "Capture Source",
12104 .private_value = 0x15,
12109 /* We use two mixers depending on the output pin; 0x16 is a mono output
12110 * and thus it's bound with a different mixer.
12111 * This function returns which mixer amp should be used.
12113 static int alc262_check_volbit(hda_nid_t nid)
12117 else if (nid == 0x16)
12123 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12124 const char *pfx, int *vbits, int idx)
12129 vbit = alc262_check_volbit(nid);
12132 if (*vbits & vbit) /* a volume control for this mixer already there */
12136 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12138 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12139 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12142 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12143 const char *pfx, int idx)
12150 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12152 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12153 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12156 /* add playback controls from the parsed DAC table */
12157 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12158 const struct auto_pin_cfg *cfg)
12164 spec->multiout.num_dacs = 1; /* only use one dac */
12165 spec->multiout.dac_nids = spec->private_dac_nids;
12166 spec->multiout.dac_nids[0] = 2;
12168 pfx = alc_get_line_out_pfx(cfg, true);
12171 for (i = 0; i < 2; i++) {
12172 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12175 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12176 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12181 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12182 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12189 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12190 alc262_check_volbit(cfg->speaker_pins[0]) |
12191 alc262_check_volbit(cfg->hp_pins[0]);
12192 if (vbits == 1 || vbits == 2)
12193 pfx = "Master"; /* only one mixer is used */
12195 for (i = 0; i < 2; i++) {
12196 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12200 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12201 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12202 "Speaker", &vbits, i);
12206 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12207 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12208 "Headphone", &vbits, i);
12216 #define alc262_auto_create_input_ctls \
12217 alc882_auto_create_input_ctls
12220 * generic initialization of ADC, input mixers and output mixers
12222 static struct hda_verb alc262_volume_init_verbs[] = {
12224 * Unmute ADC0-2 and set the default input to mic-in
12226 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12228 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12229 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12230 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12231 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12233 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12235 * Note: PASD motherboards uses the Line In 2 as the input for
12236 * front panel mic (mic 2)
12238 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12239 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12246 * Set up output mixers (0x0c - 0x0f)
12248 /* set vol=0 to output mixers */
12249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12250 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12251 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12253 /* set up input amps for analog loopback */
12254 /* Amp Indices: DAC = 0, mixer = 1 */
12255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12257 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12262 /* FIXME: use matrix-type input source selection */
12263 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12264 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12266 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12267 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12268 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12270 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12271 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12272 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12273 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12275 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12278 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12283 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12285 * Unmute ADC0-2 and set the default input to mic-in
12287 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12288 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12289 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12290 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12291 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12292 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12294 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12296 * Note: PASD motherboards uses the Line In 2 as the input for
12297 * front panel mic (mic 2)
12299 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12301 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12302 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12303 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12304 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12305 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12306 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12309 * Set up output mixers (0x0c - 0x0e)
12311 /* set vol=0 to output mixers */
12312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12313 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12314 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12316 /* set up input amps for analog loopback */
12317 /* Amp Indices: DAC = 0, mixer = 1 */
12318 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12319 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12320 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12321 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12322 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12323 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12325 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12327 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12329 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12332 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12333 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12337 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12338 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12339 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12342 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12343 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12345 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12346 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12349 /* FIXME: use matrix-type input source selection */
12350 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12351 /* Input mixer1: only unmute Mic */
12352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12370 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12380 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12382 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12387 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12389 * Unmute ADC0-2 and set the default input to mic-in
12391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12394 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12395 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12398 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12400 * Note: PASD motherboards uses the Line In 2 as the input for front
12401 * panel mic (mic 2)
12403 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12413 * Set up output mixers (0x0c - 0x0e)
12415 /* set vol=0 to output mixers */
12416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12420 /* set up input amps for analog loopback */
12421 /* Amp Indices: DAC = 0, mixer = 1 */
12422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12425 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12427 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12431 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12434 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12435 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12438 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12441 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12442 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12444 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12445 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12446 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12447 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12448 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12449 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12451 /* FIXME: use matrix-type input source selection */
12452 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12453 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12459 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12467 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12475 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12478 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12483 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12487 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12490 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12491 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12492 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12495 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12496 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12507 static const struct alc_fixup alc262_fixups[] = {
12508 [PINFIX_FSC_H270] = {
12509 .type = ALC_FIXUP_PINS,
12510 .v.pins = (const struct alc_pincfg[]) {
12511 { 0x14, 0x99130110 }, /* speaker */
12512 { 0x15, 0x0221142f }, /* front HP */
12513 { 0x1b, 0x0121141f }, /* rear HP */
12519 static struct snd_pci_quirk alc262_fixup_tbl[] = {
12520 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12525 #ifdef CONFIG_SND_HDA_POWER_SAVE
12526 #define alc262_loopbacks alc880_loopbacks
12529 /* pcm configuration: identical with ALC880 */
12530 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12531 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12532 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12533 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12536 * BIOS auto configuration
12538 static int alc262_parse_auto_config(struct hda_codec *codec)
12540 struct alc_spec *spec = codec->spec;
12542 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12544 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12548 if (!spec->autocfg.line_outs) {
12549 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12550 spec->multiout.max_channels = 2;
12551 spec->no_analog = 1;
12554 return 0; /* can't find valid BIOS pin config */
12556 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12559 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12563 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12566 alc_auto_parse_digital(codec);
12568 if (spec->kctls.list)
12569 add_mixer(spec, spec->kctls.list);
12571 add_verb(spec, alc262_volume_init_verbs);
12572 spec->num_mux_defs = 1;
12573 spec->input_mux = &spec->private_imux[0];
12575 err = alc_auto_add_mic_boost(codec);
12579 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12584 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12585 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12586 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12587 #define alc262_auto_init_input_src alc882_auto_init_input_src
12590 /* init callback for auto-configuration model -- overriding the default init */
12591 static void alc262_auto_init(struct hda_codec *codec)
12593 struct alc_spec *spec = codec->spec;
12594 alc262_auto_init_multi_out(codec);
12595 alc262_auto_init_hp_out(codec);
12596 alc262_auto_init_analog_input(codec);
12597 alc262_auto_init_input_src(codec);
12598 alc_auto_init_digital(codec);
12599 if (spec->unsol_event)
12600 alc_inithook(codec);
12604 * configuration and preset
12606 static const char * const alc262_models[ALC262_MODEL_LAST] = {
12607 [ALC262_BASIC] = "basic",
12608 [ALC262_HIPPO] = "hippo",
12609 [ALC262_HIPPO_1] = "hippo_1",
12610 [ALC262_FUJITSU] = "fujitsu",
12611 [ALC262_HP_BPC] = "hp-bpc",
12612 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12613 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12614 [ALC262_HP_RP5700] = "hp-rp5700",
12615 [ALC262_BENQ_ED8] = "benq",
12616 [ALC262_BENQ_T31] = "benq-t31",
12617 [ALC262_SONY_ASSAMD] = "sony-assamd",
12618 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12619 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12620 [ALC262_ULTRA] = "ultra",
12621 [ALC262_LENOVO_3000] = "lenovo-3000",
12622 [ALC262_NEC] = "nec",
12623 [ALC262_TYAN] = "tyan",
12624 [ALC262_AUTO] = "auto",
12627 static struct snd_pci_quirk alc262_cfg_tbl[] = {
12628 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12629 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12630 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12632 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12634 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12636 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12638 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12639 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12640 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12641 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12642 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12643 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12644 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12645 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12646 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12647 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12648 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12649 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12650 ALC262_HP_TC_T5735),
12651 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12652 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12653 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12654 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12655 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12656 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12657 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12658 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12659 #if 0 /* disable the quirk since model=auto works better in recent versions */
12660 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12661 ALC262_SONY_ASSAMD),
12663 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12664 ALC262_TOSHIBA_RX1),
12665 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12666 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12667 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12668 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12669 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12671 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12672 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12673 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12674 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12675 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12679 static struct alc_config_preset alc262_presets[] = {
12681 .mixers = { alc262_base_mixer },
12682 .init_verbs = { alc262_init_verbs },
12683 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12684 .dac_nids = alc262_dac_nids,
12686 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12687 .channel_mode = alc262_modes,
12688 .input_mux = &alc262_capture_source,
12691 .mixers = { alc262_hippo_mixer },
12692 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12693 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12694 .dac_nids = alc262_dac_nids,
12696 .dig_out_nid = ALC262_DIGOUT_NID,
12697 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12698 .channel_mode = alc262_modes,
12699 .input_mux = &alc262_capture_source,
12700 .unsol_event = alc262_hippo_unsol_event,
12701 .setup = alc262_hippo_setup,
12702 .init_hook = alc262_hippo_automute,
12704 [ALC262_HIPPO_1] = {
12705 .mixers = { alc262_hippo1_mixer },
12706 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12707 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12708 .dac_nids = alc262_dac_nids,
12710 .dig_out_nid = ALC262_DIGOUT_NID,
12711 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12712 .channel_mode = alc262_modes,
12713 .input_mux = &alc262_capture_source,
12714 .unsol_event = alc262_hippo_unsol_event,
12715 .setup = alc262_hippo1_setup,
12716 .init_hook = alc262_hippo_automute,
12718 [ALC262_FUJITSU] = {
12719 .mixers = { alc262_fujitsu_mixer },
12720 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12721 alc262_fujitsu_unsol_verbs },
12722 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12723 .dac_nids = alc262_dac_nids,
12725 .dig_out_nid = ALC262_DIGOUT_NID,
12726 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12727 .channel_mode = alc262_modes,
12728 .input_mux = &alc262_fujitsu_capture_source,
12729 .unsol_event = alc262_fujitsu_unsol_event,
12730 .init_hook = alc262_fujitsu_init_hook,
12732 [ALC262_HP_BPC] = {
12733 .mixers = { alc262_HP_BPC_mixer },
12734 .init_verbs = { alc262_HP_BPC_init_verbs },
12735 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12736 .dac_nids = alc262_dac_nids,
12738 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12739 .channel_mode = alc262_modes,
12740 .input_mux = &alc262_HP_capture_source,
12741 .unsol_event = alc262_hp_bpc_unsol_event,
12742 .init_hook = alc262_hp_bpc_automute,
12744 [ALC262_HP_BPC_D7000_WF] = {
12745 .mixers = { alc262_HP_BPC_WildWest_mixer },
12746 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12747 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12748 .dac_nids = alc262_dac_nids,
12750 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12751 .channel_mode = alc262_modes,
12752 .input_mux = &alc262_HP_D7000_capture_source,
12753 .unsol_event = alc262_hp_wildwest_unsol_event,
12754 .init_hook = alc262_hp_wildwest_automute,
12756 [ALC262_HP_BPC_D7000_WL] = {
12757 .mixers = { alc262_HP_BPC_WildWest_mixer,
12758 alc262_HP_BPC_WildWest_option_mixer },
12759 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12760 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12761 .dac_nids = alc262_dac_nids,
12763 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12764 .channel_mode = alc262_modes,
12765 .input_mux = &alc262_HP_D7000_capture_source,
12766 .unsol_event = alc262_hp_wildwest_unsol_event,
12767 .init_hook = alc262_hp_wildwest_automute,
12769 [ALC262_HP_TC_T5735] = {
12770 .mixers = { alc262_hp_t5735_mixer },
12771 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12772 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12773 .dac_nids = alc262_dac_nids,
12775 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12776 .channel_mode = alc262_modes,
12777 .input_mux = &alc262_capture_source,
12778 .unsol_event = alc_sku_unsol_event,
12779 .setup = alc262_hp_t5735_setup,
12780 .init_hook = alc_inithook,
12782 [ALC262_HP_RP5700] = {
12783 .mixers = { alc262_hp_rp5700_mixer },
12784 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12785 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12786 .dac_nids = alc262_dac_nids,
12787 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12788 .channel_mode = alc262_modes,
12789 .input_mux = &alc262_hp_rp5700_capture_source,
12791 [ALC262_BENQ_ED8] = {
12792 .mixers = { alc262_base_mixer },
12793 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12794 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12795 .dac_nids = alc262_dac_nids,
12797 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12798 .channel_mode = alc262_modes,
12799 .input_mux = &alc262_capture_source,
12801 [ALC262_SONY_ASSAMD] = {
12802 .mixers = { alc262_sony_mixer },
12803 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12804 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12805 .dac_nids = alc262_dac_nids,
12807 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12808 .channel_mode = alc262_modes,
12809 .input_mux = &alc262_capture_source,
12810 .unsol_event = alc262_hippo_unsol_event,
12811 .setup = alc262_hippo_setup,
12812 .init_hook = alc262_hippo_automute,
12814 [ALC262_BENQ_T31] = {
12815 .mixers = { alc262_benq_t31_mixer },
12816 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12817 alc_hp15_unsol_verbs },
12818 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12819 .dac_nids = alc262_dac_nids,
12821 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12822 .channel_mode = alc262_modes,
12823 .input_mux = &alc262_capture_source,
12824 .unsol_event = alc262_hippo_unsol_event,
12825 .setup = alc262_hippo_setup,
12826 .init_hook = alc262_hippo_automute,
12829 .mixers = { alc262_ultra_mixer },
12830 .cap_mixer = alc262_ultra_capture_mixer,
12831 .init_verbs = { alc262_ultra_verbs },
12832 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12833 .dac_nids = alc262_dac_nids,
12834 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12835 .channel_mode = alc262_modes,
12836 .input_mux = &alc262_ultra_capture_source,
12837 .adc_nids = alc262_adc_nids, /* ADC0 */
12838 .capsrc_nids = alc262_capsrc_nids,
12839 .num_adc_nids = 1, /* single ADC */
12840 .unsol_event = alc262_ultra_unsol_event,
12841 .init_hook = alc262_ultra_automute,
12843 [ALC262_LENOVO_3000] = {
12844 .mixers = { alc262_lenovo_3000_mixer },
12845 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12846 alc262_lenovo_3000_unsol_verbs,
12847 alc262_lenovo_3000_init_verbs },
12848 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12849 .dac_nids = alc262_dac_nids,
12851 .dig_out_nid = ALC262_DIGOUT_NID,
12852 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12853 .channel_mode = alc262_modes,
12854 .input_mux = &alc262_fujitsu_capture_source,
12855 .unsol_event = alc262_lenovo_3000_unsol_event,
12858 .mixers = { alc262_nec_mixer },
12859 .init_verbs = { alc262_nec_verbs },
12860 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12861 .dac_nids = alc262_dac_nids,
12863 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12864 .channel_mode = alc262_modes,
12865 .input_mux = &alc262_capture_source,
12867 [ALC262_TOSHIBA_S06] = {
12868 .mixers = { alc262_toshiba_s06_mixer },
12869 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12870 alc262_eapd_verbs },
12871 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12872 .capsrc_nids = alc262_dmic_capsrc_nids,
12873 .dac_nids = alc262_dac_nids,
12874 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12875 .num_adc_nids = 1, /* single ADC */
12876 .dig_out_nid = ALC262_DIGOUT_NID,
12877 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12878 .channel_mode = alc262_modes,
12879 .unsol_event = alc_sku_unsol_event,
12880 .setup = alc262_toshiba_s06_setup,
12881 .init_hook = alc_inithook,
12883 [ALC262_TOSHIBA_RX1] = {
12884 .mixers = { alc262_toshiba_rx1_mixer },
12885 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12886 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12887 .dac_nids = alc262_dac_nids,
12889 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12890 .channel_mode = alc262_modes,
12891 .input_mux = &alc262_capture_source,
12892 .unsol_event = alc262_hippo_unsol_event,
12893 .setup = alc262_hippo_setup,
12894 .init_hook = alc262_hippo_automute,
12897 .mixers = { alc262_tyan_mixer },
12898 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12899 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12900 .dac_nids = alc262_dac_nids,
12902 .dig_out_nid = ALC262_DIGOUT_NID,
12903 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12904 .channel_mode = alc262_modes,
12905 .input_mux = &alc262_capture_source,
12906 .unsol_event = alc_automute_amp_unsol_event,
12907 .setup = alc262_tyan_setup,
12908 .init_hook = alc_automute_amp,
12912 static int patch_alc262(struct hda_codec *codec)
12914 struct alc_spec *spec;
12918 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12922 codec->spec = spec;
12924 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12929 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12930 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12931 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12932 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12935 alc_auto_parse_customize_define(codec);
12937 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12939 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12943 if (board_config < 0) {
12944 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12946 board_config = ALC262_AUTO;
12949 if (board_config == ALC262_AUTO) {
12950 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12951 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12954 if (board_config == ALC262_AUTO) {
12955 /* automatic parse from the BIOS config */
12956 err = alc262_parse_auto_config(codec);
12962 "hda_codec: Cannot set up configuration "
12963 "from BIOS. Using base mode...\n");
12964 board_config = ALC262_BASIC;
12968 if (!spec->no_analog && has_cdefine_beep(codec)) {
12969 err = snd_hda_attach_beep_device(codec, 0x1);
12976 if (board_config != ALC262_AUTO)
12977 setup_preset(codec, &alc262_presets[board_config]);
12979 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12980 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12982 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12983 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12985 if (!spec->adc_nids && spec->input_mux) {
12987 /* check whether the digital-mic has to be supported */
12988 for (i = 0; i < spec->input_mux->num_items; i++) {
12989 if (spec->input_mux->items[i].index >= 9)
12992 if (i < spec->input_mux->num_items) {
12993 /* use only ADC0 */
12994 spec->adc_nids = alc262_dmic_adc_nids;
12995 spec->num_adc_nids = 1;
12996 spec->capsrc_nids = alc262_dmic_capsrc_nids;
12998 /* all analog inputs */
12999 /* check whether NID 0x07 is valid */
13000 unsigned int wcap = get_wcaps(codec, 0x07);
13003 wcap = get_wcaps_type(wcap);
13004 if (wcap != AC_WID_AUD_IN) {
13005 spec->adc_nids = alc262_adc_nids_alt;
13006 spec->num_adc_nids =
13007 ARRAY_SIZE(alc262_adc_nids_alt);
13008 spec->capsrc_nids = alc262_capsrc_nids_alt;
13010 spec->adc_nids = alc262_adc_nids;
13011 spec->num_adc_nids =
13012 ARRAY_SIZE(alc262_adc_nids);
13013 spec->capsrc_nids = alc262_capsrc_nids;
13017 if (!spec->cap_mixer && !spec->no_analog)
13018 set_capture_mixer(codec);
13019 if (!spec->no_analog && has_cdefine_beep(codec))
13020 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13022 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13024 spec->vmaster_nid = 0x0c;
13026 codec->patch_ops = alc_patch_ops;
13027 if (board_config == ALC262_AUTO)
13028 spec->init_hook = alc262_auto_init;
13029 spec->shutup = alc_eapd_shutup;
13031 alc_init_jacks(codec);
13032 #ifdef CONFIG_SND_HDA_POWER_SAVE
13033 if (!spec->loopback.amplist)
13034 spec->loopback.amplist = alc262_loopbacks;
13041 * ALC268 channel source setting (2 channel)
13043 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13044 #define alc268_modes alc260_modes
13046 static hda_nid_t alc268_dac_nids[2] = {
13051 static hda_nid_t alc268_adc_nids[2] = {
13056 static hda_nid_t alc268_adc_nids_alt[1] = {
13061 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13063 static struct snd_kcontrol_new alc268_base_mixer[] = {
13064 /* output mixer control */
13065 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13066 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13067 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13068 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13069 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13070 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13071 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13075 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13076 /* output mixer control */
13077 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13078 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13079 ALC262_HIPPO_MASTER_SWITCH,
13080 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13081 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13082 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13086 /* bind Beep switches of both NID 0x0f and 0x10 */
13087 static struct hda_bind_ctls alc268_bind_beep_sw = {
13088 .ops = &snd_hda_bind_sw,
13090 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13091 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13096 static struct snd_kcontrol_new alc268_beep_mixer[] = {
13097 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13098 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13102 static struct hda_verb alc268_eapd_verbs[] = {
13103 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13104 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13108 /* Toshiba specific */
13109 static struct hda_verb alc268_toshiba_verbs[] = {
13110 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13114 /* Acer specific */
13115 /* bind volumes of both NID 0x02 and 0x03 */
13116 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13117 .ops = &snd_hda_bind_vol,
13119 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13120 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13125 /* mute/unmute internal speaker according to the hp jack and mute state */
13126 static void alc268_acer_automute(struct hda_codec *codec, int force)
13128 struct alc_spec *spec = codec->spec;
13131 if (force || !spec->sense_updated) {
13132 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
13133 spec->sense_updated = 1;
13135 if (spec->jack_present)
13136 mute = HDA_AMP_MUTE; /* mute internal speaker */
13137 else /* unmute internal speaker if necessary */
13138 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13139 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13140 HDA_AMP_MUTE, mute);
13144 /* bind hp and internal speaker mute (with plug check) */
13145 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13146 struct snd_ctl_elem_value *ucontrol)
13148 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13149 long *valp = ucontrol->value.integer.value;
13152 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
13154 alc268_acer_automute(codec, 0);
13158 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13159 /* output mixer control */
13160 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13162 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13163 .name = "Master Playback Switch",
13164 .subdevice = HDA_SUBDEV_AMP_FLAG,
13165 .info = snd_hda_mixer_amp_switch_info,
13166 .get = snd_hda_mixer_amp_switch_get,
13167 .put = alc268_acer_master_sw_put,
13168 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13170 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13174 static struct snd_kcontrol_new alc268_acer_mixer[] = {
13175 /* output mixer control */
13176 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13178 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13179 .name = "Master Playback Switch",
13180 .subdevice = HDA_SUBDEV_AMP_FLAG,
13181 .info = snd_hda_mixer_amp_switch_info,
13182 .get = snd_hda_mixer_amp_switch_get,
13183 .put = alc268_acer_master_sw_put,
13184 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13186 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13187 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13188 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13192 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13193 /* output mixer control */
13194 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13197 .name = "Master Playback Switch",
13198 .subdevice = HDA_SUBDEV_AMP_FLAG,
13199 .info = snd_hda_mixer_amp_switch_info,
13200 .get = snd_hda_mixer_amp_switch_get,
13201 .put = alc268_acer_master_sw_put,
13202 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13204 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13205 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13209 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13210 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13212 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13213 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13214 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13219 static struct hda_verb alc268_acer_verbs[] = {
13220 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13221 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13222 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13223 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13225 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13226 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13230 /* unsolicited event for HP jack sensing */
13231 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
13232 #define alc268_toshiba_setup alc262_hippo_setup
13233 #define alc268_toshiba_automute alc262_hippo_automute
13235 static void alc268_acer_unsol_event(struct hda_codec *codec,
13238 if ((res >> 26) != ALC880_HP_EVENT)
13240 alc268_acer_automute(codec, 1);
13243 static void alc268_acer_init_hook(struct hda_codec *codec)
13245 alc268_acer_automute(codec, 1);
13248 /* toggle speaker-output according to the hp-jack state */
13249 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13251 unsigned int present;
13252 unsigned char bits;
13254 present = snd_hda_jack_detect(codec, 0x15);
13255 bits = present ? HDA_AMP_MUTE : 0;
13256 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
13257 HDA_AMP_MUTE, bits);
13258 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
13259 HDA_AMP_MUTE, bits);
13262 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13265 switch (res >> 26) {
13266 case ALC880_HP_EVENT:
13267 alc268_aspire_one_speaker_automute(codec);
13269 case ALC880_MIC_EVENT:
13270 alc_mic_automute(codec);
13275 static void alc268_acer_lc_setup(struct hda_codec *codec)
13277 struct alc_spec *spec = codec->spec;
13278 spec->ext_mic.pin = 0x18;
13279 spec->ext_mic.mux_idx = 0;
13280 spec->int_mic.pin = 0x12;
13281 spec->int_mic.mux_idx = 6;
13282 spec->auto_mic = 1;
13285 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13287 alc268_aspire_one_speaker_automute(codec);
13288 alc_mic_automute(codec);
13291 static struct snd_kcontrol_new alc268_dell_mixer[] = {
13292 /* output mixer control */
13293 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13294 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13295 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13296 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13297 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13298 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13302 static struct hda_verb alc268_dell_verbs[] = {
13303 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13304 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13305 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13306 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13310 /* mute/unmute internal speaker according to the hp jack and mute state */
13311 static void alc268_dell_setup(struct hda_codec *codec)
13313 struct alc_spec *spec = codec->spec;
13315 spec->autocfg.hp_pins[0] = 0x15;
13316 spec->autocfg.speaker_pins[0] = 0x14;
13317 spec->ext_mic.pin = 0x18;
13318 spec->ext_mic.mux_idx = 0;
13319 spec->int_mic.pin = 0x19;
13320 spec->int_mic.mux_idx = 1;
13321 spec->auto_mic = 1;
13324 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13325 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13326 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13327 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13329 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13330 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13331 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13332 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13336 static struct hda_verb alc267_quanta_il1_verbs[] = {
13337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13338 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13342 static void alc267_quanta_il1_setup(struct hda_codec *codec)
13344 struct alc_spec *spec = codec->spec;
13345 spec->autocfg.hp_pins[0] = 0x15;
13346 spec->autocfg.speaker_pins[0] = 0x14;
13347 spec->ext_mic.pin = 0x18;
13348 spec->ext_mic.mux_idx = 0;
13349 spec->int_mic.pin = 0x19;
13350 spec->int_mic.mux_idx = 1;
13351 spec->auto_mic = 1;
13355 * generic initialization of ADC, input mixers and output mixers
13357 static struct hda_verb alc268_base_init_verbs[] = {
13358 /* Unmute DAC0-1 and set vol = 0 */
13359 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13360 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13363 * Set up output mixers (0x0c - 0x0e)
13365 /* set vol=0 to output mixers */
13366 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13367 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13369 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13370 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13374 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13376 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13377 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13378 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13379 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13381 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13382 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13383 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13384 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13385 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13387 /* set PCBEEP vol = 0, mute connections */
13388 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13390 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13392 /* Unmute Selector 23h,24h and set the default input to mic-in */
13394 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13395 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13396 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13397 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13403 * generic initialization of ADC, input mixers and output mixers
13405 static struct hda_verb alc268_volume_init_verbs[] = {
13406 /* set output DAC */
13407 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13408 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13410 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13411 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13412 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13413 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13414 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13416 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13417 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13418 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13420 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13421 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13423 /* set PCBEEP vol = 0, mute connections */
13424 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13426 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13431 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13432 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13433 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13437 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13438 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13439 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13444 static struct snd_kcontrol_new alc268_capture_mixer[] = {
13445 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13446 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13447 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13448 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13453 static struct hda_input_mux alc268_capture_source = {
13457 { "Front Mic", 0x1 },
13463 static struct hda_input_mux alc268_acer_capture_source = {
13467 { "Internal Mic", 0x1 },
13472 static struct hda_input_mux alc268_acer_dmic_capture_source = {
13476 { "Internal Mic", 0x6 },
13481 #ifdef CONFIG_SND_DEBUG
13482 static struct snd_kcontrol_new alc268_test_mixer[] = {
13483 /* Volume widgets */
13484 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13485 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13486 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13487 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13488 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13489 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13490 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13491 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13492 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13493 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13494 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13495 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13496 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13497 /* The below appears problematic on some hardwares */
13498 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13499 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13500 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13501 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13502 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13504 /* Modes for retasking pin widgets */
13505 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13506 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13507 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13508 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13510 /* Controls for GPIO pins, assuming they are configured as outputs */
13511 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13512 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13513 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13514 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13516 /* Switches to allow the digital SPDIF output pin to be enabled.
13517 * The ALC268 does not have an SPDIF input.
13519 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13521 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13522 * this output to turn on an external amplifier.
13524 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13525 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13531 /* create input playback/capture controls for the given pin */
13532 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13533 const char *ctlname, int idx)
13544 case 0x1a: /* ALC259/269 only */
13545 case 0x1b: /* ALC259/269 only */
13546 case 0x21: /* ALC269vb has this pin, too */
13550 snd_printd(KERN_WARNING "hda_codec: "
13551 "ignoring pin 0x%x as unknown\n", nid);
13554 if (spec->multiout.dac_nids[0] != dac &&
13555 spec->multiout.dac_nids[1] != dac) {
13556 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13557 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13561 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13565 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13566 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13568 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13569 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13575 /* add playback controls from the parsed DAC table */
13576 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13577 const struct auto_pin_cfg *cfg)
13582 spec->multiout.dac_nids = spec->private_dac_nids;
13584 nid = cfg->line_out_pins[0];
13587 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13591 err = alc268_new_analog_output(spec, nid, name, 0);
13596 nid = cfg->speaker_pins[0];
13598 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13599 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13603 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13607 nid = cfg->hp_pins[0];
13609 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13614 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13616 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13617 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13624 /* create playback/capture controls for input pins */
13625 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13626 const struct auto_pin_cfg *cfg)
13628 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13631 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13632 hda_nid_t nid, int pin_type)
13636 alc_set_pin_output(codec, nid, pin_type);
13637 if (nid == 0x14 || nid == 0x16)
13641 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13644 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13646 struct alc_spec *spec = codec->spec;
13649 for (i = 0; i < spec->autocfg.line_outs; i++) {
13650 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13651 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13652 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13656 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13658 struct alc_spec *spec = codec->spec;
13662 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13663 pin = spec->autocfg.hp_pins[i];
13664 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13666 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13667 pin = spec->autocfg.speaker_pins[i];
13668 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13670 if (spec->autocfg.mono_out_pin)
13671 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13672 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13675 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13677 struct alc_spec *spec = codec->spec;
13678 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13679 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13680 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13681 unsigned int dac_vol1, dac_vol2;
13683 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13684 snd_hda_codec_write(codec, speaker_nid, 0,
13685 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13686 /* mute mixer inputs from 0x1d */
13687 snd_hda_codec_write(codec, 0x0f, 0,
13688 AC_VERB_SET_AMP_GAIN_MUTE,
13690 snd_hda_codec_write(codec, 0x10, 0,
13691 AC_VERB_SET_AMP_GAIN_MUTE,
13694 /* unmute mixer inputs from 0x1d */
13695 snd_hda_codec_write(codec, 0x0f, 0,
13696 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13697 snd_hda_codec_write(codec, 0x10, 0,
13698 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13701 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13702 if (line_nid == 0x14)
13703 dac_vol2 = AMP_OUT_ZERO;
13704 else if (line_nid == 0x15)
13705 dac_vol1 = AMP_OUT_ZERO;
13706 if (hp_nid == 0x14)
13707 dac_vol2 = AMP_OUT_ZERO;
13708 else if (hp_nid == 0x15)
13709 dac_vol1 = AMP_OUT_ZERO;
13710 if (line_nid != 0x16 || hp_nid != 0x16 ||
13711 spec->autocfg.line_out_pins[1] != 0x16 ||
13712 spec->autocfg.line_out_pins[2] != 0x16)
13713 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13715 snd_hda_codec_write(codec, 0x02, 0,
13716 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13717 snd_hda_codec_write(codec, 0x03, 0,
13718 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13721 /* pcm configuration: identical with ALC880 */
13722 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13723 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13724 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13725 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13728 * BIOS auto configuration
13730 static int alc268_parse_auto_config(struct hda_codec *codec)
13732 struct alc_spec *spec = codec->spec;
13734 static hda_nid_t alc268_ignore[] = { 0 };
13736 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13740 if (!spec->autocfg.line_outs) {
13741 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13742 spec->multiout.max_channels = 2;
13743 spec->no_analog = 1;
13746 return 0; /* can't find valid BIOS pin config */
13748 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13751 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13755 spec->multiout.max_channels = 2;
13758 /* digital only support output */
13759 alc_auto_parse_digital(codec);
13760 if (spec->kctls.list)
13761 add_mixer(spec, spec->kctls.list);
13763 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13764 add_mixer(spec, alc268_beep_mixer);
13766 add_verb(spec, alc268_volume_init_verbs);
13767 spec->num_mux_defs = 2;
13768 spec->input_mux = &spec->private_imux[0];
13770 err = alc_auto_add_mic_boost(codec);
13774 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13779 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13780 #define alc268_auto_init_input_src alc882_auto_init_input_src
13782 /* init callback for auto-configuration model -- overriding the default init */
13783 static void alc268_auto_init(struct hda_codec *codec)
13785 struct alc_spec *spec = codec->spec;
13786 alc268_auto_init_multi_out(codec);
13787 alc268_auto_init_hp_out(codec);
13788 alc268_auto_init_mono_speaker_out(codec);
13789 alc268_auto_init_analog_input(codec);
13790 alc268_auto_init_input_src(codec);
13791 alc_auto_init_digital(codec);
13792 if (spec->unsol_event)
13793 alc_inithook(codec);
13797 * configuration and preset
13799 static const char * const alc268_models[ALC268_MODEL_LAST] = {
13800 [ALC267_QUANTA_IL1] = "quanta-il1",
13801 [ALC268_3ST] = "3stack",
13802 [ALC268_TOSHIBA] = "toshiba",
13803 [ALC268_ACER] = "acer",
13804 [ALC268_ACER_DMIC] = "acer-dmic",
13805 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13806 [ALC268_DELL] = "dell",
13807 [ALC268_ZEPTO] = "zepto",
13808 #ifdef CONFIG_SND_DEBUG
13809 [ALC268_TEST] = "test",
13811 [ALC268_AUTO] = "auto",
13814 static struct snd_pci_quirk alc268_cfg_tbl[] = {
13815 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13816 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13817 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13818 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13819 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13820 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13821 ALC268_ACER_ASPIRE_ONE),
13822 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13823 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13824 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13825 /* almost compatible with toshiba but with optional digital outs;
13826 * auto-probing seems working fine
13828 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13830 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13831 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13832 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13833 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13834 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13838 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13839 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13840 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13841 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13842 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13847 static struct alc_config_preset alc268_presets[] = {
13848 [ALC267_QUANTA_IL1] = {
13849 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13850 alc268_capture_nosrc_mixer },
13851 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13852 alc267_quanta_il1_verbs },
13853 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13854 .dac_nids = alc268_dac_nids,
13855 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13856 .adc_nids = alc268_adc_nids_alt,
13858 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13859 .channel_mode = alc268_modes,
13860 .unsol_event = alc_sku_unsol_event,
13861 .setup = alc267_quanta_il1_setup,
13862 .init_hook = alc_inithook,
13865 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13866 alc268_beep_mixer },
13867 .init_verbs = { alc268_base_init_verbs },
13868 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13869 .dac_nids = alc268_dac_nids,
13870 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13871 .adc_nids = alc268_adc_nids_alt,
13872 .capsrc_nids = alc268_capsrc_nids,
13874 .dig_out_nid = ALC268_DIGOUT_NID,
13875 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13876 .channel_mode = alc268_modes,
13877 .input_mux = &alc268_capture_source,
13879 [ALC268_TOSHIBA] = {
13880 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13881 alc268_beep_mixer },
13882 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13883 alc268_toshiba_verbs },
13884 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13885 .dac_nids = alc268_dac_nids,
13886 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13887 .adc_nids = alc268_adc_nids_alt,
13888 .capsrc_nids = alc268_capsrc_nids,
13890 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13891 .channel_mode = alc268_modes,
13892 .input_mux = &alc268_capture_source,
13893 .unsol_event = alc268_toshiba_unsol_event,
13894 .setup = alc268_toshiba_setup,
13895 .init_hook = alc268_toshiba_automute,
13898 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13899 alc268_beep_mixer },
13900 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13901 alc268_acer_verbs },
13902 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13903 .dac_nids = alc268_dac_nids,
13904 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13905 .adc_nids = alc268_adc_nids_alt,
13906 .capsrc_nids = alc268_capsrc_nids,
13908 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13909 .channel_mode = alc268_modes,
13910 .input_mux = &alc268_acer_capture_source,
13911 .unsol_event = alc268_acer_unsol_event,
13912 .init_hook = alc268_acer_init_hook,
13914 [ALC268_ACER_DMIC] = {
13915 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13916 alc268_beep_mixer },
13917 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13918 alc268_acer_verbs },
13919 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13920 .dac_nids = alc268_dac_nids,
13921 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13922 .adc_nids = alc268_adc_nids_alt,
13923 .capsrc_nids = alc268_capsrc_nids,
13925 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13926 .channel_mode = alc268_modes,
13927 .input_mux = &alc268_acer_dmic_capture_source,
13928 .unsol_event = alc268_acer_unsol_event,
13929 .init_hook = alc268_acer_init_hook,
13931 [ALC268_ACER_ASPIRE_ONE] = {
13932 .mixers = { alc268_acer_aspire_one_mixer,
13934 alc268_capture_nosrc_mixer },
13935 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13936 alc268_acer_aspire_one_verbs },
13937 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13938 .dac_nids = alc268_dac_nids,
13939 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13940 .adc_nids = alc268_adc_nids_alt,
13941 .capsrc_nids = alc268_capsrc_nids,
13943 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13944 .channel_mode = alc268_modes,
13945 .unsol_event = alc268_acer_lc_unsol_event,
13946 .setup = alc268_acer_lc_setup,
13947 .init_hook = alc268_acer_lc_init_hook,
13950 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13951 alc268_capture_nosrc_mixer },
13952 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13953 alc268_dell_verbs },
13954 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13955 .dac_nids = alc268_dac_nids,
13956 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13957 .adc_nids = alc268_adc_nids_alt,
13958 .capsrc_nids = alc268_capsrc_nids,
13960 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13961 .channel_mode = alc268_modes,
13962 .unsol_event = alc_sku_unsol_event,
13963 .setup = alc268_dell_setup,
13964 .init_hook = alc_inithook,
13967 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13968 alc268_beep_mixer },
13969 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13970 alc268_toshiba_verbs },
13971 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13972 .dac_nids = alc268_dac_nids,
13973 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13974 .adc_nids = alc268_adc_nids_alt,
13975 .capsrc_nids = alc268_capsrc_nids,
13977 .dig_out_nid = ALC268_DIGOUT_NID,
13978 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13979 .channel_mode = alc268_modes,
13980 .input_mux = &alc268_capture_source,
13981 .setup = alc268_toshiba_setup,
13982 .init_hook = alc268_toshiba_automute,
13984 #ifdef CONFIG_SND_DEBUG
13986 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13987 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13988 alc268_volume_init_verbs },
13989 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13990 .dac_nids = alc268_dac_nids,
13991 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13992 .adc_nids = alc268_adc_nids_alt,
13993 .capsrc_nids = alc268_capsrc_nids,
13995 .dig_out_nid = ALC268_DIGOUT_NID,
13996 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13997 .channel_mode = alc268_modes,
13998 .input_mux = &alc268_capture_source,
14003 static int patch_alc268(struct hda_codec *codec)
14005 struct alc_spec *spec;
14007 int i, has_beep, err;
14009 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14013 codec->spec = spec;
14015 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14019 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14020 board_config = snd_hda_check_board_codec_sid_config(codec,
14021 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14023 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
14024 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14026 board_config = ALC268_AUTO;
14029 if (board_config == ALC268_AUTO) {
14030 /* automatic parse from the BIOS config */
14031 err = alc268_parse_auto_config(codec);
14037 "hda_codec: Cannot set up configuration "
14038 "from BIOS. Using base mode...\n");
14039 board_config = ALC268_3ST;
14043 if (board_config != ALC268_AUTO)
14044 setup_preset(codec, &alc268_presets[board_config]);
14046 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14047 spec->stream_analog_capture = &alc268_pcm_analog_capture;
14048 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14050 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14053 for (i = 0; i < spec->num_mixers; i++) {
14054 if (spec->mixers[i] == alc268_beep_mixer) {
14061 err = snd_hda_attach_beep_device(codec, 0x1);
14066 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14067 /* override the amp caps for beep generator */
14068 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14069 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14070 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14071 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14072 (0 << AC_AMPCAP_MUTE_SHIFT));
14075 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14076 /* check whether NID 0x07 is valid */
14077 unsigned int wcap = get_wcaps(codec, 0x07);
14079 spec->capsrc_nids = alc268_capsrc_nids;
14081 wcap = get_wcaps_type(wcap);
14082 if (spec->auto_mic ||
14083 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14084 spec->adc_nids = alc268_adc_nids_alt;
14085 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14086 if (spec->auto_mic)
14087 fixup_automic_adc(codec);
14088 if (spec->auto_mic || spec->input_mux->num_items == 1)
14089 add_mixer(spec, alc268_capture_nosrc_mixer);
14091 add_mixer(spec, alc268_capture_alt_mixer);
14093 spec->adc_nids = alc268_adc_nids;
14094 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14095 add_mixer(spec, alc268_capture_mixer);
14099 spec->vmaster_nid = 0x02;
14101 codec->patch_ops = alc_patch_ops;
14102 if (board_config == ALC268_AUTO)
14103 spec->init_hook = alc268_auto_init;
14104 spec->shutup = alc_eapd_shutup;
14106 alc_init_jacks(codec);
14112 * ALC269 channel source setting (2 channel)
14114 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14116 #define alc269_dac_nids alc260_dac_nids
14118 static hda_nid_t alc269_adc_nids[1] = {
14123 static hda_nid_t alc269_capsrc_nids[1] = {
14127 static hda_nid_t alc269vb_adc_nids[1] = {
14132 static hda_nid_t alc269vb_capsrc_nids[1] = {
14136 static hda_nid_t alc269_adc_candidates[] = {
14137 0x08, 0x09, 0x07, 0x11,
14140 #define alc269_modes alc260_modes
14141 #define alc269_capture_source alc880_lg_lw_capture_source
14143 static struct snd_kcontrol_new alc269_base_mixer[] = {
14144 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14145 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14150 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14151 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14152 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14153 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14155 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14159 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14160 /* output mixer control */
14161 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14164 .name = "Master Playback Switch",
14165 .subdevice = HDA_SUBDEV_AMP_FLAG,
14166 .info = snd_hda_mixer_amp_switch_info,
14167 .get = snd_hda_mixer_amp_switch_get,
14168 .put = alc268_acer_master_sw_put,
14169 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14171 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14173 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14174 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14175 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14176 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14180 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14181 /* output mixer control */
14182 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14185 .name = "Master Playback Switch",
14186 .subdevice = HDA_SUBDEV_AMP_FLAG,
14187 .info = snd_hda_mixer_amp_switch_info,
14188 .get = snd_hda_mixer_amp_switch_get,
14189 .put = alc268_acer_master_sw_put,
14190 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14192 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14193 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14194 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14195 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14196 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14197 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14198 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14199 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14200 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14204 static struct snd_kcontrol_new alc269_laptop_mixer[] = {
14205 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14206 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14207 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14208 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14212 static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14213 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14214 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14216 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14220 static struct snd_kcontrol_new alc269_asus_mixer[] = {
14221 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14222 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14226 /* capture mixer elements */
14227 static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14228 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14229 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14230 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14231 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14235 static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14236 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14237 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14238 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14242 static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14243 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14244 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14245 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14246 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14250 static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14251 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14252 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14253 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14258 #define alc269_fujitsu_mixer alc269_laptop_mixer
14260 static struct hda_verb alc269_quanta_fl1_verbs[] = {
14261 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14262 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14264 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14265 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14266 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14270 static struct hda_verb alc269_lifebook_verbs[] = {
14271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14272 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14273 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14274 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14275 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14277 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14278 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14279 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14280 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14284 /* toggle speaker-output according to the hp-jack state */
14285 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14287 unsigned int present;
14288 unsigned char bits;
14290 present = snd_hda_jack_detect(codec, 0x15);
14291 bits = present ? HDA_AMP_MUTE : 0;
14292 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14293 HDA_AMP_MUTE, bits);
14294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14295 HDA_AMP_MUTE, bits);
14297 snd_hda_codec_write(codec, 0x20, 0,
14298 AC_VERB_SET_COEF_INDEX, 0x0c);
14299 snd_hda_codec_write(codec, 0x20, 0,
14300 AC_VERB_SET_PROC_COEF, 0x680);
14302 snd_hda_codec_write(codec, 0x20, 0,
14303 AC_VERB_SET_COEF_INDEX, 0x0c);
14304 snd_hda_codec_write(codec, 0x20, 0,
14305 AC_VERB_SET_PROC_COEF, 0x480);
14308 /* toggle speaker-output according to the hp-jacks state */
14309 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14311 unsigned int present;
14312 unsigned char bits;
14314 /* Check laptop headphone socket */
14315 present = snd_hda_jack_detect(codec, 0x15);
14317 /* Check port replicator headphone socket */
14318 present |= snd_hda_jack_detect(codec, 0x1a);
14320 bits = present ? HDA_AMP_MUTE : 0;
14321 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14322 HDA_AMP_MUTE, bits);
14323 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14324 HDA_AMP_MUTE, bits);
14326 snd_hda_codec_write(codec, 0x20, 0,
14327 AC_VERB_SET_COEF_INDEX, 0x0c);
14328 snd_hda_codec_write(codec, 0x20, 0,
14329 AC_VERB_SET_PROC_COEF, 0x680);
14331 snd_hda_codec_write(codec, 0x20, 0,
14332 AC_VERB_SET_COEF_INDEX, 0x0c);
14333 snd_hda_codec_write(codec, 0x20, 0,
14334 AC_VERB_SET_PROC_COEF, 0x480);
14337 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14339 unsigned int present_laptop;
14340 unsigned int present_dock;
14342 present_laptop = snd_hda_jack_detect(codec, 0x18);
14343 present_dock = snd_hda_jack_detect(codec, 0x1b);
14345 /* Laptop mic port overrides dock mic port, design decision */
14347 snd_hda_codec_write(codec, 0x23, 0,
14348 AC_VERB_SET_CONNECT_SEL, 0x3);
14349 if (present_laptop)
14350 snd_hda_codec_write(codec, 0x23, 0,
14351 AC_VERB_SET_CONNECT_SEL, 0x0);
14352 if (!present_dock && !present_laptop)
14353 snd_hda_codec_write(codec, 0x23, 0,
14354 AC_VERB_SET_CONNECT_SEL, 0x1);
14357 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14360 switch (res >> 26) {
14361 case ALC880_HP_EVENT:
14362 alc269_quanta_fl1_speaker_automute(codec);
14364 case ALC880_MIC_EVENT:
14365 alc_mic_automute(codec);
14370 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14373 if ((res >> 26) == ALC880_HP_EVENT)
14374 alc269_lifebook_speaker_automute(codec);
14375 if ((res >> 26) == ALC880_MIC_EVENT)
14376 alc269_lifebook_mic_autoswitch(codec);
14379 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14381 struct alc_spec *spec = codec->spec;
14382 spec->autocfg.hp_pins[0] = 0x15;
14383 spec->autocfg.speaker_pins[0] = 0x14;
14384 spec->ext_mic.pin = 0x18;
14385 spec->ext_mic.mux_idx = 0;
14386 spec->int_mic.pin = 0x19;
14387 spec->int_mic.mux_idx = 1;
14388 spec->auto_mic = 1;
14391 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14393 alc269_quanta_fl1_speaker_automute(codec);
14394 alc_mic_automute(codec);
14397 static void alc269_lifebook_init_hook(struct hda_codec *codec)
14399 alc269_lifebook_speaker_automute(codec);
14400 alc269_lifebook_mic_autoswitch(codec);
14403 static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14404 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14405 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14406 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14407 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14408 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14409 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14410 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14414 static struct hda_verb alc269_laptop_amic_init_verbs[] = {
14415 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14416 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14417 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14418 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14419 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14420 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14424 static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14425 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14426 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14427 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14428 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14429 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14430 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14431 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14435 static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14436 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14437 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14438 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14439 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14440 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14441 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14442 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14446 static struct hda_verb alc271_acer_dmic_verbs[] = {
14447 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14448 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14449 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14450 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14451 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14452 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14453 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14454 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14455 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14456 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14460 /* toggle speaker-output according to the hp-jack state */
14461 static void alc269_speaker_automute(struct hda_codec *codec)
14463 struct alc_spec *spec = codec->spec;
14464 unsigned int nid = spec->autocfg.hp_pins[0];
14465 unsigned int present;
14466 unsigned char bits;
14468 present = snd_hda_jack_detect(codec, nid);
14469 bits = present ? HDA_AMP_MUTE : 0;
14470 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14471 HDA_AMP_MUTE, bits);
14472 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14473 HDA_AMP_MUTE, bits);
14474 snd_hda_input_jack_report(codec, nid);
14477 /* unsolicited event for HP jack sensing */
14478 static void alc269_laptop_unsol_event(struct hda_codec *codec,
14481 switch (res >> 26) {
14482 case ALC880_HP_EVENT:
14483 alc269_speaker_automute(codec);
14485 case ALC880_MIC_EVENT:
14486 alc_mic_automute(codec);
14491 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14493 struct alc_spec *spec = codec->spec;
14494 spec->autocfg.hp_pins[0] = 0x15;
14495 spec->autocfg.speaker_pins[0] = 0x14;
14496 spec->ext_mic.pin = 0x18;
14497 spec->ext_mic.mux_idx = 0;
14498 spec->int_mic.pin = 0x19;
14499 spec->int_mic.mux_idx = 1;
14500 spec->auto_mic = 1;
14503 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14505 struct alc_spec *spec = codec->spec;
14506 spec->autocfg.hp_pins[0] = 0x15;
14507 spec->autocfg.speaker_pins[0] = 0x14;
14508 spec->ext_mic.pin = 0x18;
14509 spec->ext_mic.mux_idx = 0;
14510 spec->int_mic.pin = 0x12;
14511 spec->int_mic.mux_idx = 5;
14512 spec->auto_mic = 1;
14515 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14517 struct alc_spec *spec = codec->spec;
14518 spec->autocfg.hp_pins[0] = 0x21;
14519 spec->autocfg.speaker_pins[0] = 0x14;
14520 spec->ext_mic.pin = 0x18;
14521 spec->ext_mic.mux_idx = 0;
14522 spec->int_mic.pin = 0x19;
14523 spec->int_mic.mux_idx = 1;
14524 spec->auto_mic = 1;
14527 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14529 struct alc_spec *spec = codec->spec;
14530 spec->autocfg.hp_pins[0] = 0x21;
14531 spec->autocfg.speaker_pins[0] = 0x14;
14532 spec->ext_mic.pin = 0x18;
14533 spec->ext_mic.mux_idx = 0;
14534 spec->int_mic.pin = 0x12;
14535 spec->int_mic.mux_idx = 6;
14536 spec->auto_mic = 1;
14539 static void alc269_laptop_inithook(struct hda_codec *codec)
14541 alc269_speaker_automute(codec);
14542 alc_mic_automute(codec);
14546 * generic initialization of ADC, input mixers and output mixers
14548 static struct hda_verb alc269_init_verbs[] = {
14550 * Unmute ADC0 and set the default input to mic-in
14552 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14555 * Set up output mixers (0x02 - 0x03)
14557 /* set vol=0 to output mixers */
14558 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14559 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14561 /* set up input amps for analog loopback */
14562 /* Amp Indices: DAC = 0, mixer = 1 */
14563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14565 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14566 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14567 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14568 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14572 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14573 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14575 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14576 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14578 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14579 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14581 /* FIXME: use Mux-type input source selection */
14582 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14583 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14584 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14587 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14591 static struct hda_verb alc269vb_init_verbs[] = {
14593 * Unmute ADC0 and set the default input to mic-in
14595 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14598 * Set up output mixers (0x02 - 0x03)
14600 /* set vol=0 to output mixers */
14601 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14602 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14604 /* set up input amps for analog loopback */
14605 /* Amp Indices: DAC = 0, mixer = 1 */
14606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14608 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14609 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14610 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14611 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14613 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14614 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14615 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14616 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14617 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14618 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14619 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14621 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14622 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14624 /* FIXME: use Mux-type input source selection */
14625 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14626 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14627 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14630 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14634 #define alc269_auto_create_multi_out_ctls \
14635 alc268_auto_create_multi_out_ctls
14636 #define alc269_auto_create_input_ctls \
14637 alc268_auto_create_input_ctls
14639 #ifdef CONFIG_SND_HDA_POWER_SAVE
14640 #define alc269_loopbacks alc880_loopbacks
14643 /* pcm configuration: identical with ALC880 */
14644 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14645 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14646 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14647 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14649 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14653 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14654 /* NID is set in alc_build_pcms */
14656 .open = alc880_playback_pcm_open,
14657 .prepare = alc880_playback_pcm_prepare,
14658 .cleanup = alc880_playback_pcm_cleanup
14662 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14666 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14667 /* NID is set in alc_build_pcms */
14670 #ifdef CONFIG_SND_HDA_POWER_SAVE
14671 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14673 switch (codec->subsystem_id) {
14680 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14682 /* update mute-LED according to the speaker mute state */
14683 if (nid == 0x01 || nid == 0x14) {
14685 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14690 /* mic2 vref pin is used for mute LED control */
14691 snd_hda_codec_update_cache(codec, 0x19, 0,
14692 AC_VERB_SET_PIN_WIDGET_CONTROL,
14695 return alc_check_power_status(codec, nid);
14697 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14699 static int alc275_setup_dual_adc(struct hda_codec *codec)
14701 struct alc_spec *spec = codec->spec;
14703 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14705 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14706 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14707 if (spec->ext_mic.pin <= 0x12) {
14708 spec->private_adc_nids[0] = 0x08;
14709 spec->private_adc_nids[1] = 0x11;
14710 spec->private_capsrc_nids[0] = 0x23;
14711 spec->private_capsrc_nids[1] = 0x22;
14713 spec->private_adc_nids[0] = 0x11;
14714 spec->private_adc_nids[1] = 0x08;
14715 spec->private_capsrc_nids[0] = 0x22;
14716 spec->private_capsrc_nids[1] = 0x23;
14718 spec->adc_nids = spec->private_adc_nids;
14719 spec->capsrc_nids = spec->private_capsrc_nids;
14720 spec->num_adc_nids = 2;
14721 spec->dual_adc_switch = 1;
14722 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14723 spec->adc_nids[0], spec->adc_nids[1]);
14729 /* different alc269-variants */
14731 ALC269_TYPE_NORMAL,
14732 ALC269_TYPE_ALC258,
14733 ALC269_TYPE_ALC259,
14734 ALC269_TYPE_ALC269VB,
14735 ALC269_TYPE_ALC270,
14736 ALC269_TYPE_ALC271X,
14740 * BIOS auto configuration
14742 static int alc269_parse_auto_config(struct hda_codec *codec)
14744 struct alc_spec *spec = codec->spec;
14746 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14748 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14753 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14756 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14757 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14759 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14764 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14766 alc_auto_parse_digital(codec);
14768 if (spec->kctls.list)
14769 add_mixer(spec, spec->kctls.list);
14771 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14772 add_verb(spec, alc269vb_init_verbs);
14773 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14775 add_verb(spec, alc269_init_verbs);
14776 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14779 spec->num_mux_defs = 1;
14780 spec->input_mux = &spec->private_imux[0];
14782 if (!alc275_setup_dual_adc(codec))
14783 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14784 sizeof(alc269_adc_candidates));
14786 err = alc_auto_add_mic_boost(codec);
14790 if (!spec->cap_mixer && !spec->no_analog)
14791 set_capture_mixer(codec);
14796 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14797 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14798 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14799 #define alc269_auto_init_input_src alc882_auto_init_input_src
14802 /* init callback for auto-configuration model -- overriding the default init */
14803 static void alc269_auto_init(struct hda_codec *codec)
14805 struct alc_spec *spec = codec->spec;
14806 alc269_auto_init_multi_out(codec);
14807 alc269_auto_init_hp_out(codec);
14808 alc269_auto_init_analog_input(codec);
14809 if (!spec->dual_adc_switch)
14810 alc269_auto_init_input_src(codec);
14811 alc_auto_init_digital(codec);
14812 if (spec->unsol_event)
14813 alc_inithook(codec);
14816 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14818 int val = alc_read_coef_idx(codec, 0x04);
14823 alc_write_coef_idx(codec, 0x04, val);
14826 static void alc269_shutup(struct hda_codec *codec)
14828 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14829 alc269_toggle_power_output(codec, 0);
14830 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14831 alc269_toggle_power_output(codec, 0);
14836 #ifdef SND_HDA_NEEDS_RESUME
14837 static int alc269_resume(struct hda_codec *codec)
14839 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14840 alc269_toggle_power_output(codec, 0);
14844 codec->patch_ops.init(codec);
14846 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14847 alc269_toggle_power_output(codec, 1);
14851 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14852 alc269_toggle_power_output(codec, 1);
14854 snd_hda_codec_resume_amp(codec);
14855 snd_hda_codec_resume_cache(codec);
14856 hda_call_check_power_status(codec, 0x01);
14859 #endif /* SND_HDA_NEEDS_RESUME */
14861 static void alc269_fixup_hweq(struct hda_codec *codec,
14862 const struct alc_fixup *fix, int action)
14866 if (action != ALC_FIXUP_ACT_INIT)
14868 coef = alc_read_coef_idx(codec, 0x1e);
14869 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14872 static void alc271_fixup_dmic(struct hda_codec *codec,
14873 const struct alc_fixup *fix, int action)
14875 static struct hda_verb verbs[] = {
14876 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14877 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14882 if (strcmp(codec->chip_name, "ALC271X"))
14884 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14885 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14886 snd_hda_sequence_write(codec, verbs);
14890 ALC269_FIXUP_SONY_VAIO,
14891 ALC275_FIXUP_SONY_VAIO_GPIO2,
14892 ALC269_FIXUP_DELL_M101Z,
14893 ALC269_FIXUP_SKU_IGNORE,
14894 ALC269_FIXUP_ASUS_G73JW,
14895 ALC269_FIXUP_LENOVO_EAPD,
14896 ALC275_FIXUP_SONY_HWEQ,
14900 static const struct alc_fixup alc269_fixups[] = {
14901 [ALC269_FIXUP_SONY_VAIO] = {
14902 .type = ALC_FIXUP_VERBS,
14903 .v.verbs = (const struct hda_verb[]) {
14904 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14908 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14909 .type = ALC_FIXUP_VERBS,
14910 .v.verbs = (const struct hda_verb[]) {
14911 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14912 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14913 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14917 .chain_id = ALC269_FIXUP_SONY_VAIO
14919 [ALC269_FIXUP_DELL_M101Z] = {
14920 .type = ALC_FIXUP_VERBS,
14921 .v.verbs = (const struct hda_verb[]) {
14922 /* Enables internal speaker */
14923 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14924 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14928 [ALC269_FIXUP_SKU_IGNORE] = {
14929 .type = ALC_FIXUP_SKU,
14930 .v.sku = ALC_FIXUP_SKU_IGNORE,
14932 [ALC269_FIXUP_ASUS_G73JW] = {
14933 .type = ALC_FIXUP_PINS,
14934 .v.pins = (const struct alc_pincfg[]) {
14935 { 0x17, 0x99130111 }, /* subwoofer */
14939 [ALC269_FIXUP_LENOVO_EAPD] = {
14940 .type = ALC_FIXUP_VERBS,
14941 .v.verbs = (const struct hda_verb[]) {
14942 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14946 [ALC275_FIXUP_SONY_HWEQ] = {
14947 .type = ALC_FIXUP_FUNC,
14948 .v.func = alc269_fixup_hweq,
14950 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14952 [ALC271_FIXUP_DMIC] = {
14953 .type = ALC_FIXUP_FUNC,
14954 .v.func = alc271_fixup_dmic,
14958 static struct snd_pci_quirk alc269_fixup_tbl[] = {
14959 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14960 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14961 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14962 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14963 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14964 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14965 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14966 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14967 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14968 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14969 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14970 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14971 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14977 * configuration and preset
14979 static const char * const alc269_models[ALC269_MODEL_LAST] = {
14980 [ALC269_BASIC] = "basic",
14981 [ALC269_QUANTA_FL1] = "quanta",
14982 [ALC269_AMIC] = "laptop-amic",
14983 [ALC269_DMIC] = "laptop-dmic",
14984 [ALC269_FUJITSU] = "fujitsu",
14985 [ALC269_LIFEBOOK] = "lifebook",
14986 [ALC269_AUTO] = "auto",
14989 static struct snd_pci_quirk alc269_cfg_tbl[] = {
14990 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14991 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14992 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14994 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
15001 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15002 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15008 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15013 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15014 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15015 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15016 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15021 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15022 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15023 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15024 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15025 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15026 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15027 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15028 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15029 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15030 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15032 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15034 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15035 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15036 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15037 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15038 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15039 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15040 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15041 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15042 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15043 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15047 static struct alc_config_preset alc269_presets[] = {
15049 .mixers = { alc269_base_mixer },
15050 .init_verbs = { alc269_init_verbs },
15051 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15052 .dac_nids = alc269_dac_nids,
15054 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15055 .channel_mode = alc269_modes,
15056 .input_mux = &alc269_capture_source,
15058 [ALC269_QUANTA_FL1] = {
15059 .mixers = { alc269_quanta_fl1_mixer },
15060 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15061 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15062 .dac_nids = alc269_dac_nids,
15064 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15065 .channel_mode = alc269_modes,
15066 .input_mux = &alc269_capture_source,
15067 .unsol_event = alc269_quanta_fl1_unsol_event,
15068 .setup = alc269_quanta_fl1_setup,
15069 .init_hook = alc269_quanta_fl1_init_hook,
15072 .mixers = { alc269_laptop_mixer },
15073 .cap_mixer = alc269_laptop_analog_capture_mixer,
15074 .init_verbs = { alc269_init_verbs,
15075 alc269_laptop_amic_init_verbs },
15076 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15077 .dac_nids = alc269_dac_nids,
15079 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15080 .channel_mode = alc269_modes,
15081 .unsol_event = alc269_laptop_unsol_event,
15082 .setup = alc269_laptop_amic_setup,
15083 .init_hook = alc269_laptop_inithook,
15086 .mixers = { alc269_laptop_mixer },
15087 .cap_mixer = alc269_laptop_digital_capture_mixer,
15088 .init_verbs = { alc269_init_verbs,
15089 alc269_laptop_dmic_init_verbs },
15090 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15091 .dac_nids = alc269_dac_nids,
15093 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15094 .channel_mode = alc269_modes,
15095 .unsol_event = alc269_laptop_unsol_event,
15096 .setup = alc269_laptop_dmic_setup,
15097 .init_hook = alc269_laptop_inithook,
15099 [ALC269VB_AMIC] = {
15100 .mixers = { alc269vb_laptop_mixer },
15101 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15102 .init_verbs = { alc269vb_init_verbs,
15103 alc269vb_laptop_amic_init_verbs },
15104 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15105 .dac_nids = alc269_dac_nids,
15107 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15108 .channel_mode = alc269_modes,
15109 .unsol_event = alc269_laptop_unsol_event,
15110 .setup = alc269vb_laptop_amic_setup,
15111 .init_hook = alc269_laptop_inithook,
15113 [ALC269VB_DMIC] = {
15114 .mixers = { alc269vb_laptop_mixer },
15115 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15116 .init_verbs = { alc269vb_init_verbs,
15117 alc269vb_laptop_dmic_init_verbs },
15118 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15119 .dac_nids = alc269_dac_nids,
15121 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15122 .channel_mode = alc269_modes,
15123 .unsol_event = alc269_laptop_unsol_event,
15124 .setup = alc269vb_laptop_dmic_setup,
15125 .init_hook = alc269_laptop_inithook,
15127 [ALC269_FUJITSU] = {
15128 .mixers = { alc269_fujitsu_mixer },
15129 .cap_mixer = alc269_laptop_digital_capture_mixer,
15130 .init_verbs = { alc269_init_verbs,
15131 alc269_laptop_dmic_init_verbs },
15132 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15133 .dac_nids = alc269_dac_nids,
15135 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15136 .channel_mode = alc269_modes,
15137 .unsol_event = alc269_laptop_unsol_event,
15138 .setup = alc269_laptop_dmic_setup,
15139 .init_hook = alc269_laptop_inithook,
15141 [ALC269_LIFEBOOK] = {
15142 .mixers = { alc269_lifebook_mixer },
15143 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15144 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15145 .dac_nids = alc269_dac_nids,
15147 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15148 .channel_mode = alc269_modes,
15149 .input_mux = &alc269_capture_source,
15150 .unsol_event = alc269_lifebook_unsol_event,
15151 .init_hook = alc269_lifebook_init_hook,
15154 .mixers = { alc269_asus_mixer },
15155 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15156 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15157 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15158 .dac_nids = alc269_dac_nids,
15159 .adc_nids = alc262_dmic_adc_nids,
15160 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15161 .capsrc_nids = alc262_dmic_capsrc_nids,
15162 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15163 .channel_mode = alc269_modes,
15164 .input_mux = &alc269_capture_source,
15165 .dig_out_nid = ALC880_DIGOUT_NID,
15166 .unsol_event = alc_sku_unsol_event,
15167 .setup = alc269vb_laptop_dmic_setup,
15168 .init_hook = alc_inithook,
15172 static int alc269_fill_coef(struct hda_codec *codec)
15176 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15177 alc_write_coef_idx(codec, 0xf, 0x960b);
15178 alc_write_coef_idx(codec, 0xe, 0x8817);
15181 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15182 alc_write_coef_idx(codec, 0xf, 0x960b);
15183 alc_write_coef_idx(codec, 0xe, 0x8814);
15186 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15187 val = alc_read_coef_idx(codec, 0x04);
15188 /* Power up output pin */
15189 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15192 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15193 val = alc_read_coef_idx(codec, 0xd);
15194 if ((val & 0x0c00) >> 10 != 0x1) {
15195 /* Capless ramp up clock control */
15196 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15198 val = alc_read_coef_idx(codec, 0x17);
15199 if ((val & 0x01c0) >> 6 != 0x4) {
15200 /* Class D power on reset */
15201 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15207 static int patch_alc269(struct hda_codec *codec)
15209 struct alc_spec *spec;
15210 int board_config, coef;
15213 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15217 codec->spec = spec;
15219 alc_auto_parse_customize_define(codec);
15221 if (codec->vendor_id == 0x10ec0269) {
15222 coef = alc_read_coef_idx(codec, 0);
15223 if ((coef & 0x00f0) == 0x0010) {
15224 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15225 spec->cdefine.platform_type == 1) {
15226 alc_codec_rename(codec, "ALC271X");
15227 spec->codec_variant = ALC269_TYPE_ALC271X;
15228 } else if ((coef & 0xf000) == 0x1000) {
15229 spec->codec_variant = ALC269_TYPE_ALC270;
15230 } else if ((coef & 0xf000) == 0x2000) {
15231 alc_codec_rename(codec, "ALC259");
15232 spec->codec_variant = ALC269_TYPE_ALC259;
15233 } else if ((coef & 0xf000) == 0x3000) {
15234 alc_codec_rename(codec, "ALC258");
15235 spec->codec_variant = ALC269_TYPE_ALC258;
15237 alc_codec_rename(codec, "ALC269VB");
15238 spec->codec_variant = ALC269_TYPE_ALC269VB;
15241 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15242 alc269_fill_coef(codec);
15245 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15249 if (board_config < 0) {
15250 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15252 board_config = ALC269_AUTO;
15255 if (board_config == ALC269_AUTO) {
15256 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15257 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15260 if (board_config == ALC269_AUTO) {
15261 /* automatic parse from the BIOS config */
15262 err = alc269_parse_auto_config(codec);
15268 "hda_codec: Cannot set up configuration "
15269 "from BIOS. Using base mode...\n");
15270 board_config = ALC269_BASIC;
15274 if (has_cdefine_beep(codec)) {
15275 err = snd_hda_attach_beep_device(codec, 0x1);
15282 if (board_config != ALC269_AUTO)
15283 setup_preset(codec, &alc269_presets[board_config]);
15285 if (board_config == ALC269_QUANTA_FL1) {
15286 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15287 * fix the sample rate of analog I/O to 44.1kHz
15289 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15290 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15291 } else if (spec->dual_adc_switch) {
15292 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15293 /* switch ADC dynamically */
15294 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15296 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15297 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15299 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15300 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15302 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15303 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15304 spec->adc_nids = alc269_adc_nids;
15305 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15306 spec->capsrc_nids = alc269_capsrc_nids;
15308 spec->adc_nids = alc269vb_adc_nids;
15309 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15310 spec->capsrc_nids = alc269vb_capsrc_nids;
15314 if (!spec->cap_mixer)
15315 set_capture_mixer(codec);
15316 if (has_cdefine_beep(codec))
15317 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15319 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15321 spec->vmaster_nid = 0x02;
15323 codec->patch_ops = alc_patch_ops;
15324 #ifdef SND_HDA_NEEDS_RESUME
15325 codec->patch_ops.resume = alc269_resume;
15327 if (board_config == ALC269_AUTO)
15328 spec->init_hook = alc269_auto_init;
15329 spec->shutup = alc269_shutup;
15331 alc_init_jacks(codec);
15332 #ifdef CONFIG_SND_HDA_POWER_SAVE
15333 if (!spec->loopback.amplist)
15334 spec->loopback.amplist = alc269_loopbacks;
15335 if (alc269_mic2_for_mute_led(codec))
15336 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15343 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15347 * set the path ways for 2 channel output
15348 * need to set the codec line out and mic 1 pin widgets to inputs
15350 static struct hda_verb alc861_threestack_ch2_init[] = {
15351 /* set pin widget 1Ah (line in) for input */
15352 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15353 /* set pin widget 18h (mic1/2) for input, for mic also enable
15356 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15358 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15360 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15361 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15367 * need to set the codec line out and mic 1 pin widgets to outputs
15369 static struct hda_verb alc861_threestack_ch6_init[] = {
15370 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15371 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15372 /* set pin widget 18h (mic1) for output (CLFE)*/
15373 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15375 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15376 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15378 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15380 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15381 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15386 static struct hda_channel_mode alc861_threestack_modes[2] = {
15387 { 2, alc861_threestack_ch2_init },
15388 { 6, alc861_threestack_ch6_init },
15390 /* Set mic1 as input and unmute the mixer */
15391 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15392 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15393 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15396 /* Set mic1 as output and mute mixer */
15397 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15398 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15399 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15403 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15404 { 2, alc861_uniwill_m31_ch2_init },
15405 { 4, alc861_uniwill_m31_ch4_init },
15408 /* Set mic1 and line-in as input and unmute the mixer */
15409 static struct hda_verb alc861_asus_ch2_init[] = {
15410 /* set pin widget 1Ah (line in) for input */
15411 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15412 /* set pin widget 18h (mic1/2) for input, for mic also enable
15415 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15417 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15419 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15420 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15424 /* Set mic1 nad line-in as output and mute mixer */
15425 static struct hda_verb alc861_asus_ch6_init[] = {
15426 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15427 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15428 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15429 /* set pin widget 18h (mic1) for output (CLFE)*/
15430 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15431 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15432 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15433 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15435 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15437 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15438 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15443 static struct hda_channel_mode alc861_asus_modes[2] = {
15444 { 2, alc861_asus_ch2_init },
15445 { 6, alc861_asus_ch6_init },
15450 static struct snd_kcontrol_new alc861_base_mixer[] = {
15451 /* output mixer control */
15452 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15453 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15454 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15455 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15456 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15458 /*Input mixer control */
15459 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15461 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15462 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15463 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15464 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15466 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15467 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15468 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15473 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15474 /* output mixer control */
15475 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15476 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15477 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15478 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15479 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15481 /* Input mixer control */
15482 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15484 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15485 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15486 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15487 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15489 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15490 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15494 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15495 .name = "Channel Mode",
15496 .info = alc_ch_mode_info,
15497 .get = alc_ch_mode_get,
15498 .put = alc_ch_mode_put,
15499 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15504 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15505 /* output mixer control */
15506 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15508 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15513 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15514 /* output mixer control */
15515 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15516 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15517 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15518 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15519 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15521 /* Input mixer control */
15522 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15523 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15524 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15525 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15526 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15527 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15528 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15529 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15530 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15531 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15534 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15535 .name = "Channel Mode",
15536 .info = alc_ch_mode_info,
15537 .get = alc_ch_mode_get,
15538 .put = alc_ch_mode_put,
15539 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15544 static struct snd_kcontrol_new alc861_asus_mixer[] = {
15545 /* output mixer control */
15546 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15547 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15548 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15549 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15550 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15552 /* Input mixer control */
15553 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15554 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15555 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15556 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15557 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15558 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15559 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15560 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15561 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15562 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15566 .name = "Channel Mode",
15567 .info = alc_ch_mode_info,
15568 .get = alc_ch_mode_get,
15569 .put = alc_ch_mode_put,
15570 .private_value = ARRAY_SIZE(alc861_asus_modes),
15575 /* additional mixer */
15576 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15577 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15578 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15583 * generic initialization of ADC, input mixers and output mixers
15585 static struct hda_verb alc861_base_init_verbs[] = {
15587 * Unmute ADC0 and set the default input to mic-in
15589 /* port-A for surround (rear panel) */
15590 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15591 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15592 /* port-B for mic-in (rear panel) with vref */
15593 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15594 /* port-C for line-in (rear panel) */
15595 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15596 /* port-D for Front */
15597 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15598 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15599 /* port-E for HP out (front panel) */
15600 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15601 /* route front PCM to HP */
15602 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15603 /* port-F for mic-in (front panel) with vref */
15604 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15605 /* port-G for CLFE (rear panel) */
15606 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15607 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15608 /* port-H for side (rear panel) */
15609 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15610 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15612 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15613 /* route front mic to ADC1*/
15614 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15615 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15617 /* Unmute DAC0~3 & spdif out*/
15618 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15619 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15620 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15621 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15624 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15625 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15626 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15627 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15628 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15630 /* Unmute Stereo Mixer 15 */
15631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15637 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15638 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15639 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15640 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15641 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15642 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15644 /* hp used DAC 3 (Front) */
15645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15651 static struct hda_verb alc861_threestack_init_verbs[] = {
15653 * Unmute ADC0 and set the default input to mic-in
15655 /* port-A for surround (rear panel) */
15656 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15657 /* port-B for mic-in (rear panel) with vref */
15658 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15659 /* port-C for line-in (rear panel) */
15660 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15661 /* port-D for Front */
15662 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15663 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15664 /* port-E for HP out (front panel) */
15665 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15666 /* route front PCM to HP */
15667 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15668 /* port-F for mic-in (front panel) with vref */
15669 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15670 /* port-G for CLFE (rear panel) */
15671 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15672 /* port-H for side (rear panel) */
15673 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15675 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15676 /* route front mic to ADC1*/
15677 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15678 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15679 /* Unmute DAC0~3 & spdif out*/
15680 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15681 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15682 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15683 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15686 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15687 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15688 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15689 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15690 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15692 /* Unmute Stereo Mixer 15 */
15693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15698 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15700 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15701 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15702 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15703 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15706 /* hp used DAC 3 (Front) */
15707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15708 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15712 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15714 * Unmute ADC0 and set the default input to mic-in
15716 /* port-A for surround (rear panel) */
15717 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15718 /* port-B for mic-in (rear panel) with vref */
15719 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15720 /* port-C for line-in (rear panel) */
15721 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15722 /* port-D for Front */
15723 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15724 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15725 /* port-E for HP out (front panel) */
15726 /* this has to be set to VREF80 */
15727 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15728 /* route front PCM to HP */
15729 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15730 /* port-F for mic-in (front panel) with vref */
15731 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15732 /* port-G for CLFE (rear panel) */
15733 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15734 /* port-H for side (rear panel) */
15735 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15737 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15738 /* route front mic to ADC1*/
15739 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15740 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15741 /* Unmute DAC0~3 & spdif out*/
15742 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15743 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15744 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15745 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15748 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15749 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15750 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15751 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15752 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15754 /* Unmute Stereo Mixer 15 */
15755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15757 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15758 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15760 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15761 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15762 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15763 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15764 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15765 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15766 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15767 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 /* hp used DAC 3 (Front) */
15769 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15770 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15774 static struct hda_verb alc861_asus_init_verbs[] = {
15776 * Unmute ADC0 and set the default input to mic-in
15778 /* port-A for surround (rear panel)
15779 * according to codec#0 this is the HP jack
15781 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15782 /* route front PCM to HP */
15783 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15784 /* port-B for mic-in (rear panel) with vref */
15785 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15786 /* port-C for line-in (rear panel) */
15787 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15788 /* port-D for Front */
15789 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15790 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15791 /* port-E for HP out (front panel) */
15792 /* this has to be set to VREF80 */
15793 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15794 /* route front PCM to HP */
15795 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15796 /* port-F for mic-in (front panel) with vref */
15797 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15798 /* port-G for CLFE (rear panel) */
15799 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15800 /* port-H for side (rear panel) */
15801 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15803 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15804 /* route front mic to ADC1*/
15805 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15806 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15807 /* Unmute DAC0~3 & spdif out*/
15808 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15809 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15810 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15811 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15813 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15814 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15815 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15816 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15817 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15819 /* Unmute Stereo Mixer 15 */
15820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15827 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15828 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15829 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15832 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15833 /* hp used DAC 3 (Front) */
15834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15835 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15839 /* additional init verbs for ASUS laptops */
15840 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15841 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15842 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15847 * generic initialization of ADC, input mixers and output mixers
15849 static struct hda_verb alc861_auto_init_verbs[] = {
15851 * Unmute ADC0 and set the default input to mic-in
15853 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15854 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15856 /* Unmute DAC0~3 & spdif out*/
15857 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15858 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15859 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15860 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15863 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15864 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15865 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15866 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15867 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15869 /* Unmute Stereo Mixer 15 */
15870 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15875 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15876 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15877 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15878 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15880 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15882 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15885 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15886 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15887 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15888 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15889 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15890 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15891 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15893 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15898 static struct hda_verb alc861_toshiba_init_verbs[] = {
15899 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15904 /* toggle speaker-output according to the hp-jack state */
15905 static void alc861_toshiba_automute(struct hda_codec *codec)
15907 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15909 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15910 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15911 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15912 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15915 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15918 if ((res >> 26) == ALC880_HP_EVENT)
15919 alc861_toshiba_automute(codec);
15922 /* pcm configuration: identical with ALC880 */
15923 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15924 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15925 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15926 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15929 #define ALC861_DIGOUT_NID 0x07
15931 static struct hda_channel_mode alc861_8ch_modes[1] = {
15935 static hda_nid_t alc861_dac_nids[4] = {
15936 /* front, surround, clfe, side */
15937 0x03, 0x06, 0x05, 0x04
15940 static hda_nid_t alc660_dac_nids[3] = {
15941 /* front, clfe, surround */
15945 static hda_nid_t alc861_adc_nids[1] = {
15950 static struct hda_input_mux alc861_capture_source = {
15954 { "Front Mic", 0x3 },
15961 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15963 struct alc_spec *spec = codec->spec;
15964 hda_nid_t mix, srcs[5];
15967 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15969 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15972 for (i = 0; i < num; i++) {
15974 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15975 if (type != AC_WID_AUD_OUT)
15977 for (j = 0; j < spec->multiout.num_dacs; j++)
15978 if (spec->multiout.dac_nids[j] == srcs[i])
15980 if (j >= spec->multiout.num_dacs)
15986 /* fill in the dac_nids table from the parsed pin configuration */
15987 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15988 const struct auto_pin_cfg *cfg)
15990 struct alc_spec *spec = codec->spec;
15992 hda_nid_t nid, dac;
15994 spec->multiout.dac_nids = spec->private_dac_nids;
15995 for (i = 0; i < cfg->line_outs; i++) {
15996 nid = cfg->line_out_pins[i];
15997 dac = alc861_look_for_dac(codec, nid);
16000 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
16005 static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16006 hda_nid_t nid, int idx, unsigned int chs)
16008 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16009 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16012 #define alc861_create_out_sw(codec, pfx, nid, chs) \
16013 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16015 /* add playback controls from the parsed DAC table */
16016 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16017 const struct auto_pin_cfg *cfg)
16019 struct alc_spec *spec = codec->spec;
16020 static const char * const chname[4] = {
16021 "Front", "Surround", NULL /*CLFE*/, "Side"
16023 const char *pfx = alc_get_line_out_pfx(cfg, true);
16027 for (i = 0; i < cfg->line_outs; i++) {
16028 nid = spec->multiout.dac_nids[i];
16031 if (!pfx && i == 2) {
16033 err = alc861_create_out_sw(codec, "Center", nid, 1);
16036 err = alc861_create_out_sw(codec, "LFE", nid, 2);
16040 const char *name = pfx;
16046 err = __alc861_create_out_sw(codec, name, nid, index, 3);
16054 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16056 struct alc_spec *spec = codec->spec;
16063 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16064 nid = alc861_look_for_dac(codec, pin);
16066 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16069 spec->multiout.hp_nid = nid;
16075 /* create playback/capture controls for input pins */
16076 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16077 const struct auto_pin_cfg *cfg)
16079 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16082 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16084 int pin_type, hda_nid_t dac)
16086 hda_nid_t mix, srcs[5];
16089 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16091 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16093 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16095 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16098 for (i = 0; i < num; i++) {
16100 if (srcs[i] == dac || srcs[i] == 0x15)
16101 mute = AMP_IN_UNMUTE(i);
16103 mute = AMP_IN_MUTE(i);
16104 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16109 static void alc861_auto_init_multi_out(struct hda_codec *codec)
16111 struct alc_spec *spec = codec->spec;
16114 for (i = 0; i < spec->autocfg.line_outs; i++) {
16115 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16116 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16118 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16119 spec->multiout.dac_nids[i]);
16123 static void alc861_auto_init_hp_out(struct hda_codec *codec)
16125 struct alc_spec *spec = codec->spec;
16127 if (spec->autocfg.hp_outs)
16128 alc861_auto_set_output_and_unmute(codec,
16129 spec->autocfg.hp_pins[0],
16131 spec->multiout.hp_nid);
16132 if (spec->autocfg.speaker_outs)
16133 alc861_auto_set_output_and_unmute(codec,
16134 spec->autocfg.speaker_pins[0],
16136 spec->multiout.dac_nids[0]);
16139 static void alc861_auto_init_analog_input(struct hda_codec *codec)
16141 struct alc_spec *spec = codec->spec;
16142 struct auto_pin_cfg *cfg = &spec->autocfg;
16145 for (i = 0; i < cfg->num_inputs; i++) {
16146 hda_nid_t nid = cfg->inputs[i].pin;
16147 if (nid >= 0x0c && nid <= 0x11)
16148 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16152 /* parse the BIOS configuration and set up the alc_spec */
16153 /* return 1 if successful, 0 if the proper config is not found,
16154 * or a negative error code
16156 static int alc861_parse_auto_config(struct hda_codec *codec)
16158 struct alc_spec *spec = codec->spec;
16160 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16162 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16166 if (!spec->autocfg.line_outs)
16167 return 0; /* can't find valid BIOS pin config */
16169 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16172 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16175 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16178 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16182 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16184 alc_auto_parse_digital(codec);
16186 if (spec->kctls.list)
16187 add_mixer(spec, spec->kctls.list);
16189 add_verb(spec, alc861_auto_init_verbs);
16191 spec->num_mux_defs = 1;
16192 spec->input_mux = &spec->private_imux[0];
16194 spec->adc_nids = alc861_adc_nids;
16195 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16196 set_capture_mixer(codec);
16198 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16203 /* additional initialization for auto-configuration model */
16204 static void alc861_auto_init(struct hda_codec *codec)
16206 struct alc_spec *spec = codec->spec;
16207 alc861_auto_init_multi_out(codec);
16208 alc861_auto_init_hp_out(codec);
16209 alc861_auto_init_analog_input(codec);
16210 alc_auto_init_digital(codec);
16211 if (spec->unsol_event)
16212 alc_inithook(codec);
16215 #ifdef CONFIG_SND_HDA_POWER_SAVE
16216 static struct hda_amp_list alc861_loopbacks[] = {
16217 { 0x15, HDA_INPUT, 0 },
16218 { 0x15, HDA_INPUT, 1 },
16219 { 0x15, HDA_INPUT, 2 },
16220 { 0x15, HDA_INPUT, 3 },
16227 * configuration and preset
16229 static const char * const alc861_models[ALC861_MODEL_LAST] = {
16230 [ALC861_3ST] = "3stack",
16231 [ALC660_3ST] = "3stack-660",
16232 [ALC861_3ST_DIG] = "3stack-dig",
16233 [ALC861_6ST_DIG] = "6stack-dig",
16234 [ALC861_UNIWILL_M31] = "uniwill-m31",
16235 [ALC861_TOSHIBA] = "toshiba",
16236 [ALC861_ASUS] = "asus",
16237 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16238 [ALC861_AUTO] = "auto",
16241 static struct snd_pci_quirk alc861_cfg_tbl[] = {
16242 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16243 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16244 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16245 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16246 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16247 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16248 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16249 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16250 * Any other models that need this preset?
16252 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16253 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16254 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16255 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16256 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16257 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16258 /* FIXME: the below seems conflict */
16259 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16260 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16261 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16265 static struct alc_config_preset alc861_presets[] = {
16267 .mixers = { alc861_3ST_mixer },
16268 .init_verbs = { alc861_threestack_init_verbs },
16269 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16270 .dac_nids = alc861_dac_nids,
16271 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16272 .channel_mode = alc861_threestack_modes,
16274 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16275 .adc_nids = alc861_adc_nids,
16276 .input_mux = &alc861_capture_source,
16278 [ALC861_3ST_DIG] = {
16279 .mixers = { alc861_base_mixer },
16280 .init_verbs = { alc861_threestack_init_verbs },
16281 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16282 .dac_nids = alc861_dac_nids,
16283 .dig_out_nid = ALC861_DIGOUT_NID,
16284 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16285 .channel_mode = alc861_threestack_modes,
16287 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16288 .adc_nids = alc861_adc_nids,
16289 .input_mux = &alc861_capture_source,
16291 [ALC861_6ST_DIG] = {
16292 .mixers = { alc861_base_mixer },
16293 .init_verbs = { alc861_base_init_verbs },
16294 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16295 .dac_nids = alc861_dac_nids,
16296 .dig_out_nid = ALC861_DIGOUT_NID,
16297 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16298 .channel_mode = alc861_8ch_modes,
16299 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16300 .adc_nids = alc861_adc_nids,
16301 .input_mux = &alc861_capture_source,
16304 .mixers = { alc861_3ST_mixer },
16305 .init_verbs = { alc861_threestack_init_verbs },
16306 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16307 .dac_nids = alc660_dac_nids,
16308 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16309 .channel_mode = alc861_threestack_modes,
16311 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16312 .adc_nids = alc861_adc_nids,
16313 .input_mux = &alc861_capture_source,
16315 [ALC861_UNIWILL_M31] = {
16316 .mixers = { alc861_uniwill_m31_mixer },
16317 .init_verbs = { alc861_uniwill_m31_init_verbs },
16318 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16319 .dac_nids = alc861_dac_nids,
16320 .dig_out_nid = ALC861_DIGOUT_NID,
16321 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16322 .channel_mode = alc861_uniwill_m31_modes,
16324 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16325 .adc_nids = alc861_adc_nids,
16326 .input_mux = &alc861_capture_source,
16328 [ALC861_TOSHIBA] = {
16329 .mixers = { alc861_toshiba_mixer },
16330 .init_verbs = { alc861_base_init_verbs,
16331 alc861_toshiba_init_verbs },
16332 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16333 .dac_nids = alc861_dac_nids,
16334 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16335 .channel_mode = alc883_3ST_2ch_modes,
16336 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16337 .adc_nids = alc861_adc_nids,
16338 .input_mux = &alc861_capture_source,
16339 .unsol_event = alc861_toshiba_unsol_event,
16340 .init_hook = alc861_toshiba_automute,
16343 .mixers = { alc861_asus_mixer },
16344 .init_verbs = { alc861_asus_init_verbs },
16345 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16346 .dac_nids = alc861_dac_nids,
16347 .dig_out_nid = ALC861_DIGOUT_NID,
16348 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16349 .channel_mode = alc861_asus_modes,
16352 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16353 .adc_nids = alc861_adc_nids,
16354 .input_mux = &alc861_capture_source,
16356 [ALC861_ASUS_LAPTOP] = {
16357 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16358 .init_verbs = { alc861_asus_init_verbs,
16359 alc861_asus_laptop_init_verbs },
16360 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16361 .dac_nids = alc861_dac_nids,
16362 .dig_out_nid = ALC861_DIGOUT_NID,
16363 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16364 .channel_mode = alc883_3ST_2ch_modes,
16366 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16367 .adc_nids = alc861_adc_nids,
16368 .input_mux = &alc861_capture_source,
16372 /* Pin config fixes */
16374 PINFIX_FSC_AMILO_PI1505,
16377 static const struct alc_fixup alc861_fixups[] = {
16378 [PINFIX_FSC_AMILO_PI1505] = {
16379 .type = ALC_FIXUP_PINS,
16380 .v.pins = (const struct alc_pincfg[]) {
16381 { 0x0b, 0x0221101f }, /* HP */
16382 { 0x0f, 0x90170310 }, /* speaker */
16388 static struct snd_pci_quirk alc861_fixup_tbl[] = {
16389 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16393 static int patch_alc861(struct hda_codec *codec)
16395 struct alc_spec *spec;
16399 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16403 codec->spec = spec;
16405 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16409 if (board_config < 0) {
16410 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16412 board_config = ALC861_AUTO;
16415 if (board_config == ALC861_AUTO) {
16416 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16417 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16420 if (board_config == ALC861_AUTO) {
16421 /* automatic parse from the BIOS config */
16422 err = alc861_parse_auto_config(codec);
16428 "hda_codec: Cannot set up configuration "
16429 "from BIOS. Using base mode...\n");
16430 board_config = ALC861_3ST_DIG;
16434 err = snd_hda_attach_beep_device(codec, 0x23);
16440 if (board_config != ALC861_AUTO)
16441 setup_preset(codec, &alc861_presets[board_config]);
16443 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16444 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16446 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16447 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16449 if (!spec->cap_mixer)
16450 set_capture_mixer(codec);
16451 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16453 spec->vmaster_nid = 0x03;
16455 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16457 codec->patch_ops = alc_patch_ops;
16458 if (board_config == ALC861_AUTO) {
16459 spec->init_hook = alc861_auto_init;
16460 #ifdef CONFIG_SND_HDA_POWER_SAVE
16461 spec->power_hook = alc_power_eapd;
16464 #ifdef CONFIG_SND_HDA_POWER_SAVE
16465 if (!spec->loopback.amplist)
16466 spec->loopback.amplist = alc861_loopbacks;
16473 * ALC861-VD support
16477 * In addition, an independent DAC
16479 #define ALC861VD_DIGOUT_NID 0x06
16481 static hda_nid_t alc861vd_dac_nids[4] = {
16482 /* front, surr, clfe, side surr */
16483 0x02, 0x03, 0x04, 0x05
16486 /* dac_nids for ALC660vd are in a different order - according to
16487 * Realtek's driver.
16488 * This should probably result in a different mixer for 6stack models
16489 * of ALC660vd codecs, but for now there is only 3stack mixer
16490 * - and it is the same as in 861vd.
16491 * adc_nids in ALC660vd are (is) the same as in 861vd
16493 static hda_nid_t alc660vd_dac_nids[3] = {
16494 /* front, rear, clfe, rear_surr */
16498 static hda_nid_t alc861vd_adc_nids[1] = {
16503 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16506 /* FIXME: should be a matrix-type input source selection */
16507 static struct hda_input_mux alc861vd_capture_source = {
16511 { "Front Mic", 0x1 },
16517 static struct hda_input_mux alc861vd_dallas_capture_source = {
16521 { "Internal Mic", 0x1 },
16525 static struct hda_input_mux alc861vd_hp_capture_source = {
16528 { "Front Mic", 0x0 },
16529 { "ATAPI Mic", 0x1 },
16536 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16543 static struct hda_verb alc861vd_6stack_ch6_init[] = {
16544 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16545 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16546 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16547 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16554 static struct hda_verb alc861vd_6stack_ch8_init[] = {
16555 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16556 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16557 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16558 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16562 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16563 { 6, alc861vd_6stack_ch6_init },
16564 { 8, alc861vd_6stack_ch8_init },
16567 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16570 .name = "Channel Mode",
16571 .info = alc_ch_mode_info,
16572 .get = alc_ch_mode_get,
16573 .put = alc_ch_mode_put,
16578 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16579 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16581 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16582 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16583 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16585 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16586 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16588 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16590 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16592 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16593 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16595 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16596 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16600 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16601 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16602 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16604 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16608 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16609 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16611 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16612 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16617 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16618 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16619 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16621 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16623 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16627 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16628 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16629 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16631 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16632 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16634 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16635 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16640 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16641 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16642 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16643 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16645 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16647 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16651 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16652 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16653 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16655 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16656 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16661 /* Pin assignment: Speaker=0x14, HP = 0x15,
16662 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16664 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16665 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16666 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16667 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16668 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16669 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16671 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16672 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16673 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16674 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16678 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16679 * Front Mic=0x18, ATAPI Mic = 0x19,
16681 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16682 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16683 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16685 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16686 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16687 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16688 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16689 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16695 * generic initialization of ADC, input mixers and output mixers
16697 static struct hda_verb alc861vd_volume_init_verbs[] = {
16699 * Unmute ADC0 and set the default input to mic-in
16701 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16704 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16705 * the analog-loopback mixer widget
16707 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16714 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16715 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16716 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16717 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16721 * Set up output mixers (0x02 - 0x05)
16723 /* set vol=0 to output mixers */
16724 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16725 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16726 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16727 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16729 /* set up input amps for analog loopback */
16730 /* Amp Indices: DAC = 0, mixer = 1 */
16731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16733 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16734 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16736 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16737 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16738 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16744 * 3-stack pin configuration:
16745 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16747 static struct hda_verb alc861vd_3stack_init_verbs[] = {
16749 * Set pin mode and muting
16751 /* set front pin widgets 0x14 for output */
16752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16753 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16754 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16756 /* Mic (rear) pin: input vref at 80% */
16757 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16759 /* Front Mic pin: input vref at 80% */
16760 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16761 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16762 /* Line In pin: input */
16763 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16764 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16765 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16766 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16767 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16768 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16769 /* CD pin widget for input */
16770 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16776 * 6-stack pin configuration:
16778 static struct hda_verb alc861vd_6stack_init_verbs[] = {
16780 * Set pin mode and muting
16782 /* set front pin widgets 0x14 for output */
16783 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16784 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16785 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16787 /* Rear Pin: output 1 (0x0d) */
16788 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16789 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16790 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16791 /* CLFE Pin: output 2 (0x0e) */
16792 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16793 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16794 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16795 /* Side Pin: output 3 (0x0f) */
16796 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16800 /* Mic (rear) pin: input vref at 80% */
16801 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16802 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16803 /* Front Mic pin: input vref at 80% */
16804 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16805 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16806 /* Line In pin: input */
16807 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16808 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16809 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16810 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16811 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16812 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16813 /* CD pin widget for input */
16814 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16819 static struct hda_verb alc861vd_eapd_verbs[] = {
16820 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16824 static struct hda_verb alc660vd_eapd_verbs[] = {
16825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16830 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16832 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16834 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16835 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16839 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16841 struct alc_spec *spec = codec->spec;
16842 spec->autocfg.hp_pins[0] = 0x1b;
16843 spec->autocfg.speaker_pins[0] = 0x14;
16846 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16848 alc_automute_amp(codec);
16849 alc88x_simple_mic_automute(codec);
16852 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16855 switch (res >> 26) {
16856 case ALC880_MIC_EVENT:
16857 alc88x_simple_mic_automute(codec);
16860 alc_automute_amp_unsol_event(codec, res);
16865 static struct hda_verb alc861vd_dallas_verbs[] = {
16866 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16867 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16868 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16869 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16871 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16872 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16873 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16874 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16875 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16876 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16877 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16878 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16880 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16881 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16883 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16884 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16885 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16886 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16887 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16889 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16890 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16891 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16892 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16893 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16894 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16895 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16896 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16898 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16899 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16900 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16901 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16904 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16905 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16910 /* toggle speaker-output according to the hp-jack state */
16911 static void alc861vd_dallas_setup(struct hda_codec *codec)
16913 struct alc_spec *spec = codec->spec;
16915 spec->autocfg.hp_pins[0] = 0x15;
16916 spec->autocfg.speaker_pins[0] = 0x14;
16919 #ifdef CONFIG_SND_HDA_POWER_SAVE
16920 #define alc861vd_loopbacks alc880_loopbacks
16923 /* pcm configuration: identical with ALC880 */
16924 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16925 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16926 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16927 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16930 * configuration and preset
16932 static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16933 [ALC660VD_3ST] = "3stack-660",
16934 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16935 [ALC660VD_ASUS_V1S] = "asus-v1s",
16936 [ALC861VD_3ST] = "3stack",
16937 [ALC861VD_3ST_DIG] = "3stack-digout",
16938 [ALC861VD_6ST_DIG] = "6stack-digout",
16939 [ALC861VD_LENOVO] = "lenovo",
16940 [ALC861VD_DALLAS] = "dallas",
16941 [ALC861VD_HP] = "hp",
16942 [ALC861VD_AUTO] = "auto",
16945 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16946 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16947 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16948 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16949 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16950 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16951 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16952 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16953 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16954 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16955 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16956 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16957 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16958 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16959 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16960 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16964 static struct alc_config_preset alc861vd_presets[] = {
16966 .mixers = { alc861vd_3st_mixer },
16967 .init_verbs = { alc861vd_volume_init_verbs,
16968 alc861vd_3stack_init_verbs },
16969 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16970 .dac_nids = alc660vd_dac_nids,
16971 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16972 .channel_mode = alc861vd_3stack_2ch_modes,
16973 .input_mux = &alc861vd_capture_source,
16975 [ALC660VD_3ST_DIG] = {
16976 .mixers = { alc861vd_3st_mixer },
16977 .init_verbs = { alc861vd_volume_init_verbs,
16978 alc861vd_3stack_init_verbs },
16979 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16980 .dac_nids = alc660vd_dac_nids,
16981 .dig_out_nid = ALC861VD_DIGOUT_NID,
16982 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16983 .channel_mode = alc861vd_3stack_2ch_modes,
16984 .input_mux = &alc861vd_capture_source,
16987 .mixers = { alc861vd_3st_mixer },
16988 .init_verbs = { alc861vd_volume_init_verbs,
16989 alc861vd_3stack_init_verbs },
16990 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16991 .dac_nids = alc861vd_dac_nids,
16992 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16993 .channel_mode = alc861vd_3stack_2ch_modes,
16994 .input_mux = &alc861vd_capture_source,
16996 [ALC861VD_3ST_DIG] = {
16997 .mixers = { alc861vd_3st_mixer },
16998 .init_verbs = { alc861vd_volume_init_verbs,
16999 alc861vd_3stack_init_verbs },
17000 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17001 .dac_nids = alc861vd_dac_nids,
17002 .dig_out_nid = ALC861VD_DIGOUT_NID,
17003 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17004 .channel_mode = alc861vd_3stack_2ch_modes,
17005 .input_mux = &alc861vd_capture_source,
17007 [ALC861VD_6ST_DIG] = {
17008 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17009 .init_verbs = { alc861vd_volume_init_verbs,
17010 alc861vd_6stack_init_verbs },
17011 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17012 .dac_nids = alc861vd_dac_nids,
17013 .dig_out_nid = ALC861VD_DIGOUT_NID,
17014 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17015 .channel_mode = alc861vd_6stack_modes,
17016 .input_mux = &alc861vd_capture_source,
17018 [ALC861VD_LENOVO] = {
17019 .mixers = { alc861vd_lenovo_mixer },
17020 .init_verbs = { alc861vd_volume_init_verbs,
17021 alc861vd_3stack_init_verbs,
17022 alc861vd_eapd_verbs,
17023 alc861vd_lenovo_unsol_verbs },
17024 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17025 .dac_nids = alc660vd_dac_nids,
17026 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17027 .channel_mode = alc861vd_3stack_2ch_modes,
17028 .input_mux = &alc861vd_capture_source,
17029 .unsol_event = alc861vd_lenovo_unsol_event,
17030 .setup = alc861vd_lenovo_setup,
17031 .init_hook = alc861vd_lenovo_init_hook,
17033 [ALC861VD_DALLAS] = {
17034 .mixers = { alc861vd_dallas_mixer },
17035 .init_verbs = { alc861vd_dallas_verbs },
17036 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17037 .dac_nids = alc861vd_dac_nids,
17038 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17039 .channel_mode = alc861vd_3stack_2ch_modes,
17040 .input_mux = &alc861vd_dallas_capture_source,
17041 .unsol_event = alc_automute_amp_unsol_event,
17042 .setup = alc861vd_dallas_setup,
17043 .init_hook = alc_automute_amp,
17046 .mixers = { alc861vd_hp_mixer },
17047 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17048 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17049 .dac_nids = alc861vd_dac_nids,
17050 .dig_out_nid = ALC861VD_DIGOUT_NID,
17051 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17052 .channel_mode = alc861vd_3stack_2ch_modes,
17053 .input_mux = &alc861vd_hp_capture_source,
17054 .unsol_event = alc_automute_amp_unsol_event,
17055 .setup = alc861vd_dallas_setup,
17056 .init_hook = alc_automute_amp,
17058 [ALC660VD_ASUS_V1S] = {
17059 .mixers = { alc861vd_lenovo_mixer },
17060 .init_verbs = { alc861vd_volume_init_verbs,
17061 alc861vd_3stack_init_verbs,
17062 alc861vd_eapd_verbs,
17063 alc861vd_lenovo_unsol_verbs },
17064 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17065 .dac_nids = alc660vd_dac_nids,
17066 .dig_out_nid = ALC861VD_DIGOUT_NID,
17067 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17068 .channel_mode = alc861vd_3stack_2ch_modes,
17069 .input_mux = &alc861vd_capture_source,
17070 .unsol_event = alc861vd_lenovo_unsol_event,
17071 .setup = alc861vd_lenovo_setup,
17072 .init_hook = alc861vd_lenovo_init_hook,
17077 * BIOS auto configuration
17079 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17080 const struct auto_pin_cfg *cfg)
17082 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17086 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17087 hda_nid_t nid, int pin_type, int dac_idx)
17089 alc_set_pin_output(codec, nid, pin_type);
17092 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17094 struct alc_spec *spec = codec->spec;
17097 for (i = 0; i <= HDA_SIDE; i++) {
17098 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17099 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17101 alc861vd_auto_set_output_and_unmute(codec, nid,
17107 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17109 struct alc_spec *spec = codec->spec;
17112 pin = spec->autocfg.hp_pins[0];
17113 if (pin) /* connect to front and use dac 0 */
17114 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17115 pin = spec->autocfg.speaker_pins[0];
17117 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17120 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17122 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17124 struct alc_spec *spec = codec->spec;
17125 struct auto_pin_cfg *cfg = &spec->autocfg;
17128 for (i = 0; i < cfg->num_inputs; i++) {
17129 hda_nid_t nid = cfg->inputs[i].pin;
17130 if (alc_is_input_pin(codec, nid)) {
17131 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17132 if (nid != ALC861VD_PIN_CD_NID &&
17133 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17134 snd_hda_codec_write(codec, nid, 0,
17135 AC_VERB_SET_AMP_GAIN_MUTE,
17141 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
17143 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17144 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17146 /* add playback controls from the parsed DAC table */
17147 /* Based on ALC880 version. But ALC861VD has separate,
17148 * different NIDs for mute/unmute switch and volume control */
17149 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17150 const struct auto_pin_cfg *cfg)
17152 static const char * const chname[4] = {
17153 "Front", "Surround", "CLFE", "Side"
17155 const char *pfx = alc_get_line_out_pfx(cfg, true);
17156 hda_nid_t nid_v, nid_s;
17159 for (i = 0; i < cfg->line_outs; i++) {
17160 if (!spec->multiout.dac_nids[i])
17162 nid_v = alc861vd_idx_to_mixer_vol(
17164 spec->multiout.dac_nids[i]));
17165 nid_s = alc861vd_idx_to_mixer_switch(
17167 spec->multiout.dac_nids[i]));
17169 if (!pfx && i == 2) {
17171 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17173 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17177 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17179 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17183 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17185 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17189 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17191 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17196 const char *name = pfx;
17202 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17204 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17208 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17210 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17219 /* add playback controls for speaker and HP outputs */
17220 /* Based on ALC880 version. But ALC861VD has separate,
17221 * different NIDs for mute/unmute switch and volume control */
17222 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17223 hda_nid_t pin, const char *pfx)
17225 hda_nid_t nid_v, nid_s;
17231 if (alc880_is_fixed_pin(pin)) {
17232 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17233 /* specify the DAC as the extra output */
17234 if (!spec->multiout.hp_nid)
17235 spec->multiout.hp_nid = nid_v;
17237 spec->multiout.extra_out_nid[0] = nid_v;
17238 /* control HP volume/switch on the output mixer amp */
17239 nid_v = alc861vd_idx_to_mixer_vol(
17240 alc880_fixed_pin_idx(pin));
17241 nid_s = alc861vd_idx_to_mixer_switch(
17242 alc880_fixed_pin_idx(pin));
17244 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17245 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17248 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17249 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17252 } else if (alc880_is_multi_pin(pin)) {
17253 /* set manual connection */
17254 /* we have only a switch on HP-out PIN */
17255 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17256 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17263 /* parse the BIOS configuration and set up the alc_spec
17264 * return 1 if successful, 0 if the proper config is not found,
17265 * or a negative error code
17266 * Based on ALC880 version - had to change it to override
17267 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17268 static int alc861vd_parse_auto_config(struct hda_codec *codec)
17270 struct alc_spec *spec = codec->spec;
17272 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17274 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17278 if (!spec->autocfg.line_outs)
17279 return 0; /* can't find valid BIOS pin config */
17281 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17284 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17287 err = alc861vd_auto_create_extra_out(spec,
17288 spec->autocfg.speaker_pins[0],
17292 err = alc861vd_auto_create_extra_out(spec,
17293 spec->autocfg.hp_pins[0],
17297 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17301 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17303 alc_auto_parse_digital(codec);
17305 if (spec->kctls.list)
17306 add_mixer(spec, spec->kctls.list);
17308 add_verb(spec, alc861vd_volume_init_verbs);
17310 spec->num_mux_defs = 1;
17311 spec->input_mux = &spec->private_imux[0];
17313 err = alc_auto_add_mic_boost(codec);
17317 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17322 /* additional initialization for auto-configuration model */
17323 static void alc861vd_auto_init(struct hda_codec *codec)
17325 struct alc_spec *spec = codec->spec;
17326 alc861vd_auto_init_multi_out(codec);
17327 alc861vd_auto_init_hp_out(codec);
17328 alc861vd_auto_init_analog_input(codec);
17329 alc861vd_auto_init_input_src(codec);
17330 alc_auto_init_digital(codec);
17331 if (spec->unsol_event)
17332 alc_inithook(codec);
17336 ALC660VD_FIX_ASUS_GPIO1
17340 static const struct alc_fixup alc861vd_fixups[] = {
17341 [ALC660VD_FIX_ASUS_GPIO1] = {
17342 .type = ALC_FIXUP_VERBS,
17343 .v.verbs = (const struct hda_verb[]) {
17344 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17345 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17346 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17352 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17353 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17357 static int patch_alc861vd(struct hda_codec *codec)
17359 struct alc_spec *spec;
17360 int err, board_config;
17362 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17366 codec->spec = spec;
17368 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17372 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17373 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17375 board_config = ALC861VD_AUTO;
17378 if (board_config == ALC861VD_AUTO) {
17379 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17380 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17383 if (board_config == ALC861VD_AUTO) {
17384 /* automatic parse from the BIOS config */
17385 err = alc861vd_parse_auto_config(codec);
17391 "hda_codec: Cannot set up configuration "
17392 "from BIOS. Using base mode...\n");
17393 board_config = ALC861VD_3ST;
17397 err = snd_hda_attach_beep_device(codec, 0x23);
17403 if (board_config != ALC861VD_AUTO)
17404 setup_preset(codec, &alc861vd_presets[board_config]);
17406 if (codec->vendor_id == 0x10ec0660) {
17407 /* always turn on EAPD */
17408 add_verb(spec, alc660vd_eapd_verbs);
17411 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17412 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17414 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17415 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17417 if (!spec->adc_nids) {
17418 spec->adc_nids = alc861vd_adc_nids;
17419 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17421 if (!spec->capsrc_nids)
17422 spec->capsrc_nids = alc861vd_capsrc_nids;
17424 set_capture_mixer(codec);
17425 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17427 spec->vmaster_nid = 0x02;
17429 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17431 codec->patch_ops = alc_patch_ops;
17433 if (board_config == ALC861VD_AUTO)
17434 spec->init_hook = alc861vd_auto_init;
17435 spec->shutup = alc_eapd_shutup;
17436 #ifdef CONFIG_SND_HDA_POWER_SAVE
17437 if (!spec->loopback.amplist)
17438 spec->loopback.amplist = alc861vd_loopbacks;
17447 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17448 * configuration. Each pin widget can choose any input DACs and a mixer.
17449 * Each ADC is connected from a mixer of all inputs. This makes possible
17450 * 6-channel independent captures.
17452 * In addition, an independent DAC for the multi-playback (not used in this
17455 #define ALC662_DIGOUT_NID 0x06
17456 #define ALC662_DIGIN_NID 0x0a
17458 static hda_nid_t alc662_dac_nids[3] = {
17459 /* front, rear, clfe */
17463 static hda_nid_t alc272_dac_nids[2] = {
17467 static hda_nid_t alc662_adc_nids[2] = {
17472 static hda_nid_t alc272_adc_nids[1] = {
17477 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17478 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17482 /* FIXME: should be a matrix-type input source selection */
17483 static struct hda_input_mux alc662_capture_source = {
17487 { "Front Mic", 0x1 },
17493 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17501 static struct hda_input_mux alc663_capture_source = {
17505 { "Front Mic", 0x1 },
17510 #if 0 /* set to 1 for testing other input sources below */
17511 static struct hda_input_mux alc272_nc10_capture_source = {
17514 { "Autoselect Mic", 0x0 },
17515 { "Internal Mic", 0x1 },
17516 { "In-0x02", 0x2 },
17517 { "In-0x03", 0x3 },
17518 { "In-0x04", 0x4 },
17519 { "In-0x05", 0x5 },
17520 { "In-0x06", 0x6 },
17521 { "In-0x07", 0x7 },
17522 { "In-0x08", 0x8 },
17523 { "In-0x09", 0x9 },
17524 { "In-0x0a", 0x0a },
17525 { "In-0x0b", 0x0b },
17526 { "In-0x0c", 0x0c },
17527 { "In-0x0d", 0x0d },
17528 { "In-0x0e", 0x0e },
17529 { "In-0x0f", 0x0f },
17537 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17544 static struct hda_verb alc662_3ST_ch2_init[] = {
17545 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17546 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17547 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17548 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17555 static struct hda_verb alc662_3ST_ch6_init[] = {
17556 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17557 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17558 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17559 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17560 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17561 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17565 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17566 { 2, alc662_3ST_ch2_init },
17567 { 6, alc662_3ST_ch6_init },
17573 static struct hda_verb alc662_sixstack_ch6_init[] = {
17574 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17575 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17576 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17583 static struct hda_verb alc662_sixstack_ch8_init[] = {
17584 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17585 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17586 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17590 static struct hda_channel_mode alc662_5stack_modes[2] = {
17591 { 2, alc662_sixstack_ch6_init },
17592 { 6, alc662_sixstack_ch8_init },
17595 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17596 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17599 static struct snd_kcontrol_new alc662_base_mixer[] = {
17600 /* output mixer control */
17601 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17602 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17603 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17604 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17605 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17606 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17607 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17608 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17609 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17611 /*Input mixer control */
17612 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17613 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17614 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17615 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17616 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17617 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17623 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17624 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17625 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17626 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17627 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17628 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17633 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17634 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17638 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17639 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17640 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17641 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17642 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17643 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17644 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17645 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17646 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17647 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17648 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17649 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17650 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17651 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17654 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17655 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17659 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17660 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17661 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17662 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17663 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17672 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17673 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17674 ALC262_HIPPO_MASTER_SWITCH,
17676 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17680 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17681 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17682 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17686 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17687 ALC262_HIPPO_MASTER_SWITCH,
17688 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17689 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17690 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17691 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17692 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17693 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17694 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17700 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17701 .ops = &snd_hda_bind_vol,
17703 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17704 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17709 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17710 .ops = &snd_hda_bind_sw,
17712 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17713 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17718 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
17719 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17720 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17721 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17726 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17727 .ops = &snd_hda_bind_sw,
17729 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17730 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17731 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17736 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17737 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17738 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17740 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17741 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17742 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17747 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17748 .ops = &snd_hda_bind_sw,
17750 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17751 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17752 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17757 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17758 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17759 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17762 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17763 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17767 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17768 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17769 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17770 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17771 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17772 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17773 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17774 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17778 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17779 .ops = &snd_hda_bind_vol,
17781 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17782 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17787 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17788 .ops = &snd_hda_bind_sw,
17790 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17791 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17796 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17797 HDA_BIND_VOL("Master Playback Volume",
17798 &alc663_asus_two_bind_master_vol),
17799 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17800 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17801 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17802 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17803 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17807 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17808 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17809 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17812 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17813 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17817 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17818 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17819 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17820 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17821 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17822 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17826 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17827 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17831 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17832 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17833 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17834 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17838 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17839 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17840 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17841 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17845 static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17846 .ops = &snd_hda_bind_sw,
17848 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17849 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17850 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17851 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17852 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17857 static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17858 .ops = &snd_hda_bind_sw,
17860 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17861 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17866 static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17867 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17868 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17869 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17870 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17871 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17872 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17873 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17879 static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17880 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17881 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17882 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17883 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17884 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17885 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17886 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17891 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17893 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17894 .name = "Channel Mode",
17895 .info = alc_ch_mode_info,
17896 .get = alc_ch_mode_get,
17897 .put = alc_ch_mode_put,
17902 static struct hda_verb alc662_init_verbs[] = {
17903 /* ADC: mute amp left and right */
17904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17905 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17907 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17909 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17911 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17914 /* Front Pin: output 0 (0x0c) */
17915 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17918 /* Rear Pin: output 1 (0x0d) */
17919 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17920 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17922 /* CLFE Pin: output 2 (0x0e) */
17923 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17924 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17926 /* Mic (rear) pin: input vref at 80% */
17927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17928 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17929 /* Front Mic pin: input vref at 80% */
17930 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17931 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17932 /* Line In pin: input */
17933 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17934 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17935 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17936 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17937 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17938 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17939 /* CD pin widget for input */
17940 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17942 /* FIXME: use matrix-type input source selection */
17943 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17945 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17951 static struct hda_verb alc662_eapd_init_verbs[] = {
17952 /* always trun on EAPD */
17953 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17954 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17958 static struct hda_verb alc662_sue_init_verbs[] = {
17959 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17960 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17964 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17965 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17966 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17970 /* Set Unsolicited Event*/
17971 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17973 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17977 static struct hda_verb alc663_m51va_init_verbs[] = {
17978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17979 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17980 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17981 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17982 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17983 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17985 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17986 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17990 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17991 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17992 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17993 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17996 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17997 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18001 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18002 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18003 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18004 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18005 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18008 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18009 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18013 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
18014 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18016 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18017 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18019 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18020 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18024 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18025 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18026 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18027 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18028 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18030 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18031 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18034 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18035 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18036 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18040 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18041 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18042 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18043 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18044 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18045 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18046 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18047 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18049 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18050 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18051 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18052 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18056 static struct hda_verb alc663_g71v_init_verbs[] = {
18057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18058 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18059 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18061 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18062 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18063 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18065 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18066 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18067 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18071 static struct hda_verb alc663_g50v_init_verbs[] = {
18072 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18073 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18074 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18076 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18077 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18081 static struct hda_verb alc662_ecs_init_verbs[] = {
18082 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18083 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18084 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18085 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18089 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18090 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18091 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18092 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18093 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18094 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18095 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18096 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18098 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18099 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18100 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18104 static struct hda_verb alc272_dell_init_verbs[] = {
18105 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18106 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18107 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18108 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18109 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18110 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18111 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18112 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18113 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18114 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18115 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18119 static struct hda_verb alc663_mode7_init_verbs[] = {
18120 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18121 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18122 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18123 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18124 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18125 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18126 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18127 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18128 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18129 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18130 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18132 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18133 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18134 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18138 static struct hda_verb alc663_mode8_init_verbs[] = {
18139 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18141 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18142 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18143 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18144 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18145 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18146 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18147 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18148 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18149 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18150 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18151 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18152 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18153 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18154 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18158 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18159 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18160 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18164 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18165 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18166 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18170 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18172 unsigned int present;
18173 unsigned char bits;
18175 present = snd_hda_jack_detect(codec, 0x14);
18176 bits = present ? HDA_AMP_MUTE : 0;
18178 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18179 HDA_AMP_MUTE, bits);
18182 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18184 unsigned int present;
18185 unsigned char bits;
18187 present = snd_hda_jack_detect(codec, 0x1b);
18188 bits = present ? HDA_AMP_MUTE : 0;
18190 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18191 HDA_AMP_MUTE, bits);
18192 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18193 HDA_AMP_MUTE, bits);
18196 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18199 if ((res >> 26) == ALC880_HP_EVENT)
18200 alc662_lenovo_101e_all_automute(codec);
18201 if ((res >> 26) == ALC880_FRONT_EVENT)
18202 alc662_lenovo_101e_ispeaker_automute(codec);
18205 /* unsolicited event for HP jack sensing */
18206 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18209 if ((res >> 26) == ALC880_MIC_EVENT)
18210 alc_mic_automute(codec);
18212 alc262_hippo_unsol_event(codec, res);
18215 static void alc662_eeepc_setup(struct hda_codec *codec)
18217 struct alc_spec *spec = codec->spec;
18219 alc262_hippo1_setup(codec);
18220 spec->ext_mic.pin = 0x18;
18221 spec->ext_mic.mux_idx = 0;
18222 spec->int_mic.pin = 0x19;
18223 spec->int_mic.mux_idx = 1;
18224 spec->auto_mic = 1;
18227 static void alc662_eeepc_inithook(struct hda_codec *codec)
18229 alc262_hippo_automute(codec);
18230 alc_mic_automute(codec);
18233 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18235 struct alc_spec *spec = codec->spec;
18237 spec->autocfg.hp_pins[0] = 0x14;
18238 spec->autocfg.speaker_pins[0] = 0x1b;
18241 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18243 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18245 unsigned int present;
18246 unsigned char bits;
18248 present = snd_hda_jack_detect(codec, 0x21);
18249 bits = present ? HDA_AMP_MUTE : 0;
18250 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18251 HDA_AMP_MUTE, bits);
18252 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18253 HDA_AMP_MUTE, bits);
18256 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18258 unsigned int present;
18259 unsigned char bits;
18261 present = snd_hda_jack_detect(codec, 0x21);
18262 bits = present ? HDA_AMP_MUTE : 0;
18263 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18264 HDA_AMP_MUTE, bits);
18265 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18266 HDA_AMP_MUTE, bits);
18267 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18268 HDA_AMP_MUTE, bits);
18269 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18270 HDA_AMP_MUTE, bits);
18273 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18275 unsigned int present;
18276 unsigned char bits;
18278 present = snd_hda_jack_detect(codec, 0x15);
18279 bits = present ? HDA_AMP_MUTE : 0;
18280 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18281 HDA_AMP_MUTE, bits);
18282 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18283 HDA_AMP_MUTE, bits);
18284 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18285 HDA_AMP_MUTE, bits);
18286 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18287 HDA_AMP_MUTE, bits);
18290 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18292 unsigned int present;
18293 unsigned char bits;
18295 present = snd_hda_jack_detect(codec, 0x1b);
18296 bits = present ? 0 : PIN_OUT;
18297 snd_hda_codec_write(codec, 0x14, 0,
18298 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18301 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18303 unsigned int present1, present2;
18305 present1 = snd_hda_jack_detect(codec, 0x21);
18306 present2 = snd_hda_jack_detect(codec, 0x15);
18308 if (present1 || present2) {
18309 snd_hda_codec_write_cache(codec, 0x14, 0,
18310 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18312 snd_hda_codec_write_cache(codec, 0x14, 0,
18313 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18317 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18319 unsigned int present1, present2;
18321 present1 = snd_hda_jack_detect(codec, 0x1b);
18322 present2 = snd_hda_jack_detect(codec, 0x15);
18324 if (present1 || present2) {
18325 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18326 HDA_AMP_MUTE, HDA_AMP_MUTE);
18327 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18328 HDA_AMP_MUTE, HDA_AMP_MUTE);
18330 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18332 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18337 static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18339 unsigned int present1, present2;
18341 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18342 AC_VERB_GET_PIN_SENSE, 0)
18343 & AC_PINSENSE_PRESENCE;
18344 present2 = snd_hda_codec_read(codec, 0x21, 0,
18345 AC_VERB_GET_PIN_SENSE, 0)
18346 & AC_PINSENSE_PRESENCE;
18348 if (present1 || present2) {
18349 snd_hda_codec_write_cache(codec, 0x14, 0,
18350 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18351 snd_hda_codec_write_cache(codec, 0x17, 0,
18352 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18354 snd_hda_codec_write_cache(codec, 0x14, 0,
18355 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18356 snd_hda_codec_write_cache(codec, 0x17, 0,
18357 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18361 static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18363 unsigned int present1, present2;
18365 present1 = snd_hda_codec_read(codec, 0x21, 0,
18366 AC_VERB_GET_PIN_SENSE, 0)
18367 & AC_PINSENSE_PRESENCE;
18368 present2 = snd_hda_codec_read(codec, 0x15, 0,
18369 AC_VERB_GET_PIN_SENSE, 0)
18370 & AC_PINSENSE_PRESENCE;
18372 if (present1 || present2) {
18373 snd_hda_codec_write_cache(codec, 0x14, 0,
18374 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18375 snd_hda_codec_write_cache(codec, 0x17, 0,
18376 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18378 snd_hda_codec_write_cache(codec, 0x14, 0,
18379 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18380 snd_hda_codec_write_cache(codec, 0x17, 0,
18381 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18385 static void alc663_m51va_unsol_event(struct hda_codec *codec,
18388 switch (res >> 26) {
18389 case ALC880_HP_EVENT:
18390 alc663_m51va_speaker_automute(codec);
18392 case ALC880_MIC_EVENT:
18393 alc_mic_automute(codec);
18398 static void alc663_m51va_setup(struct hda_codec *codec)
18400 struct alc_spec *spec = codec->spec;
18401 spec->ext_mic.pin = 0x18;
18402 spec->ext_mic.mux_idx = 0;
18403 spec->int_mic.pin = 0x12;
18404 spec->int_mic.mux_idx = 9;
18405 spec->auto_mic = 1;
18408 static void alc663_m51va_inithook(struct hda_codec *codec)
18410 alc663_m51va_speaker_automute(codec);
18411 alc_mic_automute(codec);
18414 /* ***************** Mode1 ******************************/
18415 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
18417 static void alc663_mode1_setup(struct hda_codec *codec)
18419 struct alc_spec *spec = codec->spec;
18420 spec->ext_mic.pin = 0x18;
18421 spec->ext_mic.mux_idx = 0;
18422 spec->int_mic.pin = 0x19;
18423 spec->int_mic.mux_idx = 1;
18424 spec->auto_mic = 1;
18427 #define alc663_mode1_inithook alc663_m51va_inithook
18429 /* ***************** Mode2 ******************************/
18430 static void alc662_mode2_unsol_event(struct hda_codec *codec,
18433 switch (res >> 26) {
18434 case ALC880_HP_EVENT:
18435 alc662_f5z_speaker_automute(codec);
18437 case ALC880_MIC_EVENT:
18438 alc_mic_automute(codec);
18443 #define alc662_mode2_setup alc663_mode1_setup
18445 static void alc662_mode2_inithook(struct hda_codec *codec)
18447 alc662_f5z_speaker_automute(codec);
18448 alc_mic_automute(codec);
18450 /* ***************** Mode3 ******************************/
18451 static void alc663_mode3_unsol_event(struct hda_codec *codec,
18454 switch (res >> 26) {
18455 case ALC880_HP_EVENT:
18456 alc663_two_hp_m1_speaker_automute(codec);
18458 case ALC880_MIC_EVENT:
18459 alc_mic_automute(codec);
18464 #define alc663_mode3_setup alc663_mode1_setup
18466 static void alc663_mode3_inithook(struct hda_codec *codec)
18468 alc663_two_hp_m1_speaker_automute(codec);
18469 alc_mic_automute(codec);
18471 /* ***************** Mode4 ******************************/
18472 static void alc663_mode4_unsol_event(struct hda_codec *codec,
18475 switch (res >> 26) {
18476 case ALC880_HP_EVENT:
18477 alc663_21jd_two_speaker_automute(codec);
18479 case ALC880_MIC_EVENT:
18480 alc_mic_automute(codec);
18485 #define alc663_mode4_setup alc663_mode1_setup
18487 static void alc663_mode4_inithook(struct hda_codec *codec)
18489 alc663_21jd_two_speaker_automute(codec);
18490 alc_mic_automute(codec);
18492 /* ***************** Mode5 ******************************/
18493 static void alc663_mode5_unsol_event(struct hda_codec *codec,
18496 switch (res >> 26) {
18497 case ALC880_HP_EVENT:
18498 alc663_15jd_two_speaker_automute(codec);
18500 case ALC880_MIC_EVENT:
18501 alc_mic_automute(codec);
18506 #define alc663_mode5_setup alc663_mode1_setup
18508 static void alc663_mode5_inithook(struct hda_codec *codec)
18510 alc663_15jd_two_speaker_automute(codec);
18511 alc_mic_automute(codec);
18513 /* ***************** Mode6 ******************************/
18514 static void alc663_mode6_unsol_event(struct hda_codec *codec,
18517 switch (res >> 26) {
18518 case ALC880_HP_EVENT:
18519 alc663_two_hp_m2_speaker_automute(codec);
18521 case ALC880_MIC_EVENT:
18522 alc_mic_automute(codec);
18527 #define alc663_mode6_setup alc663_mode1_setup
18529 static void alc663_mode6_inithook(struct hda_codec *codec)
18531 alc663_two_hp_m2_speaker_automute(codec);
18532 alc_mic_automute(codec);
18535 /* ***************** Mode7 ******************************/
18536 static void alc663_mode7_unsol_event(struct hda_codec *codec,
18539 switch (res >> 26) {
18540 case ALC880_HP_EVENT:
18541 alc663_two_hp_m7_speaker_automute(codec);
18543 case ALC880_MIC_EVENT:
18544 alc_mic_automute(codec);
18549 #define alc663_mode7_setup alc663_mode1_setup
18551 static void alc663_mode7_inithook(struct hda_codec *codec)
18553 alc663_two_hp_m7_speaker_automute(codec);
18554 alc_mic_automute(codec);
18557 /* ***************** Mode8 ******************************/
18558 static void alc663_mode8_unsol_event(struct hda_codec *codec,
18561 switch (res >> 26) {
18562 case ALC880_HP_EVENT:
18563 alc663_two_hp_m8_speaker_automute(codec);
18565 case ALC880_MIC_EVENT:
18566 alc_mic_automute(codec);
18571 #define alc663_mode8_setup alc663_m51va_setup
18573 static void alc663_mode8_inithook(struct hda_codec *codec)
18575 alc663_two_hp_m8_speaker_automute(codec);
18576 alc_mic_automute(codec);
18579 static void alc663_g71v_hp_automute(struct hda_codec *codec)
18581 unsigned int present;
18582 unsigned char bits;
18584 present = snd_hda_jack_detect(codec, 0x21);
18585 bits = present ? HDA_AMP_MUTE : 0;
18586 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18587 HDA_AMP_MUTE, bits);
18588 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18589 HDA_AMP_MUTE, bits);
18592 static void alc663_g71v_front_automute(struct hda_codec *codec)
18594 unsigned int present;
18595 unsigned char bits;
18597 present = snd_hda_jack_detect(codec, 0x15);
18598 bits = present ? HDA_AMP_MUTE : 0;
18599 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18600 HDA_AMP_MUTE, bits);
18603 static void alc663_g71v_unsol_event(struct hda_codec *codec,
18606 switch (res >> 26) {
18607 case ALC880_HP_EVENT:
18608 alc663_g71v_hp_automute(codec);
18610 case ALC880_FRONT_EVENT:
18611 alc663_g71v_front_automute(codec);
18613 case ALC880_MIC_EVENT:
18614 alc_mic_automute(codec);
18619 #define alc663_g71v_setup alc663_m51va_setup
18621 static void alc663_g71v_inithook(struct hda_codec *codec)
18623 alc663_g71v_front_automute(codec);
18624 alc663_g71v_hp_automute(codec);
18625 alc_mic_automute(codec);
18628 static void alc663_g50v_unsol_event(struct hda_codec *codec,
18631 switch (res >> 26) {
18632 case ALC880_HP_EVENT:
18633 alc663_m51va_speaker_automute(codec);
18635 case ALC880_MIC_EVENT:
18636 alc_mic_automute(codec);
18641 #define alc663_g50v_setup alc663_m51va_setup
18643 static void alc663_g50v_inithook(struct hda_codec *codec)
18645 alc663_m51va_speaker_automute(codec);
18646 alc_mic_automute(codec);
18649 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18650 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18651 ALC262_HIPPO_MASTER_SWITCH,
18653 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18654 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18655 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18657 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18658 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18659 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18663 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18664 /* Master Playback automatically created from Speaker and Headphone */
18665 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18666 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18667 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18668 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18671 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18672 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18674 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18675 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18676 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18680 #ifdef CONFIG_SND_HDA_POWER_SAVE
18681 #define alc662_loopbacks alc880_loopbacks
18685 /* pcm configuration: identical with ALC880 */
18686 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
18687 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
18688 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
18689 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
18692 * configuration and preset
18694 static const char * const alc662_models[ALC662_MODEL_LAST] = {
18695 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18696 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18697 [ALC662_3ST_6ch] = "3stack-6ch",
18698 [ALC662_5ST_DIG] = "5stack-dig",
18699 [ALC662_LENOVO_101E] = "lenovo-101e",
18700 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18701 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18702 [ALC662_ECS] = "ecs",
18703 [ALC663_ASUS_M51VA] = "m51va",
18704 [ALC663_ASUS_G71V] = "g71v",
18705 [ALC663_ASUS_H13] = "h13",
18706 [ALC663_ASUS_G50V] = "g50v",
18707 [ALC663_ASUS_MODE1] = "asus-mode1",
18708 [ALC662_ASUS_MODE2] = "asus-mode2",
18709 [ALC663_ASUS_MODE3] = "asus-mode3",
18710 [ALC663_ASUS_MODE4] = "asus-mode4",
18711 [ALC663_ASUS_MODE5] = "asus-mode5",
18712 [ALC663_ASUS_MODE6] = "asus-mode6",
18713 [ALC663_ASUS_MODE7] = "asus-mode7",
18714 [ALC663_ASUS_MODE8] = "asus-mode8",
18715 [ALC272_DELL] = "dell",
18716 [ALC272_DELL_ZM1] = "dell-zm1",
18717 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18718 [ALC662_AUTO] = "auto",
18721 static struct snd_pci_quirk alc662_cfg_tbl[] = {
18722 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18723 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18724 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18725 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18726 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18727 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18728 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18729 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18730 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18731 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18732 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18733 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18734 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18735 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18736 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18737 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18738 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18739 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18740 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18741 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18742 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18743 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18744 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18745 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18746 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18747 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18748 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18749 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18750 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18751 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18752 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18753 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18754 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18755 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18756 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18757 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18758 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18759 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18760 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18761 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18762 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18763 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18764 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18765 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18766 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18767 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18768 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18769 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18770 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18771 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18772 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18773 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18774 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18775 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18776 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18777 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18778 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18779 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18780 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18781 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18782 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18783 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18784 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18785 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18786 ALC662_3ST_6ch_DIG),
18787 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18788 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18789 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18790 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18791 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18792 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18793 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18794 ALC662_3ST_6ch_DIG),
18795 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18797 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18801 static struct alc_config_preset alc662_presets[] = {
18802 [ALC662_3ST_2ch_DIG] = {
18803 .mixers = { alc662_3ST_2ch_mixer },
18804 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18805 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18806 .dac_nids = alc662_dac_nids,
18807 .dig_out_nid = ALC662_DIGOUT_NID,
18808 .dig_in_nid = ALC662_DIGIN_NID,
18809 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18810 .channel_mode = alc662_3ST_2ch_modes,
18811 .input_mux = &alc662_capture_source,
18813 [ALC662_3ST_6ch_DIG] = {
18814 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18815 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18816 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18817 .dac_nids = alc662_dac_nids,
18818 .dig_out_nid = ALC662_DIGOUT_NID,
18819 .dig_in_nid = ALC662_DIGIN_NID,
18820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18821 .channel_mode = alc662_3ST_6ch_modes,
18823 .input_mux = &alc662_capture_source,
18825 [ALC662_3ST_6ch] = {
18826 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18827 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18828 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18829 .dac_nids = alc662_dac_nids,
18830 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18831 .channel_mode = alc662_3ST_6ch_modes,
18833 .input_mux = &alc662_capture_source,
18835 [ALC662_5ST_DIG] = {
18836 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18837 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18838 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18839 .dac_nids = alc662_dac_nids,
18840 .dig_out_nid = ALC662_DIGOUT_NID,
18841 .dig_in_nid = ALC662_DIGIN_NID,
18842 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18843 .channel_mode = alc662_5stack_modes,
18844 .input_mux = &alc662_capture_source,
18846 [ALC662_LENOVO_101E] = {
18847 .mixers = { alc662_lenovo_101e_mixer },
18848 .init_verbs = { alc662_init_verbs,
18849 alc662_eapd_init_verbs,
18850 alc662_sue_init_verbs },
18851 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18852 .dac_nids = alc662_dac_nids,
18853 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18854 .channel_mode = alc662_3ST_2ch_modes,
18855 .input_mux = &alc662_lenovo_101e_capture_source,
18856 .unsol_event = alc662_lenovo_101e_unsol_event,
18857 .init_hook = alc662_lenovo_101e_all_automute,
18859 [ALC662_ASUS_EEEPC_P701] = {
18860 .mixers = { alc662_eeepc_p701_mixer },
18861 .init_verbs = { alc662_init_verbs,
18862 alc662_eapd_init_verbs,
18863 alc662_eeepc_sue_init_verbs },
18864 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18865 .dac_nids = alc662_dac_nids,
18866 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18867 .channel_mode = alc662_3ST_2ch_modes,
18868 .unsol_event = alc662_eeepc_unsol_event,
18869 .setup = alc662_eeepc_setup,
18870 .init_hook = alc662_eeepc_inithook,
18872 [ALC662_ASUS_EEEPC_EP20] = {
18873 .mixers = { alc662_eeepc_ep20_mixer,
18874 alc662_chmode_mixer },
18875 .init_verbs = { alc662_init_verbs,
18876 alc662_eapd_init_verbs,
18877 alc662_eeepc_ep20_sue_init_verbs },
18878 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18879 .dac_nids = alc662_dac_nids,
18880 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18881 .channel_mode = alc662_3ST_6ch_modes,
18882 .input_mux = &alc662_lenovo_101e_capture_source,
18883 .unsol_event = alc662_eeepc_unsol_event,
18884 .setup = alc662_eeepc_ep20_setup,
18885 .init_hook = alc662_eeepc_ep20_inithook,
18888 .mixers = { alc662_ecs_mixer },
18889 .init_verbs = { alc662_init_verbs,
18890 alc662_eapd_init_verbs,
18891 alc662_ecs_init_verbs },
18892 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18893 .dac_nids = alc662_dac_nids,
18894 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18895 .channel_mode = alc662_3ST_2ch_modes,
18896 .unsol_event = alc662_eeepc_unsol_event,
18897 .setup = alc662_eeepc_setup,
18898 .init_hook = alc662_eeepc_inithook,
18900 [ALC663_ASUS_M51VA] = {
18901 .mixers = { alc663_m51va_mixer },
18902 .init_verbs = { alc662_init_verbs,
18903 alc662_eapd_init_verbs,
18904 alc663_m51va_init_verbs },
18905 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18906 .dac_nids = alc662_dac_nids,
18907 .dig_out_nid = ALC662_DIGOUT_NID,
18908 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18909 .channel_mode = alc662_3ST_2ch_modes,
18910 .unsol_event = alc663_m51va_unsol_event,
18911 .setup = alc663_m51va_setup,
18912 .init_hook = alc663_m51va_inithook,
18914 [ALC663_ASUS_G71V] = {
18915 .mixers = { alc663_g71v_mixer },
18916 .init_verbs = { alc662_init_verbs,
18917 alc662_eapd_init_verbs,
18918 alc663_g71v_init_verbs },
18919 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18920 .dac_nids = alc662_dac_nids,
18921 .dig_out_nid = ALC662_DIGOUT_NID,
18922 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18923 .channel_mode = alc662_3ST_2ch_modes,
18924 .unsol_event = alc663_g71v_unsol_event,
18925 .setup = alc663_g71v_setup,
18926 .init_hook = alc663_g71v_inithook,
18928 [ALC663_ASUS_H13] = {
18929 .mixers = { alc663_m51va_mixer },
18930 .init_verbs = { alc662_init_verbs,
18931 alc662_eapd_init_verbs,
18932 alc663_m51va_init_verbs },
18933 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18934 .dac_nids = alc662_dac_nids,
18935 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18936 .channel_mode = alc662_3ST_2ch_modes,
18937 .unsol_event = alc663_m51va_unsol_event,
18938 .init_hook = alc663_m51va_inithook,
18940 [ALC663_ASUS_G50V] = {
18941 .mixers = { alc663_g50v_mixer },
18942 .init_verbs = { alc662_init_verbs,
18943 alc662_eapd_init_verbs,
18944 alc663_g50v_init_verbs },
18945 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18946 .dac_nids = alc662_dac_nids,
18947 .dig_out_nid = ALC662_DIGOUT_NID,
18948 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18949 .channel_mode = alc662_3ST_6ch_modes,
18950 .input_mux = &alc663_capture_source,
18951 .unsol_event = alc663_g50v_unsol_event,
18952 .setup = alc663_g50v_setup,
18953 .init_hook = alc663_g50v_inithook,
18955 [ALC663_ASUS_MODE1] = {
18956 .mixers = { alc663_m51va_mixer },
18957 .cap_mixer = alc662_auto_capture_mixer,
18958 .init_verbs = { alc662_init_verbs,
18959 alc662_eapd_init_verbs,
18960 alc663_21jd_amic_init_verbs },
18961 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18963 .dac_nids = alc662_dac_nids,
18964 .dig_out_nid = ALC662_DIGOUT_NID,
18965 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18966 .channel_mode = alc662_3ST_2ch_modes,
18967 .unsol_event = alc663_mode1_unsol_event,
18968 .setup = alc663_mode1_setup,
18969 .init_hook = alc663_mode1_inithook,
18971 [ALC662_ASUS_MODE2] = {
18972 .mixers = { alc662_1bjd_mixer },
18973 .cap_mixer = alc662_auto_capture_mixer,
18974 .init_verbs = { alc662_init_verbs,
18975 alc662_eapd_init_verbs,
18976 alc662_1bjd_amic_init_verbs },
18977 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18978 .dac_nids = alc662_dac_nids,
18979 .dig_out_nid = ALC662_DIGOUT_NID,
18980 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18981 .channel_mode = alc662_3ST_2ch_modes,
18982 .unsol_event = alc662_mode2_unsol_event,
18983 .setup = alc662_mode2_setup,
18984 .init_hook = alc662_mode2_inithook,
18986 [ALC663_ASUS_MODE3] = {
18987 .mixers = { alc663_two_hp_m1_mixer },
18988 .cap_mixer = alc662_auto_capture_mixer,
18989 .init_verbs = { alc662_init_verbs,
18990 alc662_eapd_init_verbs,
18991 alc663_two_hp_amic_m1_init_verbs },
18992 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18994 .dac_nids = alc662_dac_nids,
18995 .dig_out_nid = ALC662_DIGOUT_NID,
18996 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18997 .channel_mode = alc662_3ST_2ch_modes,
18998 .unsol_event = alc663_mode3_unsol_event,
18999 .setup = alc663_mode3_setup,
19000 .init_hook = alc663_mode3_inithook,
19002 [ALC663_ASUS_MODE4] = {
19003 .mixers = { alc663_asus_21jd_clfe_mixer },
19004 .cap_mixer = alc662_auto_capture_mixer,
19005 .init_verbs = { alc662_init_verbs,
19006 alc662_eapd_init_verbs,
19007 alc663_21jd_amic_init_verbs},
19008 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19010 .dac_nids = alc662_dac_nids,
19011 .dig_out_nid = ALC662_DIGOUT_NID,
19012 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19013 .channel_mode = alc662_3ST_2ch_modes,
19014 .unsol_event = alc663_mode4_unsol_event,
19015 .setup = alc663_mode4_setup,
19016 .init_hook = alc663_mode4_inithook,
19018 [ALC663_ASUS_MODE5] = {
19019 .mixers = { alc663_asus_15jd_clfe_mixer },
19020 .cap_mixer = alc662_auto_capture_mixer,
19021 .init_verbs = { alc662_init_verbs,
19022 alc662_eapd_init_verbs,
19023 alc663_15jd_amic_init_verbs },
19024 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19026 .dac_nids = alc662_dac_nids,
19027 .dig_out_nid = ALC662_DIGOUT_NID,
19028 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19029 .channel_mode = alc662_3ST_2ch_modes,
19030 .unsol_event = alc663_mode5_unsol_event,
19031 .setup = alc663_mode5_setup,
19032 .init_hook = alc663_mode5_inithook,
19034 [ALC663_ASUS_MODE6] = {
19035 .mixers = { alc663_two_hp_m2_mixer },
19036 .cap_mixer = alc662_auto_capture_mixer,
19037 .init_verbs = { alc662_init_verbs,
19038 alc662_eapd_init_verbs,
19039 alc663_two_hp_amic_m2_init_verbs },
19040 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19042 .dac_nids = alc662_dac_nids,
19043 .dig_out_nid = ALC662_DIGOUT_NID,
19044 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19045 .channel_mode = alc662_3ST_2ch_modes,
19046 .unsol_event = alc663_mode6_unsol_event,
19047 .setup = alc663_mode6_setup,
19048 .init_hook = alc663_mode6_inithook,
19050 [ALC663_ASUS_MODE7] = {
19051 .mixers = { alc663_mode7_mixer },
19052 .cap_mixer = alc662_auto_capture_mixer,
19053 .init_verbs = { alc662_init_verbs,
19054 alc662_eapd_init_verbs,
19055 alc663_mode7_init_verbs },
19056 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19058 .dac_nids = alc662_dac_nids,
19059 .dig_out_nid = ALC662_DIGOUT_NID,
19060 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19061 .channel_mode = alc662_3ST_2ch_modes,
19062 .unsol_event = alc663_mode7_unsol_event,
19063 .setup = alc663_mode7_setup,
19064 .init_hook = alc663_mode7_inithook,
19066 [ALC663_ASUS_MODE8] = {
19067 .mixers = { alc663_mode8_mixer },
19068 .cap_mixer = alc662_auto_capture_mixer,
19069 .init_verbs = { alc662_init_verbs,
19070 alc662_eapd_init_verbs,
19071 alc663_mode8_init_verbs },
19072 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19074 .dac_nids = alc662_dac_nids,
19075 .dig_out_nid = ALC662_DIGOUT_NID,
19076 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19077 .channel_mode = alc662_3ST_2ch_modes,
19078 .unsol_event = alc663_mode8_unsol_event,
19079 .setup = alc663_mode8_setup,
19080 .init_hook = alc663_mode8_inithook,
19083 .mixers = { alc663_m51va_mixer },
19084 .cap_mixer = alc272_auto_capture_mixer,
19085 .init_verbs = { alc662_init_verbs,
19086 alc662_eapd_init_verbs,
19087 alc272_dell_init_verbs },
19088 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19089 .dac_nids = alc272_dac_nids,
19090 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19091 .adc_nids = alc272_adc_nids,
19092 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19093 .capsrc_nids = alc272_capsrc_nids,
19094 .channel_mode = alc662_3ST_2ch_modes,
19095 .unsol_event = alc663_m51va_unsol_event,
19096 .setup = alc663_m51va_setup,
19097 .init_hook = alc663_m51va_inithook,
19099 [ALC272_DELL_ZM1] = {
19100 .mixers = { alc663_m51va_mixer },
19101 .cap_mixer = alc662_auto_capture_mixer,
19102 .init_verbs = { alc662_init_verbs,
19103 alc662_eapd_init_verbs,
19104 alc272_dell_zm1_init_verbs },
19105 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19106 .dac_nids = alc272_dac_nids,
19107 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19108 .adc_nids = alc662_adc_nids,
19110 .capsrc_nids = alc662_capsrc_nids,
19111 .channel_mode = alc662_3ST_2ch_modes,
19112 .unsol_event = alc663_m51va_unsol_event,
19113 .setup = alc663_m51va_setup,
19114 .init_hook = alc663_m51va_inithook,
19116 [ALC272_SAMSUNG_NC10] = {
19117 .mixers = { alc272_nc10_mixer },
19118 .init_verbs = { alc662_init_verbs,
19119 alc662_eapd_init_verbs,
19120 alc663_21jd_amic_init_verbs },
19121 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19122 .dac_nids = alc272_dac_nids,
19123 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19124 .channel_mode = alc662_3ST_2ch_modes,
19125 /*.input_mux = &alc272_nc10_capture_source,*/
19126 .unsol_event = alc663_mode4_unsol_event,
19127 .setup = alc663_mode4_setup,
19128 .init_hook = alc663_mode4_inithook,
19134 * BIOS auto configuration
19137 /* convert from MIX nid to DAC */
19138 static hda_nid_t alc662_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
19143 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
19144 for (i = 0; i < num; i++) {
19145 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
19151 /* get MIX nid connected to the given pin targeted to DAC */
19152 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19158 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19159 for (i = 0; i < num; i++) {
19160 if (alc662_mix_to_dac(codec, mix[i]) == dac)
19166 /* look for an empty DAC slot */
19167 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19169 struct alc_spec *spec = codec->spec;
19173 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19176 for (i = 0; i < num; i++) {
19177 hda_nid_t nid = alc662_mix_to_dac(codec, srcs[i]);
19180 for (j = 0; j < spec->multiout.num_dacs; j++)
19181 if (spec->multiout.dac_nids[j] == nid)
19183 if (j >= spec->multiout.num_dacs)
19189 /* fill in the dac_nids table from the parsed pin configuration */
19190 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19191 const struct auto_pin_cfg *cfg)
19193 struct alc_spec *spec = codec->spec;
19197 spec->multiout.dac_nids = spec->private_dac_nids;
19198 for (i = 0; i < cfg->line_outs; i++) {
19199 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19202 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19207 static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19208 hda_nid_t nid, int idx, unsigned int chs)
19210 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19211 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19214 static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19215 hda_nid_t nid, int idx, unsigned int chs)
19217 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19218 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19221 #define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19222 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19223 #define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19224 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19225 #define alc662_add_stereo_vol(spec, pfx, nid) \
19226 alc662_add_vol_ctl(spec, pfx, nid, 3)
19227 #define alc662_add_stereo_sw(spec, pfx, nid) \
19228 alc662_add_sw_ctl(spec, pfx, nid, 3)
19230 /* add playback controls from the parsed DAC table */
19231 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19232 const struct auto_pin_cfg *cfg)
19234 struct alc_spec *spec = codec->spec;
19235 static const char * const chname[4] = {
19236 "Front", "Surround", NULL /*CLFE*/, "Side"
19238 const char *pfx = alc_get_line_out_pfx(cfg, true);
19239 hda_nid_t nid, mix;
19242 for (i = 0; i < cfg->line_outs; i++) {
19243 nid = spec->multiout.dac_nids[i];
19246 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19249 if (!pfx && i == 2) {
19251 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19254 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19257 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19260 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19264 const char *name = pfx;
19270 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
19273 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
19281 /* add playback controls for speaker and HP outputs */
19282 /* return DAC nid if any new DAC is assigned */
19283 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19286 struct alc_spec *spec = codec->spec;
19287 hda_nid_t nid, mix;
19292 nid = alc662_look_for_dac(codec, pin);
19294 /* the corresponding DAC is already occupied */
19295 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19296 return 0; /* no way */
19297 /* create a switch only */
19298 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19299 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19302 mix = alc662_dac_to_mix(codec, pin, nid);
19305 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19308 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19314 /* create playback/capture controls for input pins */
19315 #define alc662_auto_create_input_ctls \
19316 alc882_auto_create_input_ctls
19318 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19319 hda_nid_t nid, int pin_type,
19323 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19325 alc_set_pin_output(codec, nid, pin_type);
19326 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19327 for (i = 0; i < num; i++) {
19328 if (alc662_mix_to_dac(codec, srcs[i]) != dac)
19330 /* need the manual connection? */
19332 snd_hda_codec_write(codec, nid, 0,
19333 AC_VERB_SET_CONNECT_SEL, i);
19334 /* unmute mixer widget inputs */
19335 snd_hda_codec_write(codec, srcs[i], 0,
19336 AC_VERB_SET_AMP_GAIN_MUTE,
19338 snd_hda_codec_write(codec, srcs[i], 0,
19339 AC_VERB_SET_AMP_GAIN_MUTE,
19345 static void alc662_auto_init_multi_out(struct hda_codec *codec)
19347 struct alc_spec *spec = codec->spec;
19348 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19351 for (i = 0; i <= HDA_SIDE; i++) {
19352 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19354 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19355 spec->multiout.dac_nids[i]);
19359 static void alc662_auto_init_hp_out(struct hda_codec *codec)
19361 struct alc_spec *spec = codec->spec;
19364 pin = spec->autocfg.hp_pins[0];
19366 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19367 spec->multiout.hp_nid);
19368 pin = spec->autocfg.speaker_pins[0];
19370 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19371 spec->multiout.extra_out_nid[0]);
19374 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19376 static void alc662_auto_init_analog_input(struct hda_codec *codec)
19378 struct alc_spec *spec = codec->spec;
19379 struct auto_pin_cfg *cfg = &spec->autocfg;
19382 for (i = 0; i < cfg->num_inputs; i++) {
19383 hda_nid_t nid = cfg->inputs[i].pin;
19384 if (alc_is_input_pin(codec, nid)) {
19385 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19386 if (nid != ALC662_PIN_CD_NID &&
19387 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19388 snd_hda_codec_write(codec, nid, 0,
19389 AC_VERB_SET_AMP_GAIN_MUTE,
19395 #define alc662_auto_init_input_src alc882_auto_init_input_src
19397 static int alc662_parse_auto_config(struct hda_codec *codec)
19399 struct alc_spec *spec = codec->spec;
19401 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19403 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19407 if (!spec->autocfg.line_outs)
19408 return 0; /* can't find valid BIOS pin config */
19410 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19413 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19416 err = alc662_auto_create_extra_out(codec,
19417 spec->autocfg.speaker_pins[0],
19422 spec->multiout.extra_out_nid[0] = err;
19423 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19428 spec->multiout.hp_nid = err;
19429 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19433 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19435 alc_auto_parse_digital(codec);
19437 if (spec->kctls.list)
19438 add_mixer(spec, spec->kctls.list);
19440 spec->num_mux_defs = 1;
19441 spec->input_mux = &spec->private_imux[0];
19443 err = alc_auto_add_mic_boost(codec);
19447 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19448 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19449 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19451 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19456 /* additional initialization for auto-configuration model */
19457 static void alc662_auto_init(struct hda_codec *codec)
19459 struct alc_spec *spec = codec->spec;
19460 alc662_auto_init_multi_out(codec);
19461 alc662_auto_init_hp_out(codec);
19462 alc662_auto_init_analog_input(codec);
19463 alc662_auto_init_input_src(codec);
19464 alc_auto_init_digital(codec);
19465 if (spec->unsol_event)
19466 alc_inithook(codec);
19469 static void alc272_fixup_mario(struct hda_codec *codec,
19470 const struct alc_fixup *fix, int action)
19472 if (action != ALC_FIXUP_ACT_PROBE)
19474 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19475 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19476 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19477 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19478 (0 << AC_AMPCAP_MUTE_SHIFT)))
19479 printk(KERN_WARNING
19480 "hda_codec: failed to override amp caps for NID 0x2\n");
19484 ALC662_FIXUP_ASPIRE,
19485 ALC662_FIXUP_IDEAPAD,
19486 ALC272_FIXUP_MARIO,
19487 ALC662_FIXUP_CZC_P10T,
19488 ALC662_FIXUP_GIGABYTE,
19491 static const struct alc_fixup alc662_fixups[] = {
19492 [ALC662_FIXUP_ASPIRE] = {
19493 .type = ALC_FIXUP_PINS,
19494 .v.pins = (const struct alc_pincfg[]) {
19495 { 0x15, 0x99130112 }, /* subwoofer */
19499 [ALC662_FIXUP_IDEAPAD] = {
19500 .type = ALC_FIXUP_PINS,
19501 .v.pins = (const struct alc_pincfg[]) {
19502 { 0x17, 0x99130112 }, /* subwoofer */
19506 [ALC272_FIXUP_MARIO] = {
19507 .type = ALC_FIXUP_FUNC,
19508 .v.func = alc272_fixup_mario,
19510 [ALC662_FIXUP_CZC_P10T] = {
19511 .type = ALC_FIXUP_VERBS,
19512 .v.verbs = (const struct hda_verb[]) {
19513 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19517 [ALC662_FIXUP_GIGABYTE] = {
19518 .type = ALC_FIXUP_PINS,
19519 .v.pins = (const struct alc_pincfg[]) {
19520 { 0x14, 0x1114410 }, /* set as speaker */
19526 static struct snd_pci_quirk alc662_fixup_tbl[] = {
19527 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19528 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19529 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19530 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE),
19531 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19532 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19533 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19537 static const struct alc_model_fixup alc662_fixup_models[] = {
19538 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19543 static int patch_alc662(struct hda_codec *codec)
19545 struct alc_spec *spec;
19546 int err, board_config;
19549 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19553 codec->spec = spec;
19555 alc_auto_parse_customize_define(codec);
19557 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19559 coef = alc_read_coef_idx(codec, 0);
19560 if (coef == 0x8020 || coef == 0x8011)
19561 alc_codec_rename(codec, "ALC661");
19562 else if (coef & (1 << 14) &&
19563 codec->bus->pci->subsystem_vendor == 0x1025 &&
19564 spec->cdefine.platform_type == 1)
19565 alc_codec_rename(codec, "ALC272X");
19566 else if (coef == 0x4011)
19567 alc_codec_rename(codec, "ALC656");
19569 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19572 if (board_config < 0) {
19573 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19575 board_config = ALC662_AUTO;
19578 if (board_config == ALC662_AUTO) {
19579 alc_pick_fixup(codec, alc662_fixup_models,
19580 alc662_fixup_tbl, alc662_fixups);
19581 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19582 /* automatic parse from the BIOS config */
19583 err = alc662_parse_auto_config(codec);
19589 "hda_codec: Cannot set up configuration "
19590 "from BIOS. Using base mode...\n");
19591 board_config = ALC662_3ST_2ch_DIG;
19595 if (has_cdefine_beep(codec)) {
19596 err = snd_hda_attach_beep_device(codec, 0x1);
19603 if (board_config != ALC662_AUTO)
19604 setup_preset(codec, &alc662_presets[board_config]);
19606 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19607 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19609 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19610 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19612 if (!spec->adc_nids) {
19613 spec->adc_nids = alc662_adc_nids;
19614 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19616 if (!spec->capsrc_nids)
19617 spec->capsrc_nids = alc662_capsrc_nids;
19619 if (!spec->cap_mixer)
19620 set_capture_mixer(codec);
19622 if (has_cdefine_beep(codec)) {
19623 switch (codec->vendor_id) {
19625 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19630 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19633 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19637 spec->vmaster_nid = 0x02;
19639 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19641 codec->patch_ops = alc_patch_ops;
19642 if (board_config == ALC662_AUTO)
19643 spec->init_hook = alc662_auto_init;
19644 spec->shutup = alc_eapd_shutup;
19646 alc_init_jacks(codec);
19648 #ifdef CONFIG_SND_HDA_POWER_SAVE
19649 if (!spec->loopback.amplist)
19650 spec->loopback.amplist = alc662_loopbacks;
19656 static int patch_alc888(struct hda_codec *codec)
19658 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19659 kfree(codec->chip_name);
19660 if (codec->vendor_id == 0x10ec0887)
19661 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19663 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19664 if (!codec->chip_name) {
19668 return patch_alc662(codec);
19670 return patch_alc882(codec);
19676 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19677 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19678 #define alc680_modes alc260_modes
19680 static hda_nid_t alc680_dac_nids[3] = {
19681 /* Lout1, Lout2, hp */
19685 static hda_nid_t alc680_adc_nids[3] = {
19687 /* DMIC, MIC, Line-in*/
19692 * Analog capture ADC cgange
19694 static void alc680_rec_autoswitch(struct hda_codec *codec)
19696 struct alc_spec *spec = codec->spec;
19697 struct auto_pin_cfg *cfg = &spec->autocfg;
19699 int type_found = AUTO_PIN_LAST;
19703 for (i = 0; i < cfg->num_inputs; i++) {
19704 nid = cfg->inputs[i].pin;
19705 if (!(snd_hda_query_pin_caps(codec, nid) &
19706 AC_PINCAP_PRES_DETECT))
19708 if (snd_hda_jack_detect(codec, nid)) {
19709 if (cfg->inputs[i].type < type_found) {
19710 type_found = cfg->inputs[i].type;
19718 snd_hda_get_connections(codec, pin_found, &nid, 1);
19720 if (nid != spec->cur_adc)
19721 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19722 spec->cur_adc = nid;
19723 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19724 spec->cur_adc_format);
19727 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19728 struct hda_codec *codec,
19729 unsigned int stream_tag,
19730 unsigned int format,
19731 struct snd_pcm_substream *substream)
19733 struct alc_spec *spec = codec->spec;
19735 spec->cur_adc = 0x07;
19736 spec->cur_adc_stream_tag = stream_tag;
19737 spec->cur_adc_format = format;
19739 alc680_rec_autoswitch(codec);
19743 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19744 struct hda_codec *codec,
19745 struct snd_pcm_substream *substream)
19747 snd_hda_codec_cleanup_stream(codec, 0x07);
19748 snd_hda_codec_cleanup_stream(codec, 0x08);
19749 snd_hda_codec_cleanup_stream(codec, 0x09);
19753 static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19754 .substreams = 1, /* can be overridden */
19757 /* NID is set in alc_build_pcms */
19759 .prepare = alc680_capture_pcm_prepare,
19760 .cleanup = alc680_capture_pcm_cleanup
19764 static struct snd_kcontrol_new alc680_base_mixer[] = {
19765 /* output mixer control */
19766 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19767 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19768 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19769 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19770 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19771 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19772 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19776 static struct hda_bind_ctls alc680_bind_cap_vol = {
19777 .ops = &snd_hda_bind_vol,
19779 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19780 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19781 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19786 static struct hda_bind_ctls alc680_bind_cap_switch = {
19787 .ops = &snd_hda_bind_sw,
19789 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19790 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19791 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19796 static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19797 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19798 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19803 * generic initialization of ADC, input mixers and output mixers
19805 static struct hda_verb alc680_init_verbs[] = {
19806 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19807 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19808 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19810 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19813 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19815 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19817 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19818 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19819 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19820 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19821 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19823 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19824 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19825 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19830 /* toggle speaker-output according to the hp-jack state */
19831 static void alc680_base_setup(struct hda_codec *codec)
19833 struct alc_spec *spec = codec->spec;
19835 spec->autocfg.hp_pins[0] = 0x16;
19836 spec->autocfg.speaker_pins[0] = 0x14;
19837 spec->autocfg.speaker_pins[1] = 0x15;
19838 spec->autocfg.num_inputs = 2;
19839 spec->autocfg.inputs[0].pin = 0x18;
19840 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19841 spec->autocfg.inputs[1].pin = 0x19;
19842 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19845 static void alc680_unsol_event(struct hda_codec *codec,
19848 if ((res >> 26) == ALC880_HP_EVENT)
19849 alc_automute_amp(codec);
19850 if ((res >> 26) == ALC880_MIC_EVENT)
19851 alc680_rec_autoswitch(codec);
19854 static void alc680_inithook(struct hda_codec *codec)
19856 alc_automute_amp(codec);
19857 alc680_rec_autoswitch(codec);
19860 /* create input playback/capture controls for the given pin */
19861 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19862 const char *ctlname, int idx)
19880 if (spec->multiout.dac_nids[0] != dac &&
19881 spec->multiout.dac_nids[1] != dac) {
19882 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19883 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19888 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19889 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19893 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19899 /* add playback controls from the parsed DAC table */
19900 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19901 const struct auto_pin_cfg *cfg)
19906 spec->multiout.dac_nids = spec->private_dac_nids;
19908 nid = cfg->line_out_pins[0];
19911 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19915 err = alc680_new_analog_output(spec, nid, name, 0);
19920 nid = cfg->speaker_pins[0];
19922 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19926 nid = cfg->hp_pins[0];
19928 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19936 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19937 hda_nid_t nid, int pin_type)
19939 alc_set_pin_output(codec, nid, pin_type);
19942 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19944 struct alc_spec *spec = codec->spec;
19945 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19947 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19948 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19952 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19954 struct alc_spec *spec = codec->spec;
19957 pin = spec->autocfg.hp_pins[0];
19959 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19960 pin = spec->autocfg.speaker_pins[0];
19962 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19965 /* pcm configuration: identical with ALC880 */
19966 #define alc680_pcm_analog_playback alc880_pcm_analog_playback
19967 #define alc680_pcm_analog_capture alc880_pcm_analog_capture
19968 #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19969 #define alc680_pcm_digital_playback alc880_pcm_digital_playback
19970 #define alc680_pcm_digital_capture alc880_pcm_digital_capture
19973 * BIOS auto configuration
19975 static int alc680_parse_auto_config(struct hda_codec *codec)
19977 struct alc_spec *spec = codec->spec;
19979 static hda_nid_t alc680_ignore[] = { 0 };
19981 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19986 if (!spec->autocfg.line_outs) {
19987 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19988 spec->multiout.max_channels = 2;
19989 spec->no_analog = 1;
19992 return 0; /* can't find valid BIOS pin config */
19994 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19998 spec->multiout.max_channels = 2;
20001 /* digital only support output */
20002 alc_auto_parse_digital(codec);
20003 if (spec->kctls.list)
20004 add_mixer(spec, spec->kctls.list);
20006 add_verb(spec, alc680_init_verbs);
20008 err = alc_auto_add_mic_boost(codec);
20015 #define alc680_auto_init_analog_input alc882_auto_init_analog_input
20017 /* init callback for auto-configuration model -- overriding the default init */
20018 static void alc680_auto_init(struct hda_codec *codec)
20020 struct alc_spec *spec = codec->spec;
20021 alc680_auto_init_multi_out(codec);
20022 alc680_auto_init_hp_out(codec);
20023 alc680_auto_init_analog_input(codec);
20024 alc_auto_init_digital(codec);
20025 if (spec->unsol_event)
20026 alc_inithook(codec);
20030 * configuration and preset
20032 static const char * const alc680_models[ALC680_MODEL_LAST] = {
20033 [ALC680_BASE] = "base",
20034 [ALC680_AUTO] = "auto",
20037 static struct snd_pci_quirk alc680_cfg_tbl[] = {
20038 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20042 static struct alc_config_preset alc680_presets[] = {
20044 .mixers = { alc680_base_mixer },
20045 .cap_mixer = alc680_master_capture_mixer,
20046 .init_verbs = { alc680_init_verbs },
20047 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20048 .dac_nids = alc680_dac_nids,
20049 .dig_out_nid = ALC680_DIGOUT_NID,
20050 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20051 .channel_mode = alc680_modes,
20052 .unsol_event = alc680_unsol_event,
20053 .setup = alc680_base_setup,
20054 .init_hook = alc680_inithook,
20059 static int patch_alc680(struct hda_codec *codec)
20061 struct alc_spec *spec;
20065 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20069 codec->spec = spec;
20071 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20075 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20076 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20078 board_config = ALC680_AUTO;
20081 if (board_config == ALC680_AUTO) {
20082 /* automatic parse from the BIOS config */
20083 err = alc680_parse_auto_config(codec);
20089 "hda_codec: Cannot set up configuration "
20090 "from BIOS. Using base mode...\n");
20091 board_config = ALC680_BASE;
20095 if (board_config != ALC680_AUTO)
20096 setup_preset(codec, &alc680_presets[board_config]);
20098 spec->stream_analog_playback = &alc680_pcm_analog_playback;
20099 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
20100 spec->stream_digital_playback = &alc680_pcm_digital_playback;
20101 spec->stream_digital_capture = &alc680_pcm_digital_capture;
20103 if (!spec->adc_nids) {
20104 spec->adc_nids = alc680_adc_nids;
20105 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20108 if (!spec->cap_mixer)
20109 set_capture_mixer(codec);
20111 spec->vmaster_nid = 0x02;
20113 codec->patch_ops = alc_patch_ops;
20114 if (board_config == ALC680_AUTO)
20115 spec->init_hook = alc680_auto_init;
20123 static struct hda_codec_preset snd_hda_preset_realtek[] = {
20124 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20125 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20126 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
20127 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
20128 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
20129 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20130 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20131 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20132 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20133 .patch = patch_alc861 },
20134 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20135 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20136 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
20137 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
20138 .patch = patch_alc882 },
20139 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20140 .patch = patch_alc662 },
20141 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20142 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20143 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
20144 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
20145 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
20146 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
20147 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
20148 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
20149 .patch = patch_alc882 },
20150 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
20151 .patch = patch_alc882 },
20152 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
20153 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
20154 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
20155 .patch = patch_alc882 },
20156 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20157 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20158 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20159 {} /* terminator */
20162 MODULE_ALIAS("snd-hda-codec-id:10ec*");
20164 MODULE_LICENSE("GPL");
20165 MODULE_DESCRIPTION("Realtek HD-audio codec");
20167 static struct hda_codec_preset_list realtek_list = {
20168 .preset = snd_hda_preset_realtek,
20169 .owner = THIS_MODULE,
20172 static int __init patch_realtek_init(void)
20174 return snd_hda_add_codec_preset(&realtek_list);
20177 static void __exit patch_realtek_exit(void)
20179 snd_hda_delete_codec_preset(&realtek_list);
20182 module_init(patch_realtek_init)
20183 module_exit(patch_realtek_exit)