2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include <sound/jack.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
36 #define ALC880_FRONT_EVENT 0x01
37 #define ALC880_DCVOL_EVENT 0x02
38 #define ALC880_HP_EVENT 0x04
39 #define ALC880_MIC_EVENT 0x08
41 /* ALC880 board config type */
65 #ifdef CONFIG_SND_DEBUG
69 ALC880_MODEL_LAST /* last tag */
83 #ifdef CONFIG_SND_DEBUG
87 ALC260_MODEL_LAST /* last tag */
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
111 ALC262_MODEL_LAST /* last tag */
121 ALC268_ACER_ASPIRE_ONE,
124 #ifdef CONFIG_SND_DEBUG
128 ALC268_MODEL_LAST /* last tag */
143 ALC269_MODEL_LAST /* last tag */
160 /* ALC861-VD models */
182 ALC662_ASUS_EEEPC_P701,
183 ALC662_ASUS_EEEPC_EP20,
225 ALC883_TARGA_2ch_DIG,
226 ALC883_TARGA_8ch_DIG,
229 ALC888_ACER_ASPIRE_4930G,
230 ALC888_ACER_ASPIRE_6530G,
231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G,
234 ALC883_MEDION_WIM2160,
236 ALC883_LENOVO_101E_2ch,
237 ALC883_LENOVO_NB0763,
238 ALC888_LENOVO_MS7195_DIG,
246 ALC883_FUJITSU_PI2515,
247 ALC888_FUJITSU_XA3530,
248 ALC883_3ST_6ch_INTEL,
268 #define GPIO_MASK 0x03
270 /* extra amp-initialization sequence types */
279 struct alc_mic_route {
281 unsigned char mux_idx;
282 unsigned char amix_idx;
285 #define MUX_IDX_UNDEF ((unsigned char)-1)
287 struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
296 unsigned int override:1;
297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
302 struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
315 /* codec parameterization */
316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
317 unsigned int num_mixers;
318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
321 const struct hda_verb *init_verbs[10]; /* initialization verbs
325 unsigned int num_init_verbs;
327 char stream_name_analog[32]; /* analog PCM stream */
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
333 char stream_name_digital[32]; /* digital PCM stream */
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
342 hda_nid_t alt_dac_nid;
343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
347 unsigned int num_adc_nids;
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
351 hda_nid_t mixer_nid; /* analog-mixer NID */
353 /* capture setup for dynamic dual-adc switch */
354 unsigned int cur_adc_idx;
356 unsigned int cur_adc_stream_tag;
357 unsigned int cur_adc_format;
360 unsigned int num_mux_defs;
361 const struct hda_input_mux *input_mux;
362 unsigned int cur_mux[3];
363 struct alc_mic_route ext_mic;
364 struct alc_mic_route dock_mic;
365 struct alc_mic_route int_mic;
368 const struct hda_channel_mode *channel_mode;
369 int num_channel_mode;
371 int const_channel_count;
372 int ext_channel_count;
374 /* PCM information */
375 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
377 /* dynamic controls, init_verbs and input_mux */
378 struct auto_pin_cfg autocfg;
379 struct alc_customize_define cdefine;
380 struct snd_array kctls;
381 struct hda_input_mux private_imux[3];
382 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
383 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
384 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
387 void (*init_hook)(struct hda_codec *codec);
388 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
389 #ifdef CONFIG_SND_HDA_POWER_SAVE
390 void (*power_hook)(struct hda_codec *codec);
392 void (*shutup)(struct hda_codec *codec);
394 /* for pin sensing */
395 unsigned int jack_present: 1;
396 unsigned int line_jack_present:1;
397 unsigned int master_mute:1;
398 unsigned int auto_mic:1;
399 unsigned int automute:1; /* HP automute enabled */
400 unsigned int detect_line:1; /* Line-out detection enabled */
401 unsigned int automute_lines:1; /* automute line-out as well */
402 unsigned int automute_hp_lo:1; /* both HP and LO available */
405 unsigned int no_analog :1; /* digital I/O only */
406 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
407 unsigned int single_input_src:1;
409 /* auto-mute control */
411 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
414 int codec_variant; /* flag for other variants */
416 /* for virtual master */
417 hda_nid_t vmaster_nid;
418 #ifdef CONFIG_SND_HDA_POWER_SAVE
419 struct hda_loopback_check loopback;
424 unsigned int pll_coef_idx, pll_coef_bit;
428 const struct alc_fixup *fixup_list;
429 const char *fixup_name;
433 struct alc_multi_io multi_io[4];
437 * configuration template - to be copied to the spec instance
439 struct alc_config_preset {
440 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
443 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
444 const struct hda_verb *init_verbs[5];
445 unsigned int num_dacs;
446 const hda_nid_t *dac_nids;
447 hda_nid_t dig_out_nid; /* optional */
448 hda_nid_t hp_nid; /* optional */
449 const hda_nid_t *slave_dig_outs;
450 unsigned int num_adc_nids;
451 const hda_nid_t *adc_nids;
452 const hda_nid_t *capsrc_nids;
453 hda_nid_t dig_in_nid;
454 unsigned int num_channel_mode;
455 const struct hda_channel_mode *channel_mode;
457 int const_channel_count;
458 unsigned int num_mux_defs;
459 const struct hda_input_mux *input_mux;
460 void (*unsol_event)(struct hda_codec *, unsigned int);
461 void (*setup)(struct hda_codec *);
462 void (*init_hook)(struct hda_codec *);
463 #ifdef CONFIG_SND_HDA_POWER_SAVE
464 const struct hda_amp_list *loopbacks;
465 void (*power_hook)(struct hda_codec *codec);
473 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
474 struct snd_ctl_elem_info *uinfo)
476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
477 struct alc_spec *spec = codec->spec;
478 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
479 if (mux_idx >= spec->num_mux_defs)
481 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
483 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
486 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_value *ucontrol)
489 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
490 struct alc_spec *spec = codec->spec;
491 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
493 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
497 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
501 struct alc_spec *spec = codec->spec;
502 const struct hda_input_mux *imux;
503 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
504 unsigned int mux_idx;
505 hda_nid_t nid = spec->capsrc_nids ?
506 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
509 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
510 imux = &spec->input_mux[mux_idx];
511 if (!imux->num_items && mux_idx > 0)
512 imux = &spec->input_mux[0];
514 type = get_wcaps_type(get_wcaps(codec, nid));
515 if (type == AC_WID_AUD_MIX) {
516 /* Matrix-mixer style (e.g. ALC882) */
517 unsigned int *cur_val = &spec->cur_mux[adc_idx];
520 idx = ucontrol->value.enumerated.item[0];
521 if (idx >= imux->num_items)
522 idx = imux->num_items - 1;
525 for (i = 0; i < imux->num_items; i++) {
526 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
527 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
528 imux->items[i].index,
534 /* MUX style (e.g. ALC880) */
535 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
536 &spec->cur_mux[adc_idx]);
541 * channel mode setting
543 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_info *uinfo)
546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
547 struct alc_spec *spec = codec->spec;
548 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
549 spec->num_channel_mode);
552 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
555 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
556 struct alc_spec *spec = codec->spec;
557 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
558 spec->num_channel_mode,
559 spec->ext_channel_count);
562 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
565 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566 struct alc_spec *spec = codec->spec;
567 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
568 spec->num_channel_mode,
569 &spec->ext_channel_count);
570 if (err >= 0 && !spec->const_channel_count) {
571 spec->multiout.max_channels = spec->ext_channel_count;
572 if (spec->need_dac_fix)
573 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
579 * Control the mode of pin widget settings via the mixer. "pc" is used
580 * instead of "%" to avoid consequences of accidentally treating the % as
581 * being part of a format specifier. Maximum allowed length of a value is
582 * 63 characters plus NULL terminator.
584 * Note: some retasking pin complexes seem to ignore requests for input
585 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
586 * are requested. Therefore order this list so that this behaviour will not
587 * cause problems when mixer clients move through the enum sequentially.
588 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
591 static const char * const alc_pin_mode_names[] = {
592 "Mic 50pc bias", "Mic 80pc bias",
593 "Line in", "Line out", "Headphone out",
595 static const unsigned char alc_pin_mode_values[] = {
596 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
598 /* The control can present all 5 options, or it can limit the options based
599 * in the pin being assumed to be exclusively an input or an output pin. In
600 * addition, "input" pins may or may not process the mic bias option
601 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
602 * accept requests for bias as of chip versions up to March 2006) and/or
603 * wiring in the computer.
605 #define ALC_PIN_DIR_IN 0x00
606 #define ALC_PIN_DIR_OUT 0x01
607 #define ALC_PIN_DIR_INOUT 0x02
608 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
609 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
611 /* Info about the pin modes supported by the different pin direction modes.
612 * For each direction the minimum and maximum values are given.
614 static const signed char alc_pin_mode_dir_info[5][2] = {
615 { 0, 2 }, /* ALC_PIN_DIR_IN */
616 { 3, 4 }, /* ALC_PIN_DIR_OUT */
617 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
618 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
619 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
621 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
622 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
623 #define alc_pin_mode_n_items(_dir) \
624 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
626 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_info *uinfo)
629 unsigned int item_num = uinfo->value.enumerated.item;
630 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
632 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
634 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
636 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
637 item_num = alc_pin_mode_min(dir);
638 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
642 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 hda_nid_t nid = kcontrol->private_value & 0xffff;
648 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
649 long *valp = ucontrol->value.integer.value;
650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
651 AC_VERB_GET_PIN_WIDGET_CONTROL,
654 /* Find enumerated value for current pinctl setting */
655 i = alc_pin_mode_min(dir);
656 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
658 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
662 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
663 struct snd_ctl_elem_value *ucontrol)
666 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
667 hda_nid_t nid = kcontrol->private_value & 0xffff;
668 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
669 long val = *ucontrol->value.integer.value;
670 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
671 AC_VERB_GET_PIN_WIDGET_CONTROL,
674 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
675 val = alc_pin_mode_min(dir);
677 change = pinctl != alc_pin_mode_values[val];
679 /* Set pin mode to that requested */
680 snd_hda_codec_write_cache(codec, nid, 0,
681 AC_VERB_SET_PIN_WIDGET_CONTROL,
682 alc_pin_mode_values[val]);
684 /* Also enable the retasking pin's input/output as required
685 * for the requested pin mode. Enum values of 2 or less are
688 * Dynamically switching the input/output buffers probably
689 * reduces noise slightly (particularly on input) so we'll
690 * do it. However, having both input and output buffers
691 * enabled simultaneously doesn't seem to be problematic if
692 * this turns out to be necessary in the future.
695 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
696 HDA_AMP_MUTE, HDA_AMP_MUTE);
697 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
700 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
701 HDA_AMP_MUTE, HDA_AMP_MUTE);
702 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
709 #define ALC_PIN_MODE(xname, nid, dir) \
710 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
711 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
712 .info = alc_pin_mode_info, \
713 .get = alc_pin_mode_get, \
714 .put = alc_pin_mode_put, \
715 .private_value = nid | (dir<<16) }
717 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
718 * together using a mask with more than one bit set. This control is
719 * currently used only by the ALC260 test model. At this stage they are not
720 * needed for any "production" models.
722 #ifdef CONFIG_SND_DEBUG
723 #define alc_gpio_data_info snd_ctl_boolean_mono_info
725 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
726 struct snd_ctl_elem_value *ucontrol)
728 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
729 hda_nid_t nid = kcontrol->private_value & 0xffff;
730 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
731 long *valp = ucontrol->value.integer.value;
732 unsigned int val = snd_hda_codec_read(codec, nid, 0,
733 AC_VERB_GET_GPIO_DATA, 0x00);
735 *valp = (val & mask) != 0;
738 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
739 struct snd_ctl_elem_value *ucontrol)
742 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
743 hda_nid_t nid = kcontrol->private_value & 0xffff;
744 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
745 long val = *ucontrol->value.integer.value;
746 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
747 AC_VERB_GET_GPIO_DATA,
750 /* Set/unset the masked GPIO bit(s) as needed */
751 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
756 snd_hda_codec_write_cache(codec, nid, 0,
757 AC_VERB_SET_GPIO_DATA, gpio_data);
761 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
762 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
763 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
764 .info = alc_gpio_data_info, \
765 .get = alc_gpio_data_get, \
766 .put = alc_gpio_data_put, \
767 .private_value = nid | (mask<<16) }
768 #endif /* CONFIG_SND_DEBUG */
770 /* A switch control to allow the enabling of the digital IO pins on the
771 * ALC260. This is incredibly simplistic; the intention of this control is
772 * to provide something in the test model allowing digital outputs to be
773 * identified if present. If models are found which can utilise these
774 * outputs a more complete mixer control can be devised for those models if
777 #ifdef CONFIG_SND_DEBUG
778 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
780 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
781 struct snd_ctl_elem_value *ucontrol)
783 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
784 hda_nid_t nid = kcontrol->private_value & 0xffff;
785 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
786 long *valp = ucontrol->value.integer.value;
787 unsigned int val = snd_hda_codec_read(codec, nid, 0,
788 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
790 *valp = (val & mask) != 0;
793 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
797 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
798 hda_nid_t nid = kcontrol->private_value & 0xffff;
799 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
800 long val = *ucontrol->value.integer.value;
801 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
802 AC_VERB_GET_DIGI_CONVERT_1,
805 /* Set/unset the masked control bit(s) as needed */
806 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
811 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
816 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
817 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
818 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
819 .info = alc_spdif_ctrl_info, \
820 .get = alc_spdif_ctrl_get, \
821 .put = alc_spdif_ctrl_put, \
822 .private_value = nid | (mask<<16) }
823 #endif /* CONFIG_SND_DEBUG */
825 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
826 * Again, this is only used in the ALC26x test models to help identify when
827 * the EAPD line must be asserted for features to work.
829 #ifdef CONFIG_SND_DEBUG
830 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
832 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
833 struct snd_ctl_elem_value *ucontrol)
835 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
836 hda_nid_t nid = kcontrol->private_value & 0xffff;
837 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
838 long *valp = ucontrol->value.integer.value;
839 unsigned int val = snd_hda_codec_read(codec, nid, 0,
840 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
842 *valp = (val & mask) != 0;
846 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
847 struct snd_ctl_elem_value *ucontrol)
850 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
851 hda_nid_t nid = kcontrol->private_value & 0xffff;
852 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
853 long val = *ucontrol->value.integer.value;
854 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
855 AC_VERB_GET_EAPD_BTLENABLE,
858 /* Set/unset the masked control bit(s) as needed */
859 change = (!val ? 0 : mask) != (ctrl_data & mask);
864 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
870 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
871 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
872 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
873 .info = alc_eapd_ctrl_info, \
874 .get = alc_eapd_ctrl_get, \
875 .put = alc_eapd_ctrl_put, \
876 .private_value = nid | (mask<<16) }
877 #endif /* CONFIG_SND_DEBUG */
880 * set up the input pin config (depending on the given auto-pin type)
882 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
885 unsigned int val = PIN_IN;
887 if (auto_pin_type == AUTO_PIN_MIC) {
890 oldval = snd_hda_codec_read(codec, nid, 0,
891 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
892 pincap = snd_hda_query_pin_caps(codec, nid);
893 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
894 /* if the default pin setup is vref50, we give it priority */
895 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
897 else if (pincap & AC_PINCAP_VREF_50)
899 else if (pincap & AC_PINCAP_VREF_100)
901 else if (pincap & AC_PINCAP_VREF_GRD)
904 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
907 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
909 struct alc_spec *spec = codec->spec;
910 struct auto_pin_cfg *cfg = &spec->autocfg;
912 if (!cfg->line_outs) {
913 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
914 cfg->line_out_pins[cfg->line_outs])
917 if (!cfg->speaker_outs) {
918 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
919 cfg->speaker_pins[cfg->speaker_outs])
923 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
924 cfg->hp_pins[cfg->hp_outs])
931 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
933 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
935 spec->mixers[spec->num_mixers++] = mix;
938 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
940 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
942 spec->init_verbs[spec->num_init_verbs++] = verb;
946 * set up from the preset table
948 static void setup_preset(struct hda_codec *codec,
949 const struct alc_config_preset *preset)
951 struct alc_spec *spec = codec->spec;
954 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
955 add_mixer(spec, preset->mixers[i]);
956 spec->cap_mixer = preset->cap_mixer;
957 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
959 add_verb(spec, preset->init_verbs[i]);
961 spec->channel_mode = preset->channel_mode;
962 spec->num_channel_mode = preset->num_channel_mode;
963 spec->need_dac_fix = preset->need_dac_fix;
964 spec->const_channel_count = preset->const_channel_count;
966 if (preset->const_channel_count)
967 spec->multiout.max_channels = preset->const_channel_count;
969 spec->multiout.max_channels = spec->channel_mode[0].channels;
970 spec->ext_channel_count = spec->channel_mode[0].channels;
972 spec->multiout.num_dacs = preset->num_dacs;
973 spec->multiout.dac_nids = preset->dac_nids;
974 spec->multiout.dig_out_nid = preset->dig_out_nid;
975 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
976 spec->multiout.hp_nid = preset->hp_nid;
978 spec->num_mux_defs = preset->num_mux_defs;
979 if (!spec->num_mux_defs)
980 spec->num_mux_defs = 1;
981 spec->input_mux = preset->input_mux;
983 spec->num_adc_nids = preset->num_adc_nids;
984 spec->adc_nids = preset->adc_nids;
985 spec->capsrc_nids = preset->capsrc_nids;
986 spec->dig_in_nid = preset->dig_in_nid;
988 spec->unsol_event = preset->unsol_event;
989 spec->init_hook = preset->init_hook;
990 #ifdef CONFIG_SND_HDA_POWER_SAVE
991 spec->power_hook = preset->power_hook;
992 spec->loopback.amplist = preset->loopbacks;
996 preset->setup(codec);
998 alc_fixup_autocfg_pin_nums(codec);
1001 /* Enable GPIO mask and set output */
1002 static const struct hda_verb alc_gpio1_init_verbs[] = {
1003 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1004 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1005 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1009 static const struct hda_verb alc_gpio2_init_verbs[] = {
1010 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1011 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1012 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1016 static const struct hda_verb alc_gpio3_init_verbs[] = {
1017 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1018 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1019 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1024 * Fix hardware PLL issue
1025 * On some codecs, the analog PLL gating control must be off while
1026 * the default value is 1.
1028 static void alc_fix_pll(struct hda_codec *codec)
1030 struct alc_spec *spec = codec->spec;
1035 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1036 spec->pll_coef_idx);
1037 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1038 AC_VERB_GET_PROC_COEF, 0);
1039 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1040 spec->pll_coef_idx);
1041 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1042 val & ~(1 << spec->pll_coef_bit));
1045 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1046 unsigned int coef_idx, unsigned int coef_bit)
1048 struct alc_spec *spec = codec->spec;
1049 spec->pll_nid = nid;
1050 spec->pll_coef_idx = coef_idx;
1051 spec->pll_coef_bit = coef_bit;
1055 static int alc_init_jacks(struct hda_codec *codec)
1057 #ifdef CONFIG_SND_HDA_INPUT_JACK
1058 struct alc_spec *spec = codec->spec;
1060 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1061 unsigned int mic_nid = spec->ext_mic.pin;
1062 unsigned int dock_nid = spec->dock_mic.pin;
1065 err = snd_hda_input_jack_add(codec, hp_nid,
1066 SND_JACK_HEADPHONE, NULL);
1069 snd_hda_input_jack_report(codec, hp_nid);
1073 err = snd_hda_input_jack_add(codec, mic_nid,
1074 SND_JACK_MICROPHONE, NULL);
1077 snd_hda_input_jack_report(codec, mic_nid);
1080 err = snd_hda_input_jack_add(codec, dock_nid,
1081 SND_JACK_MICROPHONE, NULL);
1084 snd_hda_input_jack_report(codec, dock_nid);
1086 #endif /* CONFIG_SND_HDA_INPUT_JACK */
1090 static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1094 for (i = 0; i < num_pins; i++) {
1095 hda_nid_t nid = pins[i];
1098 snd_hda_input_jack_report(codec, nid);
1099 present |= snd_hda_jack_detect(codec, nid);
1104 static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1105 bool mute, bool hp_out)
1107 struct alc_spec *spec = codec->spec;
1108 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1109 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1112 for (i = 0; i < num_pins; i++) {
1113 hda_nid_t nid = pins[i];
1116 switch (spec->automute_mode) {
1117 case ALC_AUTOMUTE_PIN:
1118 snd_hda_codec_write(codec, nid, 0,
1119 AC_VERB_SET_PIN_WIDGET_CONTROL,
1122 case ALC_AUTOMUTE_AMP:
1123 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1124 HDA_AMP_MUTE, mute_bits);
1126 case ALC_AUTOMUTE_MIXER:
1127 nid = spec->automute_mixer_nid[i];
1130 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1131 HDA_AMP_MUTE, mute_bits);
1132 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1133 HDA_AMP_MUTE, mute_bits);
1139 /* Toggle internal speakers muting */
1140 static void update_speakers(struct hda_codec *codec)
1142 struct alc_spec *spec = codec->spec;
1145 /* Control HP pins/amps depending on master_mute state;
1146 * in general, HP pins/amps control should be enabled in all cases,
1147 * but currently set only for master_mute, just to be safe
1149 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1150 spec->autocfg.hp_pins, spec->master_mute, true);
1152 if (!spec->automute)
1155 on = spec->jack_present | spec->line_jack_present;
1156 on |= spec->master_mute;
1157 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1158 spec->autocfg.speaker_pins, on, false);
1160 /* toggle line-out mutes if needed, too */
1161 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1162 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1163 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1165 if (!spec->automute_lines || !spec->automute)
1168 on = spec->jack_present;
1169 on |= spec->master_mute;
1170 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1171 spec->autocfg.line_out_pins, on, false);
1174 static void alc_hp_automute(struct hda_codec *codec)
1176 struct alc_spec *spec = codec->spec;
1178 if (!spec->automute)
1180 spec->jack_present =
1181 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1182 spec->autocfg.hp_pins);
1183 update_speakers(codec);
1186 static void alc_line_automute(struct hda_codec *codec)
1188 struct alc_spec *spec = codec->spec;
1190 if (!spec->automute || !spec->detect_line)
1192 spec->line_jack_present =
1193 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1194 spec->autocfg.line_out_pins);
1195 update_speakers(codec);
1198 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1201 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1204 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1205 for (i = 0; i < nums; i++)
1211 /* switch the current ADC according to the jack state */
1212 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1214 struct alc_spec *spec = codec->spec;
1215 unsigned int present;
1218 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1220 spec->cur_adc_idx = 1;
1222 spec->cur_adc_idx = 0;
1223 new_adc = spec->adc_nids[spec->cur_adc_idx];
1224 if (spec->cur_adc && spec->cur_adc != new_adc) {
1225 /* stream is running, let's swap the current ADC */
1226 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1227 spec->cur_adc = new_adc;
1228 snd_hda_codec_setup_stream(codec, new_adc,
1229 spec->cur_adc_stream_tag, 0,
1230 spec->cur_adc_format);
1234 static void alc_mic_automute(struct hda_codec *codec)
1236 struct alc_spec *spec = codec->spec;
1237 struct alc_mic_route *dead1, *dead2, *alive;
1238 unsigned int present, type;
1241 if (!spec->auto_mic)
1243 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1245 if (snd_BUG_ON(!spec->adc_nids))
1248 if (spec->dual_adc_switch) {
1249 alc_dual_mic_adc_auto_switch(codec);
1253 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1255 alive = &spec->int_mic;
1256 dead1 = &spec->ext_mic;
1257 dead2 = &spec->dock_mic;
1259 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1261 alive = &spec->ext_mic;
1262 dead1 = &spec->int_mic;
1263 dead2 = &spec->dock_mic;
1265 if (!present && spec->dock_mic.pin > 0) {
1266 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1268 alive = &spec->dock_mic;
1269 dead1 = &spec->int_mic;
1270 dead2 = &spec->ext_mic;
1272 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1275 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1276 if (type == AC_WID_AUD_MIX) {
1277 /* Matrix-mixer style (e.g. ALC882) */
1278 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1282 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1284 HDA_AMP_MUTE, HDA_AMP_MUTE);
1286 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1288 HDA_AMP_MUTE, HDA_AMP_MUTE);
1290 /* MUX style (e.g. ALC880) */
1291 snd_hda_codec_write_cache(codec, cap_nid, 0,
1292 AC_VERB_SET_CONNECT_SEL,
1295 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1297 /* FIXME: analog mixer */
1300 /* unsolicited event for HP jack sensing */
1301 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1303 if (codec->vendor_id == 0x10ec0880)
1308 case ALC880_HP_EVENT:
1309 alc_hp_automute(codec);
1311 case ALC880_FRONT_EVENT:
1312 alc_line_automute(codec);
1314 case ALC880_MIC_EVENT:
1315 alc_mic_automute(codec);
1320 static void alc_inithook(struct hda_codec *codec)
1322 alc_hp_automute(codec);
1323 alc_line_automute(codec);
1324 alc_mic_automute(codec);
1327 /* additional initialization for ALC888 variants */
1328 static void alc888_coef_init(struct hda_codec *codec)
1332 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1333 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1334 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1335 if ((tmp & 0xf0) == 0x20)
1337 snd_hda_codec_read(codec, 0x20, 0,
1338 AC_VERB_SET_PROC_COEF, 0x830);
1341 snd_hda_codec_read(codec, 0x20, 0,
1342 AC_VERB_SET_PROC_COEF, 0x3030);
1345 static void alc889_coef_init(struct hda_codec *codec)
1349 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1350 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1351 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1352 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1355 /* turn on/off EAPD control (only if available) */
1356 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1358 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1360 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1361 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1365 /* turn on/off EAPD controls of the codec */
1366 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1368 /* We currently only handle front, HP */
1369 static hda_nid_t pins[] = {
1370 0x0f, 0x10, 0x14, 0x15, 0
1373 for (p = pins; *p; p++)
1374 set_eapd(codec, *p, on);
1377 /* generic shutup callback;
1378 * just turning off EPAD and a little pause for avoiding pop-noise
1380 static void alc_eapd_shutup(struct hda_codec *codec)
1382 alc_auto_setup_eapd(codec, false);
1386 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1390 alc_auto_setup_eapd(codec, true);
1392 case ALC_INIT_GPIO1:
1393 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1395 case ALC_INIT_GPIO2:
1396 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1398 case ALC_INIT_GPIO3:
1399 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1401 case ALC_INIT_DEFAULT:
1402 switch (codec->vendor_id) {
1404 snd_hda_codec_write(codec, 0x1a, 0,
1405 AC_VERB_SET_COEF_INDEX, 7);
1406 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1407 AC_VERB_GET_PROC_COEF, 0);
1408 snd_hda_codec_write(codec, 0x1a, 0,
1409 AC_VERB_SET_COEF_INDEX, 7);
1410 snd_hda_codec_write(codec, 0x1a, 0,
1411 AC_VERB_SET_PROC_COEF,
1420 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1421 alc889_coef_init(codec);
1424 alc888_coef_init(codec);
1426 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1429 snd_hda_codec_write(codec, 0x20, 0,
1430 AC_VERB_SET_COEF_INDEX, 7);
1431 tmp = snd_hda_codec_read(codec, 0x20, 0,
1432 AC_VERB_GET_PROC_COEF, 0);
1433 snd_hda_codec_write(codec, 0x20, 0,
1434 AC_VERB_SET_COEF_INDEX, 7);
1435 snd_hda_codec_write(codec, 0x20, 0,
1436 AC_VERB_SET_PROC_COEF,
1445 static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1446 struct snd_ctl_elem_info *uinfo)
1448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1449 struct alc_spec *spec = codec->spec;
1450 static const char * const texts2[] = {
1451 "Disabled", "Enabled"
1453 static const char * const texts3[] = {
1454 "Disabled", "Speaker Only", "Line-Out+Speaker"
1456 const char * const *texts;
1458 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1460 if (spec->automute_hp_lo) {
1461 uinfo->value.enumerated.items = 3;
1464 uinfo->value.enumerated.items = 2;
1467 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1468 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1469 strcpy(uinfo->value.enumerated.name,
1470 texts[uinfo->value.enumerated.item]);
1474 static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1475 struct snd_ctl_elem_value *ucontrol)
1477 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1478 struct alc_spec *spec = codec->spec;
1480 if (!spec->automute)
1482 else if (!spec->automute_lines)
1486 ucontrol->value.enumerated.item[0] = val;
1490 static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1491 struct snd_ctl_elem_value *ucontrol)
1493 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1494 struct alc_spec *spec = codec->spec;
1496 switch (ucontrol->value.enumerated.item[0]) {
1498 if (!spec->automute)
1503 if (spec->automute && !spec->automute_lines)
1506 spec->automute_lines = 0;
1509 if (!spec->automute_hp_lo)
1511 if (spec->automute && spec->automute_lines)
1514 spec->automute_lines = 1;
1519 update_speakers(codec);
1523 static const struct snd_kcontrol_new alc_automute_mode_enum = {
1524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1525 .name = "Auto-Mute Mode",
1526 .info = alc_automute_mode_info,
1527 .get = alc_automute_mode_get,
1528 .put = alc_automute_mode_put,
1531 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1533 static int alc_add_automute_mode_enum(struct hda_codec *codec)
1535 struct alc_spec *spec = codec->spec;
1536 struct snd_kcontrol_new *knew;
1538 knew = alc_kcontrol_new(spec);
1541 *knew = alc_automute_mode_enum;
1542 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1548 static void alc_init_auto_hp(struct hda_codec *codec)
1550 struct alc_spec *spec = codec->spec;
1551 struct auto_pin_cfg *cfg = &spec->autocfg;
1555 if (cfg->hp_pins[0])
1557 if (cfg->line_out_pins[0])
1559 if (cfg->speaker_pins[0])
1561 if (present < 2) /* need two different output types */
1564 spec->automute_hp_lo = 1; /* both HP and LO automute */
1566 if (!cfg->speaker_pins[0]) {
1567 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1568 sizeof(cfg->speaker_pins));
1569 cfg->speaker_outs = cfg->line_outs;
1572 if (!cfg->hp_pins[0]) {
1573 memcpy(cfg->hp_pins, cfg->line_out_pins,
1574 sizeof(cfg->hp_pins));
1575 cfg->hp_outs = cfg->line_outs;
1578 for (i = 0; i < cfg->hp_outs; i++) {
1579 hda_nid_t nid = cfg->hp_pins[i];
1580 if (!is_jack_detectable(codec, nid))
1582 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1584 snd_hda_codec_write_cache(codec, nid, 0,
1585 AC_VERB_SET_UNSOLICITED_ENABLE,
1586 AC_USRSP_EN | ALC880_HP_EVENT);
1588 spec->automute_mode = ALC_AUTOMUTE_PIN;
1590 if (spec->automute && cfg->line_out_pins[0] &&
1591 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1592 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1593 for (i = 0; i < cfg->line_outs; i++) {
1594 hda_nid_t nid = cfg->line_out_pins[i];
1595 if (!is_jack_detectable(codec, nid))
1597 snd_printdd("realtek: Enable Line-Out auto-muting "
1598 "on NID 0x%x\n", nid);
1599 snd_hda_codec_write_cache(codec, nid, 0,
1600 AC_VERB_SET_UNSOLICITED_ENABLE,
1601 AC_USRSP_EN | ALC880_FRONT_EVENT);
1602 spec->detect_line = 1;
1604 spec->automute_lines = spec->detect_line;
1607 if (spec->automute) {
1608 /* create a control for automute mode */
1609 alc_add_automute_mode_enum(codec);
1610 spec->unsol_event = alc_sku_unsol_event;
1614 static void alc_init_auto_mic(struct hda_codec *codec)
1616 struct alc_spec *spec = codec->spec;
1617 struct auto_pin_cfg *cfg = &spec->autocfg;
1618 hda_nid_t fixed, ext, dock;
1621 fixed = ext = dock = 0;
1622 for (i = 0; i < cfg->num_inputs; i++) {
1623 hda_nid_t nid = cfg->inputs[i].pin;
1624 unsigned int defcfg;
1625 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1626 switch (snd_hda_get_input_pin_attr(defcfg)) {
1627 case INPUT_PIN_ATTR_INT:
1629 return; /* already occupied */
1630 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1631 return; /* invalid type */
1634 case INPUT_PIN_ATTR_UNUSED:
1635 return; /* invalid entry */
1636 case INPUT_PIN_ATTR_DOCK:
1638 return; /* already occupied */
1639 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1640 return; /* invalid type */
1645 return; /* already occupied */
1646 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1647 return; /* invalid type */
1658 if (!is_jack_detectable(codec, ext))
1659 return; /* no unsol support */
1660 if (dock && !is_jack_detectable(codec, dock))
1661 return; /* no unsol support */
1662 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1664 spec->ext_mic.pin = ext;
1665 spec->dock_mic.pin = dock;
1666 spec->int_mic.pin = fixed;
1667 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1668 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1669 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1671 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1672 AC_VERB_SET_UNSOLICITED_ENABLE,
1673 AC_USRSP_EN | ALC880_MIC_EVENT);
1674 spec->unsol_event = alc_sku_unsol_event;
1677 /* Could be any non-zero and even value. When used as fixup, tells
1678 * the driver to ignore any present sku defines.
1680 #define ALC_FIXUP_SKU_IGNORE (2)
1682 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1684 unsigned int ass, tmp, i;
1686 struct alc_spec *spec = codec->spec;
1688 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1690 if (spec->cdefine.fixup) {
1691 ass = spec->cdefine.sku_cfg;
1692 if (ass == ALC_FIXUP_SKU_IGNORE)
1697 ass = codec->subsystem_id & 0xffff;
1698 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1702 if (codec->vendor_id == 0x10ec0260)
1704 ass = snd_hda_codec_get_pincfg(codec, nid);
1707 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1708 codec->chip_name, ass);
1714 for (i = 1; i < 16; i++) {
1718 if (((ass >> 16) & 0xf) != tmp)
1721 spec->cdefine.port_connectivity = ass >> 30;
1722 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1723 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1724 spec->cdefine.customization = ass >> 8;
1726 spec->cdefine.sku_cfg = ass;
1727 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1728 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1729 spec->cdefine.swap = (ass & 0x2) >> 1;
1730 spec->cdefine.override = ass & 0x1;
1732 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1733 nid, spec->cdefine.sku_cfg);
1734 snd_printd("SKU: port_connectivity=0x%x\n",
1735 spec->cdefine.port_connectivity);
1736 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1737 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1738 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1739 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1740 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1741 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1742 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1747 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1750 for (i = 0; i < nums; i++)
1756 /* check subsystem ID and set up device-specific initialization;
1757 * return 1 if initialized, 0 if invalid SSID
1759 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1760 * 31 ~ 16 : Manufacture ID
1762 * 7 ~ 0 : Assembly ID
1763 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1765 static int alc_subsystem_id(struct hda_codec *codec,
1766 hda_nid_t porta, hda_nid_t porte,
1767 hda_nid_t portd, hda_nid_t porti)
1769 unsigned int ass, tmp, i;
1771 struct alc_spec *spec = codec->spec;
1773 if (spec->cdefine.fixup) {
1774 ass = spec->cdefine.sku_cfg;
1775 if (ass == ALC_FIXUP_SKU_IGNORE)
1780 ass = codec->subsystem_id & 0xffff;
1781 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1784 /* invalid SSID, check the special NID pin defcfg instead */
1786 * 31~30 : port connectivity
1789 * 19~16 : Check sum (15:1)
1794 if (codec->vendor_id == 0x10ec0260)
1796 ass = snd_hda_codec_get_pincfg(codec, nid);
1797 snd_printd("realtek: No valid SSID, "
1798 "checking pincfg 0x%08x for NID 0x%x\n",
1802 if ((ass >> 30) != 1) /* no physical connection */
1807 for (i = 1; i < 16; i++) {
1811 if (((ass >> 16) & 0xf) != tmp)
1814 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1815 ass & 0xffff, codec->vendor_id);
1819 * 2 : 0 --> Desktop, 1 --> Laptop
1820 * 3~5 : External Amplifier control
1823 tmp = (ass & 0x38) >> 3; /* external Amp control */
1826 spec->init_amp = ALC_INIT_GPIO1;
1829 spec->init_amp = ALC_INIT_GPIO2;
1832 spec->init_amp = ALC_INIT_GPIO3;
1836 spec->init_amp = ALC_INIT_DEFAULT;
1840 /* is laptop or Desktop and enable the function "Mute internal speaker
1841 * when the external headphone out jack is plugged"
1843 if (!(ass & 0x8000))
1846 * 10~8 : Jack location
1847 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1849 * 15 : 1 --> enable the function "Mute internal speaker
1850 * when the external headphone out jack is plugged"
1852 if (!spec->autocfg.hp_pins[0]) {
1854 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1865 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1866 spec->autocfg.line_outs))
1868 spec->autocfg.hp_pins[0] = nid;
1873 static void alc_ssid_check(struct hda_codec *codec,
1874 hda_nid_t porta, hda_nid_t porte,
1875 hda_nid_t portd, hda_nid_t porti)
1877 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1878 struct alc_spec *spec = codec->spec;
1879 snd_printd("realtek: "
1880 "Enable default setup for auto mode as fallback\n");
1881 spec->init_amp = ALC_INIT_DEFAULT;
1884 alc_init_auto_hp(codec);
1885 alc_init_auto_mic(codec);
1889 * Fix-up pin default configurations and add default verbs
1897 struct alc_model_fixup {
1908 const struct alc_pincfg *pins;
1909 const struct hda_verb *verbs;
1910 void (*func)(struct hda_codec *codec,
1911 const struct alc_fixup *fix,
1925 ALC_FIXUP_ACT_PRE_PROBE,
1926 ALC_FIXUP_ACT_PROBE,
1930 static void alc_apply_fixup(struct hda_codec *codec, int action)
1932 struct alc_spec *spec = codec->spec;
1933 int id = spec->fixup_id;
1934 #ifdef CONFIG_SND_DEBUG_VERBOSE
1935 const char *modelname = spec->fixup_name;
1939 if (!spec->fixup_list)
1943 const struct alc_fixup *fix = spec->fixup_list + id;
1944 const struct alc_pincfg *cfg;
1946 switch (fix->type) {
1948 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1950 snd_printdd(KERN_INFO "hda_codec: %s: "
1951 "Apply sku override for %s\n",
1952 codec->chip_name, modelname);
1953 spec->cdefine.sku_cfg = fix->v.sku;
1954 spec->cdefine.fixup = 1;
1956 case ALC_FIXUP_PINS:
1958 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1960 snd_printdd(KERN_INFO "hda_codec: %s: "
1961 "Apply pincfg for %s\n",
1962 codec->chip_name, modelname);
1963 for (; cfg->nid; cfg++)
1964 snd_hda_codec_set_pincfg(codec, cfg->nid,
1967 case ALC_FIXUP_VERBS:
1968 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1970 snd_printdd(KERN_INFO "hda_codec: %s: "
1971 "Apply fix-verbs for %s\n",
1972 codec->chip_name, modelname);
1973 add_verb(codec->spec, fix->v.verbs);
1975 case ALC_FIXUP_FUNC:
1978 snd_printdd(KERN_INFO "hda_codec: %s: "
1979 "Apply fix-func for %s\n",
1980 codec->chip_name, modelname);
1981 fix->v.func(codec, fix, action);
1984 snd_printk(KERN_ERR "hda_codec: %s: "
1985 "Invalid fixup type %d\n",
1986 codec->chip_name, fix->type);
1997 static void alc_pick_fixup(struct hda_codec *codec,
1998 const struct alc_model_fixup *models,
1999 const struct snd_pci_quirk *quirk,
2000 const struct alc_fixup *fixlist)
2002 struct alc_spec *spec = codec->spec;
2004 const char *name = NULL;
2006 if (codec->modelname && models) {
2007 while (models->name) {
2008 if (!strcmp(codec->modelname, models->name)) {
2010 name = models->name;
2017 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2020 #ifdef CONFIG_SND_DEBUG_VERBOSE
2026 spec->fixup_id = id;
2028 spec->fixup_list = fixlist;
2029 spec->fixup_name = name;
2033 static int alc_read_coef_idx(struct hda_codec *codec,
2034 unsigned int coef_idx)
2037 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2039 val = snd_hda_codec_read(codec, 0x20, 0,
2040 AC_VERB_GET_PROC_COEF, 0);
2044 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2045 unsigned int coef_val)
2047 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2049 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2053 /* set right pin controls for digital I/O */
2054 static void alc_auto_init_digital(struct hda_codec *codec)
2056 struct alc_spec *spec = codec->spec;
2060 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2061 pin = spec->autocfg.dig_out_pins[i];
2064 snd_hda_codec_write(codec, pin, 0,
2065 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2067 dac = spec->multiout.dig_out_nid;
2069 dac = spec->slave_dig_outs[i - 1];
2070 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
2072 snd_hda_codec_write(codec, dac, 0,
2073 AC_VERB_SET_AMP_GAIN_MUTE,
2076 pin = spec->autocfg.dig_in_pin;
2078 snd_hda_codec_write(codec, pin, 0,
2079 AC_VERB_SET_PIN_WIDGET_CONTROL,
2083 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2084 static void alc_auto_parse_digital(struct hda_codec *codec)
2086 struct alc_spec *spec = codec->spec;
2090 /* support multiple SPDIFs; the secondary is set up as a slave */
2091 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2092 err = snd_hda_get_connections(codec,
2093 spec->autocfg.dig_out_pins[i],
2098 spec->multiout.dig_out_nid = dig_nid;
2099 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2101 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2102 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2104 spec->slave_dig_outs[i - 1] = dig_nid;
2108 if (spec->autocfg.dig_in_pin) {
2109 dig_nid = codec->start_nid;
2110 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2111 unsigned int wcaps = get_wcaps(codec, dig_nid);
2112 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2114 if (!(wcaps & AC_WCAP_DIGITAL))
2116 if (!(wcaps & AC_WCAP_CONN_LIST))
2118 err = get_connection_index(codec, dig_nid,
2119 spec->autocfg.dig_in_pin);
2121 spec->dig_in_nid = dig_nid;
2135 static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2136 /* Mic-in jack as mic in */
2137 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2138 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2139 /* Line-in jack as Line in */
2140 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2141 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2142 /* Line-Out as Front */
2143 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2150 static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2151 /* Mic-in jack as mic in */
2152 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2153 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2154 /* Line-in jack as Surround */
2155 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2156 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2157 /* Line-Out as Front */
2158 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2165 static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2166 /* Mic-in jack as CLFE */
2167 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2168 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2169 /* Line-in jack as Surround */
2170 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2171 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2172 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2173 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2180 static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2181 /* Mic-in jack as CLFE */
2182 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2183 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2184 /* Line-in jack as Surround */
2185 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2186 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2187 /* Line-Out as Side */
2188 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2192 static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2193 { 2, alc888_4ST_ch2_intel_init },
2194 { 4, alc888_4ST_ch4_intel_init },
2195 { 6, alc888_4ST_ch6_intel_init },
2196 { 8, alc888_4ST_ch8_intel_init },
2200 * ALC888 Fujitsu Siemens Amillo xa3530
2203 static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2204 /* Front Mic: set to PIN_IN (empty by default) */
2205 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2206 /* Connect Internal HP to Front */
2207 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2209 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2210 /* Connect Bass HP to Front */
2211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2212 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2213 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2214 /* Connect Line-Out side jack (SPDIF) to Side */
2215 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2216 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2217 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2218 /* Connect Mic jack to CLFE */
2219 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2222 /* Connect Line-in jack to Surround */
2223 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2226 /* Connect HP out jack to Front */
2227 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2228 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2230 /* Enable unsolicited event for HP jack and Line-out jack */
2231 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2232 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2236 static void alc889_automute_setup(struct hda_codec *codec)
2238 struct alc_spec *spec = codec->spec;
2240 spec->autocfg.hp_pins[0] = 0x15;
2241 spec->autocfg.speaker_pins[0] = 0x14;
2242 spec->autocfg.speaker_pins[1] = 0x16;
2243 spec->autocfg.speaker_pins[2] = 0x17;
2244 spec->autocfg.speaker_pins[3] = 0x19;
2245 spec->autocfg.speaker_pins[4] = 0x1a;
2247 spec->automute_mode = ALC_AUTOMUTE_AMP;
2250 static void alc889_intel_init_hook(struct hda_codec *codec)
2252 alc889_coef_init(codec);
2253 alc_hp_automute(codec);
2256 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2258 struct alc_spec *spec = codec->spec;
2260 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2261 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2262 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2263 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2265 spec->automute_mode = ALC_AUTOMUTE_AMP;
2269 * ALC888 Acer Aspire 4930G model
2272 static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2273 /* Front Mic: set to PIN_IN (empty by default) */
2274 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2275 /* Unselect Front Mic by default in input mixer 3 */
2276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2277 /* Enable unsolicited event for HP jack */
2278 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2279 /* Connect Internal HP to front */
2280 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2282 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2283 /* Connect HP out to front */
2284 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2285 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2286 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2287 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2292 * ALC888 Acer Aspire 6530G model
2295 static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2296 /* Route to built-in subwoofer as well as speakers */
2297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2299 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2300 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2301 /* Bias voltage on for external mic port */
2302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2303 /* Front Mic: set to PIN_IN (empty by default) */
2304 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2305 /* Unselect Front Mic by default in input mixer 3 */
2306 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2307 /* Enable unsolicited event for HP jack */
2308 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2309 /* Enable speaker output */
2310 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2311 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2312 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2313 /* Enable headphone output */
2314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2315 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2316 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2317 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2322 *ALC888 Acer Aspire 7730G model
2325 static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2326 /* Bias voltage on for external mic port */
2327 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2328 /* Front Mic: set to PIN_IN (empty by default) */
2329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2330 /* Unselect Front Mic by default in input mixer 3 */
2331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2332 /* Enable unsolicited event for HP jack */
2333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2334 /* Enable speaker output */
2335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2337 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2338 /* Enable headphone output */
2339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2340 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2342 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2343 /*Enable internal subwoofer */
2344 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2345 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2346 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2347 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2352 * ALC889 Acer Aspire 8930G model
2355 static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2356 /* Front Mic: set to PIN_IN (empty by default) */
2357 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2358 /* Unselect Front Mic by default in input mixer 3 */
2359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2360 /* Enable unsolicited event for HP jack */
2361 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2362 /* Connect Internal Front to Front */
2363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2365 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2366 /* Connect Internal Rear to Rear */
2367 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2368 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2369 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2370 /* Connect Internal CLFE to CLFE */
2371 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2372 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2373 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2374 /* Connect HP out to Front */
2375 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2376 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2378 /* Enable all DACs */
2379 /* DAC DISABLE/MUTE 1? */
2380 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2381 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2382 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2383 /* DAC DISABLE/MUTE 2? */
2384 /* some bit here disables the other DACs. Init=0x4900 */
2385 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2386 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2388 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2389 * which makes the stereo useless. However, either the mic or the ALC889
2390 * makes the signal become a difference/sum signal instead of standard
2391 * stereo, which is annoying. So instead we flip this bit which makes the
2392 * codec replicate the sum signal to both channels, turning it into a
2395 /* DMIC_CONTROL? Init value = 0x0001 */
2396 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2397 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2401 static const struct hda_input_mux alc888_2_capture_sources[2] = {
2402 /* Front mic only available on one ADC */
2409 { "Front Mic", 0xb },
2422 static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2423 /* Interal mic only available on one ADC */
2430 { "Input Mix", 0xa },
2431 { "Internal Mic", 0xb },
2440 { "Input Mix", 0xa },
2445 static const struct hda_input_mux alc889_capture_sources[3] = {
2446 /* Digital mic only available on first "ADC" */
2453 { "Front Mic", 0xb },
2454 { "Input Mix", 0xa },
2463 { "Input Mix", 0xa },
2472 { "Input Mix", 0xa },
2477 static const struct snd_kcontrol_new alc888_base_mixer[] = {
2478 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2481 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2482 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2484 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2485 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2486 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2487 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2488 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2489 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2490 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2491 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2492 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2494 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2495 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2499 static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2503 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2504 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2506 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2507 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2508 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2509 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2510 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2511 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2512 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2513 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2514 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2515 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2521 static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2522 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2523 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2525 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2526 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2528 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2529 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2530 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2531 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2532 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2534 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2535 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2540 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2542 struct alc_spec *spec = codec->spec;
2544 spec->autocfg.hp_pins[0] = 0x15;
2545 spec->autocfg.speaker_pins[0] = 0x14;
2546 spec->autocfg.speaker_pins[1] = 0x16;
2547 spec->autocfg.speaker_pins[2] = 0x17;
2549 spec->automute_mode = ALC_AUTOMUTE_AMP;
2552 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2554 struct alc_spec *spec = codec->spec;
2556 spec->autocfg.hp_pins[0] = 0x15;
2557 spec->autocfg.speaker_pins[0] = 0x14;
2558 spec->autocfg.speaker_pins[1] = 0x16;
2559 spec->autocfg.speaker_pins[2] = 0x17;
2561 spec->automute_mode = ALC_AUTOMUTE_AMP;
2564 static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2566 struct alc_spec *spec = codec->spec;
2568 spec->autocfg.hp_pins[0] = 0x15;
2569 spec->autocfg.speaker_pins[0] = 0x14;
2570 spec->autocfg.speaker_pins[1] = 0x16;
2571 spec->autocfg.speaker_pins[2] = 0x17;
2573 spec->automute_mode = ALC_AUTOMUTE_AMP;
2576 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2578 struct alc_spec *spec = codec->spec;
2580 spec->autocfg.hp_pins[0] = 0x15;
2581 spec->autocfg.speaker_pins[0] = 0x14;
2582 spec->autocfg.speaker_pins[1] = 0x16;
2583 spec->autocfg.speaker_pins[2] = 0x1b;
2585 spec->automute_mode = ALC_AUTOMUTE_AMP;
2589 * ALC880 3-stack model
2591 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2592 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2593 * F-Mic = 0x1b, HP = 0x19
2596 static const hda_nid_t alc880_dac_nids[4] = {
2597 /* front, rear, clfe, rear_surr */
2598 0x02, 0x05, 0x04, 0x03
2601 static const hda_nid_t alc880_adc_nids[3] = {
2606 /* The datasheet says the node 0x07 is connected from inputs,
2607 * but it shows zero connection in the real implementation on some devices.
2608 * Note: this is a 915GAV bug, fixed on 915GLV
2610 static const hda_nid_t alc880_adc_nids_alt[2] = {
2615 #define ALC880_DIGOUT_NID 0x06
2616 #define ALC880_DIGIN_NID 0x0a
2618 static const struct hda_input_mux alc880_capture_source = {
2622 { "Front Mic", 0x3 },
2628 /* channel source setting (2/6 channel selection for 3-stack) */
2630 static const struct hda_verb alc880_threestack_ch2_init[] = {
2631 /* set line-in to input, mute it */
2632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2634 /* set mic-in to input vref 80%, mute it */
2635 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2636 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2641 static const struct hda_verb alc880_threestack_ch6_init[] = {
2642 /* set line-in to output, unmute it */
2643 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2644 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2645 /* set mic-in to output, unmute it */
2646 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2647 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2651 static const struct hda_channel_mode alc880_threestack_modes[2] = {
2652 { 2, alc880_threestack_ch2_init },
2653 { 6, alc880_threestack_ch6_init },
2656 static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2657 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2658 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2659 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2660 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2661 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2662 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2663 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2664 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2665 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2666 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2667 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2668 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2669 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2670 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2671 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2672 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2673 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2675 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2676 .name = "Channel Mode",
2677 .info = alc_ch_mode_info,
2678 .get = alc_ch_mode_get,
2679 .put = alc_ch_mode_put,
2684 /* capture mixer elements */
2685 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2686 struct snd_ctl_elem_info *uinfo)
2688 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2689 struct alc_spec *spec = codec->spec;
2692 mutex_lock(&codec->control_mutex);
2693 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2695 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2696 mutex_unlock(&codec->control_mutex);
2700 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2701 unsigned int size, unsigned int __user *tlv)
2703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2704 struct alc_spec *spec = codec->spec;
2707 mutex_lock(&codec->control_mutex);
2708 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2710 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2711 mutex_unlock(&codec->control_mutex);
2715 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2716 struct snd_ctl_elem_value *ucontrol);
2718 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2719 struct snd_ctl_elem_value *ucontrol,
2722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2723 struct alc_spec *spec = codec->spec;
2724 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2727 mutex_lock(&codec->control_mutex);
2728 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2730 err = func(kcontrol, ucontrol);
2731 mutex_unlock(&codec->control_mutex);
2735 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2736 struct snd_ctl_elem_value *ucontrol)
2738 return alc_cap_getput_caller(kcontrol, ucontrol,
2739 snd_hda_mixer_amp_volume_get);
2742 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2743 struct snd_ctl_elem_value *ucontrol)
2745 return alc_cap_getput_caller(kcontrol, ucontrol,
2746 snd_hda_mixer_amp_volume_put);
2749 /* capture mixer elements */
2750 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2752 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2753 struct snd_ctl_elem_value *ucontrol)
2755 return alc_cap_getput_caller(kcontrol, ucontrol,
2756 snd_hda_mixer_amp_switch_get);
2759 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2760 struct snd_ctl_elem_value *ucontrol)
2762 return alc_cap_getput_caller(kcontrol, ucontrol,
2763 snd_hda_mixer_amp_switch_put);
2766 #define _DEFINE_CAPMIX(num) \
2768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2769 .name = "Capture Switch", \
2770 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2772 .info = alc_cap_sw_info, \
2773 .get = alc_cap_sw_get, \
2774 .put = alc_cap_sw_put, \
2777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2778 .name = "Capture Volume", \
2779 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2780 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2781 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2783 .info = alc_cap_vol_info, \
2784 .get = alc_cap_vol_get, \
2785 .put = alc_cap_vol_put, \
2786 .tlv = { .c = alc_cap_vol_tlv }, \
2789 #define _DEFINE_CAPSRC(num) \
2791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2792 /* .name = "Capture Source", */ \
2793 .name = "Input Source", \
2795 .info = alc_mux_enum_info, \
2796 .get = alc_mux_enum_get, \
2797 .put = alc_mux_enum_put, \
2800 #define DEFINE_CAPMIX(num) \
2801 static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2802 _DEFINE_CAPMIX(num), \
2803 _DEFINE_CAPSRC(num), \
2807 #define DEFINE_CAPMIX_NOSRC(num) \
2808 static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2809 _DEFINE_CAPMIX(num), \
2813 /* up to three ADCs */
2817 DEFINE_CAPMIX_NOSRC(1);
2818 DEFINE_CAPMIX_NOSRC(2);
2819 DEFINE_CAPMIX_NOSRC(3);
2822 * ALC880 5-stack model
2824 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2826 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2827 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2830 /* additional mixers to alc880_three_stack_mixer */
2831 static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2832 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2833 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2837 /* channel source setting (6/8 channel selection for 5-stack) */
2839 static const struct hda_verb alc880_fivestack_ch6_init[] = {
2840 /* set line-in to input, mute it */
2841 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2842 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2847 static const struct hda_verb alc880_fivestack_ch8_init[] = {
2848 /* set line-in to output, unmute it */
2849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2854 static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2855 { 6, alc880_fivestack_ch6_init },
2856 { 8, alc880_fivestack_ch8_init },
2861 * ALC880 6-stack model
2863 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2864 * Side = 0x05 (0x0f)
2865 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2866 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2869 static const hda_nid_t alc880_6st_dac_nids[4] = {
2870 /* front, rear, clfe, rear_surr */
2871 0x02, 0x03, 0x04, 0x05
2874 static const struct hda_input_mux alc880_6stack_capture_source = {
2878 { "Front Mic", 0x1 },
2884 /* fixed 8-channels */
2885 static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2889 static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2891 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2893 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2894 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2895 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2896 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2897 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2898 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2899 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2900 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2901 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2902 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2903 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2906 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2907 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2910 .name = "Channel Mode",
2911 .info = alc_ch_mode_info,
2912 .get = alc_ch_mode_get,
2913 .put = alc_ch_mode_put,
2922 * W810 has rear IO for:
2925 * Center/LFE (DAC 04)
2928 * The system also has a pair of internal speakers, and a headphone jack.
2929 * These are both connected to Line2 on the codec, hence to DAC 02.
2931 * There is a variable resistor to control the speaker or headphone
2932 * volume. This is a hardware-only device without a software API.
2934 * Plugging headphones in will disable the internal speakers. This is
2935 * implemented in hardware, not via the driver using jack sense. In
2936 * a similar fashion, plugging into the rear socket marked "front" will
2937 * disable both the speakers and headphones.
2939 * For input, there's a microphone jack, and an "audio in" jack.
2940 * These may not do anything useful with this driver yet, because I
2941 * haven't setup any initialization verbs for these yet...
2944 static const hda_nid_t alc880_w810_dac_nids[3] = {
2945 /* front, rear/surround, clfe */
2949 /* fixed 6 channels */
2950 static const struct hda_channel_mode alc880_w810_modes[1] = {
2954 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2955 static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2956 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2957 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2958 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2959 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2960 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2961 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2962 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2963 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2964 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2972 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2973 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2977 static const hda_nid_t alc880_z71v_dac_nids[1] = {
2980 #define ALC880_Z71V_HP_DAC 0x03
2982 /* fixed 2 channels */
2983 static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2987 static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
2988 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2989 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2990 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2991 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2992 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2993 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3001 * ALC880 F1734 model
3003 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3004 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3007 static const hda_nid_t alc880_f1734_dac_nids[1] = {
3010 #define ALC880_F1734_HP_DAC 0x02
3012 static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3013 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3014 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3015 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3016 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3017 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3018 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3024 static const struct hda_input_mux alc880_f1734_capture_source = {
3036 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3037 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3038 * Mic = 0x18, Line = 0x1a
3041 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3042 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3044 static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3045 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3046 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3047 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3048 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3049 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3050 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3051 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3052 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3053 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3054 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3055 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3056 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3058 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3061 .name = "Channel Mode",
3062 .info = alc_ch_mode_info,
3063 .get = alc_ch_mode_get,
3064 .put = alc_ch_mode_put,
3070 * ALC880 ASUS W1V model
3072 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3073 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3074 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3077 /* additional mixers to alc880_asus_mixer */
3078 static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3079 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3080 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3085 static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3086 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3087 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3089 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3090 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3093 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3094 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3099 static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3100 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3101 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3102 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3103 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3104 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3105 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3106 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3107 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3109 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3114 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3115 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3118 .name = "Channel Mode",
3119 .info = alc_ch_mode_info,
3120 .get = alc_ch_mode_get,
3121 .put = alc_ch_mode_put,
3126 static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3127 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3128 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3129 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3130 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3131 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3132 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3134 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3135 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3136 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3140 static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3141 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3142 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3143 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3144 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3151 * virtual master controls
3155 * slave controls for virtual master
3157 static const char * const alc_slave_vols[] = {
3158 "Front Playback Volume",
3159 "Surround Playback Volume",
3160 "Center Playback Volume",
3161 "LFE Playback Volume",
3162 "Side Playback Volume",
3163 "Headphone Playback Volume",
3164 "Speaker Playback Volume",
3165 "Mono Playback Volume",
3166 "Line-Out Playback Volume",
3170 static const char * const alc_slave_sws[] = {
3171 "Front Playback Switch",
3172 "Surround Playback Switch",
3173 "Center Playback Switch",
3174 "LFE Playback Switch",
3175 "Side Playback Switch",
3176 "Headphone Playback Switch",
3177 "Speaker Playback Switch",
3178 "Mono Playback Switch",
3179 "IEC958 Playback Switch",
3180 "Line-Out Playback Switch",
3185 * build control elements
3188 #define NID_MAPPING (-1)
3190 #define SUBDEV_SPEAKER_ (0 << 6)
3191 #define SUBDEV_HP_ (1 << 6)
3192 #define SUBDEV_LINE_ (2 << 6)
3193 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3194 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3195 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3197 static void alc_free_kctls(struct hda_codec *codec);
3199 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3200 /* additional beep mixers; the actual parameters are overwritten at build */
3201 static const struct snd_kcontrol_new alc_beep_mixer[] = {
3202 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
3203 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
3208 static int alc_build_controls(struct hda_codec *codec)
3210 struct alc_spec *spec = codec->spec;
3211 struct snd_kcontrol *kctl = NULL;
3212 const struct snd_kcontrol_new *knew;
3217 for (i = 0; i < spec->num_mixers; i++) {
3218 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3222 if (spec->cap_mixer) {
3223 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3227 if (spec->multiout.dig_out_nid) {
3228 err = snd_hda_create_spdif_out_ctls(codec,
3229 spec->multiout.dig_out_nid,
3230 spec->multiout.dig_out_nid);
3233 if (!spec->no_analog) {
3234 err = snd_hda_create_spdif_share_sw(codec,
3238 spec->multiout.share_spdif = 1;
3241 if (spec->dig_in_nid) {
3242 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3247 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3248 /* create beep controls if needed */
3249 if (spec->beep_amp) {
3250 const struct snd_kcontrol_new *knew;
3251 for (knew = alc_beep_mixer; knew->name; knew++) {
3252 struct snd_kcontrol *kctl;
3253 kctl = snd_ctl_new1(knew, codec);
3256 kctl->private_value = spec->beep_amp;
3257 err = snd_hda_ctl_add(codec, 0, kctl);
3264 /* if we have no master control, let's create it */
3265 if (!spec->no_analog &&
3266 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3267 unsigned int vmaster_tlv[4];
3268 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3269 HDA_OUTPUT, vmaster_tlv);
3270 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3271 vmaster_tlv, alc_slave_vols);
3275 if (!spec->no_analog &&
3276 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3277 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3278 NULL, alc_slave_sws);
3283 /* assign Capture Source enums to NID */
3284 if (spec->capsrc_nids || spec->adc_nids) {
3285 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3287 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3288 for (i = 0; kctl && i < kctl->count; i++) {
3289 const hda_nid_t *nids = spec->capsrc_nids;
3291 nids = spec->adc_nids;
3292 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3297 if (spec->cap_mixer) {
3298 const char *kname = kctl ? kctl->id.name : NULL;
3299 for (knew = spec->cap_mixer; knew->name; knew++) {
3300 if (kname && strcmp(knew->name, kname) == 0)
3302 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3303 for (i = 0; kctl && i < kctl->count; i++) {
3304 err = snd_hda_add_nid(codec, kctl, i,
3312 /* other nid->control mapping */
3313 for (i = 0; i < spec->num_mixers; i++) {
3314 for (knew = spec->mixers[i]; knew->name; knew++) {
3315 if (knew->iface != NID_MAPPING)
3317 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3320 u = knew->subdevice;
3321 for (j = 0; j < 4; j++, u >>= 8) {
3326 case SUBDEV_SPEAKER_:
3327 nid = spec->autocfg.speaker_pins[nid];
3330 nid = spec->autocfg.line_out_pins[nid];
3333 nid = spec->autocfg.hp_pins[nid];
3338 err = snd_hda_add_nid(codec, kctl, 0, nid);
3342 u = knew->private_value;
3343 for (j = 0; j < 4; j++, u >>= 8) {
3347 err = snd_hda_add_nid(codec, kctl, 0, nid);
3354 alc_free_kctls(codec); /* no longer needed */
3361 * initialize the codec volumes, etc
3365 * generic initialization of ADC, input mixers and output mixers
3367 static const struct hda_verb alc880_volume_init_verbs[] = {
3369 * Unmute ADC0-2 and set the default input to mic-in
3371 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3373 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3375 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3378 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3380 * Note: PASD motherboards uses the Line In 2 as the input for front
3383 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3388 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3389 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3390 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3393 * Set up output mixers (0x0c - 0x0f)
3395 /* set vol=0 to output mixers */
3396 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3398 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3400 /* set up input amps for analog loopback */
3401 /* Amp Indices: DAC = 0, mixer = 1 */
3402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3404 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3405 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3407 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3408 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3415 * 3-stack pin configuration:
3416 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3418 static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3420 * preset connection lists of input pins
3421 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3423 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3424 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3425 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3428 * Set pin mode and muting
3430 /* set front pin widgets 0x14 for output */
3431 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3432 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3433 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3434 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3435 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3436 /* Mic2 (as headphone out) for HP output */
3437 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3438 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3439 /* Line In pin widget for input */
3440 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3441 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3442 /* Line2 (as front mic) pin widget for input and vref at 80% */
3443 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3444 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3445 /* CD pin widget for input */
3446 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3452 * 5-stack pin configuration:
3453 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3454 * line-in/side = 0x1a, f-mic = 0x1b
3456 static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3458 * preset connection lists of input pins
3459 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3461 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3462 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3465 * Set pin mode and muting
3467 /* set pin widgets 0x14-0x17 for output */
3468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3470 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3471 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3472 /* unmute pins for output (no gain on this amp) */
3473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3475 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3476 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3478 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3479 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3481 /* Mic2 (as headphone out) for HP output */
3482 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3483 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3484 /* Line In pin widget for input */
3485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3486 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3487 /* Line2 (as front mic) pin widget for input and vref at 80% */
3488 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3489 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3490 /* CD pin widget for input */
3491 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3497 * W810 pin configuration:
3498 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3500 static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3501 /* hphone/speaker input selector: front DAC */
3502 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3507 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3508 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3509 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3511 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3518 * Z71V pin configuration:
3519 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3521 static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3523 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3527 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3530 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3536 * 6-stack pin configuration:
3537 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3538 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3540 static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3541 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3543 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3544 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3547 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3548 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3549 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3550 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3554 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3556 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3558 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3559 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3560 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3566 * Uniwill pin configuration:
3567 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3570 static const struct hda_verb alc880_uniwill_init_verbs[] = {
3571 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3573 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3574 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3575 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3577 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3578 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3579 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3580 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3585 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3588 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3589 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3590 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3591 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3592 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3593 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3594 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3595 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3596 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3598 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3599 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3606 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3608 static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3609 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3612 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3613 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3614 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3615 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3616 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3619 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3626 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3627 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3631 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3632 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3637 static const struct hda_verb alc880_beep_init_verbs[] = {
3638 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3642 /* auto-toggle front mic */
3643 static void alc88x_simple_mic_automute(struct hda_codec *codec)
3645 unsigned int present;
3648 present = snd_hda_jack_detect(codec, 0x18);
3649 bits = present ? HDA_AMP_MUTE : 0;
3650 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3653 static void alc880_uniwill_setup(struct hda_codec *codec)
3655 struct alc_spec *spec = codec->spec;
3657 spec->autocfg.hp_pins[0] = 0x14;
3658 spec->autocfg.speaker_pins[0] = 0x15;
3659 spec->autocfg.speaker_pins[0] = 0x16;
3661 spec->automute_mode = ALC_AUTOMUTE_AMP;
3664 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3666 alc_hp_automute(codec);
3667 alc88x_simple_mic_automute(codec);
3670 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3673 /* Looks like the unsol event is incompatible with the standard
3674 * definition. 4bit tag is placed at 28 bit!
3676 switch (res >> 28) {
3677 case ALC880_MIC_EVENT:
3678 alc88x_simple_mic_automute(codec);
3681 alc_sku_unsol_event(codec, res);
3686 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3688 struct alc_spec *spec = codec->spec;
3690 spec->autocfg.hp_pins[0] = 0x14;
3691 spec->autocfg.speaker_pins[0] = 0x15;
3693 spec->automute_mode = ALC_AUTOMUTE_AMP;
3696 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3698 unsigned int present;
3700 present = snd_hda_codec_read(codec, 0x21, 0,
3701 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3702 present &= HDA_AMP_VOLMASK;
3703 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3704 HDA_AMP_VOLMASK, present);
3705 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3706 HDA_AMP_VOLMASK, present);
3709 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3712 /* Looks like the unsol event is incompatible with the standard
3713 * definition. 4bit tag is placed at 28 bit!
3715 if ((res >> 28) == ALC880_DCVOL_EVENT)
3716 alc880_uniwill_p53_dcvol_automute(codec);
3718 alc_sku_unsol_event(codec, res);
3722 * F1734 pin configuration:
3723 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3725 static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3726 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3727 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3728 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3729 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3730 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3737 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3738 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3739 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3740 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3741 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3743 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3744 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3745 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3747 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3748 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3754 * ASUS pin configuration:
3755 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3757 static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3758 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3759 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3760 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3761 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3764 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3769 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3772 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3774 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3777 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3778 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3779 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3780 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3785 /* Enable GPIO mask and set output */
3786 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3787 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3788 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3790 /* Clevo m520g init */
3791 static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3792 /* headphone output */
3793 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3795 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3798 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3799 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3801 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3802 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3803 /* Mic1 (rear panel) */
3804 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3806 /* Mic2 (front panel) */
3807 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3808 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3810 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3811 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3812 /* change to EAPD mode */
3813 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3814 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3819 static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3820 /* change to EAPD mode */
3821 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3822 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3824 /* Headphone output */
3825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3827 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3828 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3830 /* Line In pin widget for input */
3831 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3832 /* CD pin widget for input */
3833 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3834 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3835 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3837 /* change to EAPD mode */
3838 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3839 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3845 * LG m1 express dual
3848 * Rear Line-In/Out (blue): 0x14
3849 * Build-in Mic-In: 0x15
3851 * HP-Out (green): 0x1b
3852 * Mic-In/Out (red): 0x19
3856 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3857 static const hda_nid_t alc880_lg_dac_nids[3] = {
3861 /* seems analog CD is not working */
3862 static const struct hda_input_mux alc880_lg_capture_source = {
3867 { "Internal Mic", 0x6 },
3871 /* 2,4,6 channel modes */
3872 static const struct hda_verb alc880_lg_ch2_init[] = {
3873 /* set line-in and mic-in to input */
3874 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3875 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3879 static const struct hda_verb alc880_lg_ch4_init[] = {
3880 /* set line-in to out and mic-in to input */
3881 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3882 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3886 static const struct hda_verb alc880_lg_ch6_init[] = {
3887 /* set line-in and mic-in to output */
3888 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3889 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3893 static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3894 { 2, alc880_lg_ch2_init },
3895 { 4, alc880_lg_ch4_init },
3896 { 6, alc880_lg_ch6_init },
3899 static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3900 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3901 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3902 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3903 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3904 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3905 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3906 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3907 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3908 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3909 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3910 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3911 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3912 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3913 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3916 .name = "Channel Mode",
3917 .info = alc_ch_mode_info,
3918 .get = alc_ch_mode_get,
3919 .put = alc_ch_mode_put,
3924 static const struct hda_verb alc880_lg_init_verbs[] = {
3925 /* set capture source to mic-in */
3926 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3927 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3929 /* mute all amp mixer inputs */
3930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3933 /* line-in to input */
3934 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3935 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3937 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3938 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3940 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3941 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3942 /* mic-in to input */
3943 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3944 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3945 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3947 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3948 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3949 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3951 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3955 /* toggle speaker-output according to the hp-jack state */
3956 static void alc880_lg_setup(struct hda_codec *codec)
3958 struct alc_spec *spec = codec->spec;
3960 spec->autocfg.hp_pins[0] = 0x1b;
3961 spec->autocfg.speaker_pins[0] = 0x17;
3963 spec->automute_mode = ALC_AUTOMUTE_AMP;
3972 * Built-in Mic-In: 0x19
3978 static const struct hda_input_mux alc880_lg_lw_capture_source = {
3982 { "Internal Mic", 0x1 },
3987 #define alc880_lg_lw_modes alc880_threestack_modes
3989 static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3990 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3991 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3992 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3993 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3994 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3995 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3996 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3997 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4002 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4003 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4006 .name = "Channel Mode",
4007 .info = alc_ch_mode_info,
4008 .get = alc_ch_mode_get,
4009 .put = alc_ch_mode_put,
4014 static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4015 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4016 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4017 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4019 /* set capture source to mic-in */
4020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4021 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4025 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4026 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4029 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4030 /* mic-in to input */
4031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4032 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4034 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4035 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4037 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4041 /* toggle speaker-output according to the hp-jack state */
4042 static void alc880_lg_lw_setup(struct hda_codec *codec)
4044 struct alc_spec *spec = codec->spec;
4046 spec->autocfg.hp_pins[0] = 0x1b;
4047 spec->autocfg.speaker_pins[0] = 0x14;
4049 spec->automute_mode = ALC_AUTOMUTE_AMP;
4052 static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4053 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4054 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4055 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4056 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4057 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4058 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4062 static const struct hda_input_mux alc880_medion_rim_capture_source = {
4066 { "Internal Mic", 0x1 },
4070 static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4071 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4073 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4074 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4076 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4077 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4078 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4079 /* Mic2 (as headphone out) for HP output */
4080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4081 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4082 /* Internal Speaker */
4083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4086 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4087 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4089 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4093 /* toggle speaker-output according to the hp-jack state */
4094 static void alc880_medion_rim_automute(struct hda_codec *codec)
4096 struct alc_spec *spec = codec->spec;
4097 alc_hp_automute(codec);
4099 if (spec->jack_present)
4100 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4102 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4105 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4108 /* Looks like the unsol event is incompatible with the standard
4109 * definition. 4bit tag is placed at 28 bit!
4111 if ((res >> 28) == ALC880_HP_EVENT)
4112 alc880_medion_rim_automute(codec);
4115 static void alc880_medion_rim_setup(struct hda_codec *codec)
4117 struct alc_spec *spec = codec->spec;
4119 spec->autocfg.hp_pins[0] = 0x14;
4120 spec->autocfg.speaker_pins[0] = 0x1b;
4122 spec->automute_mode = ALC_AUTOMUTE_AMP;
4125 #ifdef CONFIG_SND_HDA_POWER_SAVE
4126 static const struct hda_amp_list alc880_loopbacks[] = {
4127 { 0x0b, HDA_INPUT, 0 },
4128 { 0x0b, HDA_INPUT, 1 },
4129 { 0x0b, HDA_INPUT, 2 },
4130 { 0x0b, HDA_INPUT, 3 },
4131 { 0x0b, HDA_INPUT, 4 },
4135 static const struct hda_amp_list alc880_lg_loopbacks[] = {
4136 { 0x0b, HDA_INPUT, 1 },
4137 { 0x0b, HDA_INPUT, 6 },
4138 { 0x0b, HDA_INPUT, 7 },
4147 static void alc_init_special_input_src(struct hda_codec *codec);
4149 static int alc_init(struct hda_codec *codec)
4151 struct alc_spec *spec = codec->spec;
4155 alc_auto_init_amp(codec, spec->init_amp);
4157 for (i = 0; i < spec->num_init_verbs; i++)
4158 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4159 alc_init_special_input_src(codec);
4161 if (spec->init_hook)
4162 spec->init_hook(codec);
4164 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4166 hda_call_check_power_status(codec, 0x01);
4170 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4172 struct alc_spec *spec = codec->spec;
4174 if (spec->unsol_event)
4175 spec->unsol_event(codec, res);
4178 #ifdef CONFIG_SND_HDA_POWER_SAVE
4179 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4181 struct alc_spec *spec = codec->spec;
4182 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4187 * Analog playback callbacks
4189 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4190 struct hda_codec *codec,
4191 struct snd_pcm_substream *substream)
4193 struct alc_spec *spec = codec->spec;
4194 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4198 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4199 struct hda_codec *codec,
4200 unsigned int stream_tag,
4201 unsigned int format,
4202 struct snd_pcm_substream *substream)
4204 struct alc_spec *spec = codec->spec;
4205 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4206 stream_tag, format, substream);
4209 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4210 struct hda_codec *codec,
4211 struct snd_pcm_substream *substream)
4213 struct alc_spec *spec = codec->spec;
4214 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4220 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4221 struct hda_codec *codec,
4222 struct snd_pcm_substream *substream)
4224 struct alc_spec *spec = codec->spec;
4225 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4228 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4229 struct hda_codec *codec,
4230 unsigned int stream_tag,
4231 unsigned int format,
4232 struct snd_pcm_substream *substream)
4234 struct alc_spec *spec = codec->spec;
4235 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4236 stream_tag, format, substream);
4239 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4240 struct hda_codec *codec,
4241 struct snd_pcm_substream *substream)
4243 struct alc_spec *spec = codec->spec;
4244 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4247 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4248 struct hda_codec *codec,
4249 struct snd_pcm_substream *substream)
4251 struct alc_spec *spec = codec->spec;
4252 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4258 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4259 struct hda_codec *codec,
4260 unsigned int stream_tag,
4261 unsigned int format,
4262 struct snd_pcm_substream *substream)
4264 struct alc_spec *spec = codec->spec;
4266 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4267 stream_tag, 0, format);
4271 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4272 struct hda_codec *codec,
4273 struct snd_pcm_substream *substream)
4275 struct alc_spec *spec = codec->spec;
4277 snd_hda_codec_cleanup_stream(codec,
4278 spec->adc_nids[substream->number + 1]);
4282 /* analog capture with dynamic dual-adc changes */
4283 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4284 struct hda_codec *codec,
4285 unsigned int stream_tag,
4286 unsigned int format,
4287 struct snd_pcm_substream *substream)
4289 struct alc_spec *spec = codec->spec;
4290 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4291 spec->cur_adc_stream_tag = stream_tag;
4292 spec->cur_adc_format = format;
4293 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4297 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4298 struct hda_codec *codec,
4299 struct snd_pcm_substream *substream)
4301 struct alc_spec *spec = codec->spec;
4302 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4307 static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4311 .nid = 0, /* fill later */
4313 .prepare = dualmic_capture_pcm_prepare,
4314 .cleanup = dualmic_capture_pcm_cleanup
4320 static const struct hda_pcm_stream alc880_pcm_analog_playback = {
4324 /* NID is set in alc_build_pcms */
4326 .open = alc880_playback_pcm_open,
4327 .prepare = alc880_playback_pcm_prepare,
4328 .cleanup = alc880_playback_pcm_cleanup
4332 static const struct hda_pcm_stream alc880_pcm_analog_capture = {
4336 /* NID is set in alc_build_pcms */
4339 static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4343 /* NID is set in alc_build_pcms */
4346 static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4347 .substreams = 2, /* can be overridden */
4350 /* NID is set in alc_build_pcms */
4352 .prepare = alc880_alt_capture_pcm_prepare,
4353 .cleanup = alc880_alt_capture_pcm_cleanup
4357 static const struct hda_pcm_stream alc880_pcm_digital_playback = {
4361 /* NID is set in alc_build_pcms */
4363 .open = alc880_dig_playback_pcm_open,
4364 .close = alc880_dig_playback_pcm_close,
4365 .prepare = alc880_dig_playback_pcm_prepare,
4366 .cleanup = alc880_dig_playback_pcm_cleanup
4370 static const struct hda_pcm_stream alc880_pcm_digital_capture = {
4374 /* NID is set in alc_build_pcms */
4377 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
4378 static const struct hda_pcm_stream alc_pcm_null_stream = {
4384 static int alc_build_pcms(struct hda_codec *codec)
4386 struct alc_spec *spec = codec->spec;
4387 struct hda_pcm *info = spec->pcm_rec;
4390 codec->num_pcms = 1;
4391 codec->pcm_info = info;
4393 if (spec->no_analog)
4396 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4397 "%s Analog", codec->chip_name);
4398 info->name = spec->stream_name_analog;
4400 if (spec->stream_analog_playback) {
4401 if (snd_BUG_ON(!spec->multiout.dac_nids))
4403 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4404 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4406 if (spec->stream_analog_capture) {
4407 if (snd_BUG_ON(!spec->adc_nids))
4409 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4410 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4413 if (spec->channel_mode) {
4414 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4415 for (i = 0; i < spec->num_channel_mode; i++) {
4416 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4417 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4423 /* SPDIF for stream index #1 */
4424 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4425 snprintf(spec->stream_name_digital,
4426 sizeof(spec->stream_name_digital),
4427 "%s Digital", codec->chip_name);
4428 codec->num_pcms = 2;
4429 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4430 info = spec->pcm_rec + 1;
4431 info->name = spec->stream_name_digital;
4432 if (spec->dig_out_type)
4433 info->pcm_type = spec->dig_out_type;
4435 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4436 if (spec->multiout.dig_out_nid &&
4437 spec->stream_digital_playback) {
4438 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4439 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4441 if (spec->dig_in_nid &&
4442 spec->stream_digital_capture) {
4443 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4444 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4446 /* FIXME: do we need this for all Realtek codec models? */
4447 codec->spdif_status_reset = 1;
4450 if (spec->no_analog)
4453 /* If the use of more than one ADC is requested for the current
4454 * model, configure a second analog capture-only PCM.
4456 /* Additional Analaog capture for index #2 */
4457 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4458 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4459 codec->num_pcms = 3;
4460 info = spec->pcm_rec + 2;
4461 info->name = spec->stream_name_analog;
4462 if (spec->alt_dac_nid) {
4463 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4464 *spec->stream_analog_alt_playback;
4465 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4468 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4469 alc_pcm_null_stream;
4470 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4472 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
4473 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4474 *spec->stream_analog_alt_capture;
4475 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4477 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4478 spec->num_adc_nids - 1;
4480 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4481 alc_pcm_null_stream;
4482 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4489 static inline void alc_shutup(struct hda_codec *codec)
4491 struct alc_spec *spec = codec->spec;
4493 if (spec && spec->shutup)
4494 spec->shutup(codec);
4495 snd_hda_shutup_pins(codec);
4498 static void alc_free_kctls(struct hda_codec *codec)
4500 struct alc_spec *spec = codec->spec;
4502 if (spec->kctls.list) {
4503 struct snd_kcontrol_new *kctl = spec->kctls.list;
4505 for (i = 0; i < spec->kctls.used; i++)
4506 kfree(kctl[i].name);
4508 snd_array_free(&spec->kctls);
4511 static void alc_free(struct hda_codec *codec)
4513 struct alc_spec *spec = codec->spec;
4519 snd_hda_input_jack_free(codec);
4520 alc_free_kctls(codec);
4522 snd_hda_detach_beep_device(codec);
4525 #ifdef CONFIG_SND_HDA_POWER_SAVE
4526 static void alc_power_eapd(struct hda_codec *codec)
4528 alc_auto_setup_eapd(codec, false);
4531 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4533 struct alc_spec *spec = codec->spec;
4535 if (spec && spec->power_hook)
4536 spec->power_hook(codec);
4541 #ifdef SND_HDA_NEEDS_RESUME
4542 static int alc_resume(struct hda_codec *codec)
4544 msleep(150); /* to avoid pop noise */
4545 codec->patch_ops.init(codec);
4546 snd_hda_codec_resume_amp(codec);
4547 snd_hda_codec_resume_cache(codec);
4548 hda_call_check_power_status(codec, 0x01);
4555 static const struct hda_codec_ops alc_patch_ops = {
4556 .build_controls = alc_build_controls,
4557 .build_pcms = alc_build_pcms,
4560 .unsol_event = alc_unsol_event,
4561 #ifdef SND_HDA_NEEDS_RESUME
4562 .resume = alc_resume,
4564 #ifdef CONFIG_SND_HDA_POWER_SAVE
4565 .suspend = alc_suspend,
4566 .check_power_status = alc_check_power_status,
4568 .reboot_notify = alc_shutup,
4571 /* replace the codec chip_name with the given string */
4572 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4574 kfree(codec->chip_name);
4575 codec->chip_name = kstrdup(name, GFP_KERNEL);
4576 if (!codec->chip_name) {
4584 * Test configuration for debugging
4586 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4589 #ifdef CONFIG_SND_DEBUG
4590 static const hda_nid_t alc880_test_dac_nids[4] = {
4591 0x02, 0x03, 0x04, 0x05
4594 static const struct hda_input_mux alc880_test_capture_source = {
4603 { "Surround", 0x6 },
4607 static const struct hda_channel_mode alc880_test_modes[4] = {
4614 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4615 struct snd_ctl_elem_info *uinfo)
4617 static const char * const texts[] = {
4618 "N/A", "Line Out", "HP Out",
4619 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4621 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4623 uinfo->value.enumerated.items = 8;
4624 if (uinfo->value.enumerated.item >= 8)
4625 uinfo->value.enumerated.item = 7;
4626 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4630 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4631 struct snd_ctl_elem_value *ucontrol)
4633 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4634 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4635 unsigned int pin_ctl, item = 0;
4637 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4638 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4639 if (pin_ctl & AC_PINCTL_OUT_EN) {
4640 if (pin_ctl & AC_PINCTL_HP_EN)
4644 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4645 switch (pin_ctl & AC_PINCTL_VREFEN) {
4646 case AC_PINCTL_VREF_HIZ: item = 3; break;
4647 case AC_PINCTL_VREF_50: item = 4; break;
4648 case AC_PINCTL_VREF_GRD: item = 5; break;
4649 case AC_PINCTL_VREF_80: item = 6; break;
4650 case AC_PINCTL_VREF_100: item = 7; break;
4653 ucontrol->value.enumerated.item[0] = item;
4657 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4658 struct snd_ctl_elem_value *ucontrol)
4660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4661 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4662 static const unsigned int ctls[] = {
4663 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4664 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4665 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4666 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4667 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4668 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4670 unsigned int old_ctl, new_ctl;
4672 old_ctl = snd_hda_codec_read(codec, nid, 0,
4673 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4674 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4675 if (old_ctl != new_ctl) {
4677 snd_hda_codec_write_cache(codec, nid, 0,
4678 AC_VERB_SET_PIN_WIDGET_CONTROL,
4680 val = ucontrol->value.enumerated.item[0] >= 3 ?
4682 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4689 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4690 struct snd_ctl_elem_info *uinfo)
4692 static const char * const texts[] = {
4693 "Front", "Surround", "CLFE", "Side"
4695 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4697 uinfo->value.enumerated.items = 4;
4698 if (uinfo->value.enumerated.item >= 4)
4699 uinfo->value.enumerated.item = 3;
4700 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4704 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4705 struct snd_ctl_elem_value *ucontrol)
4707 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4708 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4711 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4712 ucontrol->value.enumerated.item[0] = sel & 3;
4716 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4717 struct snd_ctl_elem_value *ucontrol)
4719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4720 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4723 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4724 if (ucontrol->value.enumerated.item[0] != sel) {
4725 sel = ucontrol->value.enumerated.item[0] & 3;
4726 snd_hda_codec_write_cache(codec, nid, 0,
4727 AC_VERB_SET_CONNECT_SEL, sel);
4733 #define PIN_CTL_TEST(xname,nid) { \
4734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4737 .info = alc_test_pin_ctl_info, \
4738 .get = alc_test_pin_ctl_get, \
4739 .put = alc_test_pin_ctl_put, \
4740 .private_value = nid \
4743 #define PIN_SRC_TEST(xname,nid) { \
4744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4746 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4747 .info = alc_test_pin_src_info, \
4748 .get = alc_test_pin_src_get, \
4749 .put = alc_test_pin_src_put, \
4750 .private_value = nid \
4753 static const struct snd_kcontrol_new alc880_test_mixer[] = {
4754 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4755 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4756 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4757 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4759 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4760 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4761 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4762 PIN_CTL_TEST("Front Pin Mode", 0x14),
4763 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4764 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4765 PIN_CTL_TEST("Side Pin Mode", 0x17),
4766 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4767 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4768 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4769 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4770 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4771 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4772 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4773 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4774 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4775 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4776 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4777 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4778 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4779 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4780 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4781 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4782 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4783 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4786 .name = "Channel Mode",
4787 .info = alc_ch_mode_info,
4788 .get = alc_ch_mode_get,
4789 .put = alc_ch_mode_put,
4794 static const struct hda_verb alc880_test_init_verbs[] = {
4795 /* Unmute inputs of 0x0c - 0x0f */
4796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4798 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4799 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4800 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4801 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4803 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4804 /* Vol output for 0x0c-0x0f */
4805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4809 /* Set output pins 0x14-0x17 */
4810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4812 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4813 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4814 /* Unmute output pins 0x14-0x17 */
4815 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4817 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4818 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4819 /* Set input pins 0x18-0x1c */
4820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4821 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4822 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4824 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4825 /* Mute input pins 0x18-0x1b */
4826 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4827 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4829 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4832 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4836 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4837 /* Analog input/passthru */
4838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4850 static const char * const alc880_models[ALC880_MODEL_LAST] = {
4851 [ALC880_3ST] = "3stack",
4852 [ALC880_TCL_S700] = "tcl",
4853 [ALC880_3ST_DIG] = "3stack-digout",
4854 [ALC880_CLEVO] = "clevo",
4855 [ALC880_5ST] = "5stack",
4856 [ALC880_5ST_DIG] = "5stack-digout",
4857 [ALC880_W810] = "w810",
4858 [ALC880_Z71V] = "z71v",
4859 [ALC880_6ST] = "6stack",
4860 [ALC880_6ST_DIG] = "6stack-digout",
4861 [ALC880_ASUS] = "asus",
4862 [ALC880_ASUS_W1V] = "asus-w1v",
4863 [ALC880_ASUS_DIG] = "asus-dig",
4864 [ALC880_ASUS_DIG2] = "asus-dig2",
4865 [ALC880_UNIWILL_DIG] = "uniwill",
4866 [ALC880_UNIWILL_P53] = "uniwill-p53",
4867 [ALC880_FUJITSU] = "fujitsu",
4868 [ALC880_F1734] = "F1734",
4870 [ALC880_LG_LW] = "lg-lw",
4871 [ALC880_MEDION_RIM] = "medion",
4872 #ifdef CONFIG_SND_DEBUG
4873 [ALC880_TEST] = "test",
4875 [ALC880_AUTO] = "auto",
4878 static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4879 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4880 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4881 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4882 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4883 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4884 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4885 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4886 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4887 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4888 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4889 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4890 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4891 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4892 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4893 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4894 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4895 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4896 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4897 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4898 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4899 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4900 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4901 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4902 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4903 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4904 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4905 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4906 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4907 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4908 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4909 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4910 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4911 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4912 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4913 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4914 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4915 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4916 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4917 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4918 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4919 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4920 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4921 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4922 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4923 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4924 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4925 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4926 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4927 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4928 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4929 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4930 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4931 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4932 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4933 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4934 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4935 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4936 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4937 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4938 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4939 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4940 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4941 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4942 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4943 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4944 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4945 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4946 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4948 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4949 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4950 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4955 * ALC880 codec presets
4957 static const struct alc_config_preset alc880_presets[] = {
4959 .mixers = { alc880_three_stack_mixer },
4960 .init_verbs = { alc880_volume_init_verbs,
4961 alc880_pin_3stack_init_verbs },
4962 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4963 .dac_nids = alc880_dac_nids,
4964 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4965 .channel_mode = alc880_threestack_modes,
4967 .input_mux = &alc880_capture_source,
4969 [ALC880_3ST_DIG] = {
4970 .mixers = { alc880_three_stack_mixer },
4971 .init_verbs = { alc880_volume_init_verbs,
4972 alc880_pin_3stack_init_verbs },
4973 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4974 .dac_nids = alc880_dac_nids,
4975 .dig_out_nid = ALC880_DIGOUT_NID,
4976 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4977 .channel_mode = alc880_threestack_modes,
4979 .input_mux = &alc880_capture_source,
4981 [ALC880_TCL_S700] = {
4982 .mixers = { alc880_tcl_s700_mixer },
4983 .init_verbs = { alc880_volume_init_verbs,
4984 alc880_pin_tcl_S700_init_verbs,
4985 alc880_gpio2_init_verbs },
4986 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4987 .dac_nids = alc880_dac_nids,
4988 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4989 .num_adc_nids = 1, /* single ADC */
4991 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4992 .channel_mode = alc880_2_jack_modes,
4993 .input_mux = &alc880_capture_source,
4996 .mixers = { alc880_three_stack_mixer,
4997 alc880_five_stack_mixer},
4998 .init_verbs = { alc880_volume_init_verbs,
4999 alc880_pin_5stack_init_verbs },
5000 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5001 .dac_nids = alc880_dac_nids,
5002 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5003 .channel_mode = alc880_fivestack_modes,
5004 .input_mux = &alc880_capture_source,
5006 [ALC880_5ST_DIG] = {
5007 .mixers = { alc880_three_stack_mixer,
5008 alc880_five_stack_mixer },
5009 .init_verbs = { alc880_volume_init_verbs,
5010 alc880_pin_5stack_init_verbs },
5011 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5012 .dac_nids = alc880_dac_nids,
5013 .dig_out_nid = ALC880_DIGOUT_NID,
5014 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5015 .channel_mode = alc880_fivestack_modes,
5016 .input_mux = &alc880_capture_source,
5019 .mixers = { alc880_six_stack_mixer },
5020 .init_verbs = { alc880_volume_init_verbs,
5021 alc880_pin_6stack_init_verbs },
5022 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5023 .dac_nids = alc880_6st_dac_nids,
5024 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5025 .channel_mode = alc880_sixstack_modes,
5026 .input_mux = &alc880_6stack_capture_source,
5028 [ALC880_6ST_DIG] = {
5029 .mixers = { alc880_six_stack_mixer },
5030 .init_verbs = { alc880_volume_init_verbs,
5031 alc880_pin_6stack_init_verbs },
5032 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5033 .dac_nids = alc880_6st_dac_nids,
5034 .dig_out_nid = ALC880_DIGOUT_NID,
5035 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5036 .channel_mode = alc880_sixstack_modes,
5037 .input_mux = &alc880_6stack_capture_source,
5040 .mixers = { alc880_w810_base_mixer },
5041 .init_verbs = { alc880_volume_init_verbs,
5042 alc880_pin_w810_init_verbs,
5043 alc880_gpio2_init_verbs },
5044 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5045 .dac_nids = alc880_w810_dac_nids,
5046 .dig_out_nid = ALC880_DIGOUT_NID,
5047 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5048 .channel_mode = alc880_w810_modes,
5049 .input_mux = &alc880_capture_source,
5052 .mixers = { alc880_z71v_mixer },
5053 .init_verbs = { alc880_volume_init_verbs,
5054 alc880_pin_z71v_init_verbs },
5055 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5056 .dac_nids = alc880_z71v_dac_nids,
5057 .dig_out_nid = ALC880_DIGOUT_NID,
5059 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5060 .channel_mode = alc880_2_jack_modes,
5061 .input_mux = &alc880_capture_source,
5064 .mixers = { alc880_f1734_mixer },
5065 .init_verbs = { alc880_volume_init_verbs,
5066 alc880_pin_f1734_init_verbs },
5067 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5068 .dac_nids = alc880_f1734_dac_nids,
5070 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5071 .channel_mode = alc880_2_jack_modes,
5072 .input_mux = &alc880_f1734_capture_source,
5073 .unsol_event = alc880_uniwill_p53_unsol_event,
5074 .setup = alc880_uniwill_p53_setup,
5075 .init_hook = alc_hp_automute,
5078 .mixers = { alc880_asus_mixer },
5079 .init_verbs = { alc880_volume_init_verbs,
5080 alc880_pin_asus_init_verbs,
5081 alc880_gpio1_init_verbs },
5082 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5083 .dac_nids = alc880_asus_dac_nids,
5084 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5085 .channel_mode = alc880_asus_modes,
5087 .input_mux = &alc880_capture_source,
5089 [ALC880_ASUS_DIG] = {
5090 .mixers = { alc880_asus_mixer },
5091 .init_verbs = { alc880_volume_init_verbs,
5092 alc880_pin_asus_init_verbs,
5093 alc880_gpio1_init_verbs },
5094 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5095 .dac_nids = alc880_asus_dac_nids,
5096 .dig_out_nid = ALC880_DIGOUT_NID,
5097 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5098 .channel_mode = alc880_asus_modes,
5100 .input_mux = &alc880_capture_source,
5102 [ALC880_ASUS_DIG2] = {
5103 .mixers = { alc880_asus_mixer },
5104 .init_verbs = { alc880_volume_init_verbs,
5105 alc880_pin_asus_init_verbs,
5106 alc880_gpio2_init_verbs }, /* use GPIO2 */
5107 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5108 .dac_nids = alc880_asus_dac_nids,
5109 .dig_out_nid = ALC880_DIGOUT_NID,
5110 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5111 .channel_mode = alc880_asus_modes,
5113 .input_mux = &alc880_capture_source,
5115 [ALC880_ASUS_W1V] = {
5116 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5117 .init_verbs = { alc880_volume_init_verbs,
5118 alc880_pin_asus_init_verbs,
5119 alc880_gpio1_init_verbs },
5120 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5121 .dac_nids = alc880_asus_dac_nids,
5122 .dig_out_nid = ALC880_DIGOUT_NID,
5123 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5124 .channel_mode = alc880_asus_modes,
5126 .input_mux = &alc880_capture_source,
5128 [ALC880_UNIWILL_DIG] = {
5129 .mixers = { alc880_asus_mixer },
5130 .init_verbs = { alc880_volume_init_verbs,
5131 alc880_pin_asus_init_verbs },
5132 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5133 .dac_nids = alc880_asus_dac_nids,
5134 .dig_out_nid = ALC880_DIGOUT_NID,
5135 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5136 .channel_mode = alc880_asus_modes,
5138 .input_mux = &alc880_capture_source,
5140 [ALC880_UNIWILL] = {
5141 .mixers = { alc880_uniwill_mixer },
5142 .init_verbs = { alc880_volume_init_verbs,
5143 alc880_uniwill_init_verbs },
5144 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5145 .dac_nids = alc880_asus_dac_nids,
5146 .dig_out_nid = ALC880_DIGOUT_NID,
5147 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5148 .channel_mode = alc880_threestack_modes,
5150 .input_mux = &alc880_capture_source,
5151 .unsol_event = alc880_uniwill_unsol_event,
5152 .setup = alc880_uniwill_setup,
5153 .init_hook = alc880_uniwill_init_hook,
5155 [ALC880_UNIWILL_P53] = {
5156 .mixers = { alc880_uniwill_p53_mixer },
5157 .init_verbs = { alc880_volume_init_verbs,
5158 alc880_uniwill_p53_init_verbs },
5159 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5160 .dac_nids = alc880_asus_dac_nids,
5161 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5162 .channel_mode = alc880_threestack_modes,
5163 .input_mux = &alc880_capture_source,
5164 .unsol_event = alc880_uniwill_p53_unsol_event,
5165 .setup = alc880_uniwill_p53_setup,
5166 .init_hook = alc_hp_automute,
5168 [ALC880_FUJITSU] = {
5169 .mixers = { alc880_fujitsu_mixer },
5170 .init_verbs = { alc880_volume_init_verbs,
5171 alc880_uniwill_p53_init_verbs,
5172 alc880_beep_init_verbs },
5173 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5174 .dac_nids = alc880_dac_nids,
5175 .dig_out_nid = ALC880_DIGOUT_NID,
5176 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5177 .channel_mode = alc880_2_jack_modes,
5178 .input_mux = &alc880_capture_source,
5179 .unsol_event = alc880_uniwill_p53_unsol_event,
5180 .setup = alc880_uniwill_p53_setup,
5181 .init_hook = alc_hp_automute,
5184 .mixers = { alc880_three_stack_mixer },
5185 .init_verbs = { alc880_volume_init_verbs,
5186 alc880_pin_clevo_init_verbs },
5187 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5188 .dac_nids = alc880_dac_nids,
5190 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5191 .channel_mode = alc880_threestack_modes,
5193 .input_mux = &alc880_capture_source,
5196 .mixers = { alc880_lg_mixer },
5197 .init_verbs = { alc880_volume_init_verbs,
5198 alc880_lg_init_verbs },
5199 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5200 .dac_nids = alc880_lg_dac_nids,
5201 .dig_out_nid = ALC880_DIGOUT_NID,
5202 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5203 .channel_mode = alc880_lg_ch_modes,
5205 .input_mux = &alc880_lg_capture_source,
5206 .unsol_event = alc_sku_unsol_event,
5207 .setup = alc880_lg_setup,
5208 .init_hook = alc_hp_automute,
5209 #ifdef CONFIG_SND_HDA_POWER_SAVE
5210 .loopbacks = alc880_lg_loopbacks,
5214 .mixers = { alc880_lg_lw_mixer },
5215 .init_verbs = { alc880_volume_init_verbs,
5216 alc880_lg_lw_init_verbs },
5217 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5218 .dac_nids = alc880_dac_nids,
5219 .dig_out_nid = ALC880_DIGOUT_NID,
5220 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5221 .channel_mode = alc880_lg_lw_modes,
5222 .input_mux = &alc880_lg_lw_capture_source,
5223 .unsol_event = alc_sku_unsol_event,
5224 .setup = alc880_lg_lw_setup,
5225 .init_hook = alc_hp_automute,
5227 [ALC880_MEDION_RIM] = {
5228 .mixers = { alc880_medion_rim_mixer },
5229 .init_verbs = { alc880_volume_init_verbs,
5230 alc880_medion_rim_init_verbs,
5231 alc_gpio2_init_verbs },
5232 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5233 .dac_nids = alc880_dac_nids,
5234 .dig_out_nid = ALC880_DIGOUT_NID,
5235 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5236 .channel_mode = alc880_2_jack_modes,
5237 .input_mux = &alc880_medion_rim_capture_source,
5238 .unsol_event = alc880_medion_rim_unsol_event,
5239 .setup = alc880_medion_rim_setup,
5240 .init_hook = alc880_medion_rim_automute,
5242 #ifdef CONFIG_SND_DEBUG
5244 .mixers = { alc880_test_mixer },
5245 .init_verbs = { alc880_test_init_verbs },
5246 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5247 .dac_nids = alc880_test_dac_nids,
5248 .dig_out_nid = ALC880_DIGOUT_NID,
5249 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5250 .channel_mode = alc880_test_modes,
5251 .input_mux = &alc880_test_capture_source,
5257 * Automatic parse of I/O pins from the BIOS configuration
5262 ALC_CTL_WIDGET_MUTE,
5265 static const struct snd_kcontrol_new alc880_control_templates[] = {
5266 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5267 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5268 HDA_BIND_MUTE(NULL, 0, 0, 0),
5271 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5273 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5274 return snd_array_new(&spec->kctls);
5277 /* add dynamic controls */
5278 static int add_control(struct alc_spec *spec, int type, const char *name,
5279 int cidx, unsigned long val)
5281 struct snd_kcontrol_new *knew;
5283 knew = alc_kcontrol_new(spec);
5286 *knew = alc880_control_templates[type];
5287 knew->name = kstrdup(name, GFP_KERNEL);
5291 if (get_amp_nid_(val))
5292 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5293 knew->private_value = val;
5297 static int add_control_with_pfx(struct alc_spec *spec, int type,
5298 const char *pfx, const char *dir,
5299 const char *sfx, int cidx, unsigned long val)
5302 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5303 return add_control(spec, type, name, cidx, val);
5306 #define add_pb_vol_ctrl(spec, type, pfx, val) \
5307 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5308 #define add_pb_sw_ctrl(spec, type, pfx, val) \
5309 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5310 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5311 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5312 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5313 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5315 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5316 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5317 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5318 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5319 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
5320 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
5321 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5322 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
5323 #define ALC880_PIN_CD_NID 0x1c
5325 /* fill in the dac_nids table from the parsed pin configuration */
5326 static int alc880_auto_fill_dac_nids(struct hda_codec *codec)
5328 struct alc_spec *spec = codec->spec;
5329 const struct auto_pin_cfg *cfg = &spec->autocfg;
5334 memset(assigned, 0, sizeof(assigned));
5335 spec->multiout.dac_nids = spec->private_dac_nids;
5337 /* check the pins hardwired to audio widget */
5338 for (i = 0; i < cfg->line_outs; i++) {
5339 nid = cfg->line_out_pins[i];
5340 if (alc880_is_fixed_pin(nid)) {
5341 int idx = alc880_fixed_pin_idx(nid);
5342 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5346 /* left pins can be connect to any audio widget */
5347 for (i = 0; i < cfg->line_outs; i++) {
5348 nid = cfg->line_out_pins[i];
5349 if (alc880_is_fixed_pin(nid))
5351 /* search for an empty channel */
5352 for (j = 0; j < cfg->line_outs; j++) {
5354 spec->private_dac_nids[i] =
5355 alc880_idx_to_dac(j);
5361 spec->multiout.num_dacs = cfg->line_outs;
5365 static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5366 bool can_be_master, int *index)
5368 struct auto_pin_cfg *cfg = &spec->autocfg;
5369 static const char * const chname[4] = {
5370 "Front", "Surround", NULL /*CLFE*/, "Side"
5374 if (cfg->line_outs == 1 && !spec->multi_ios &&
5375 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5378 switch (cfg->line_out_type) {
5379 case AUTO_PIN_SPEAKER_OUT:
5380 if (cfg->line_outs == 1)
5383 case AUTO_PIN_HP_OUT:
5384 /* for multi-io case, only the primary out */
5385 if (ch && spec->multi_ios)
5390 if (cfg->line_outs == 1 && !spec->multi_ios)
5397 /* add playback controls from the parsed DAC table */
5398 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5399 const struct auto_pin_cfg *cfg)
5402 int i, err, noutputs;
5404 noutputs = cfg->line_outs;
5405 if (spec->multi_ios > 0)
5406 noutputs += spec->multi_ios;
5408 for (i = 0; i < noutputs; i++) {
5411 if (!spec->multiout.dac_nids[i])
5413 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5414 name = alc_get_line_out_pfx(spec, i, false, &index);
5417 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5419 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5423 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5425 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5429 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5431 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5435 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5437 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5442 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5444 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5448 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5450 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5459 /* add playback controls for speaker and HP outputs */
5460 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5469 if (alc880_is_fixed_pin(pin)) {
5470 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5471 /* specify the DAC as the extra output */
5472 if (!spec->multiout.hp_nid)
5473 spec->multiout.hp_nid = nid;
5475 spec->multiout.extra_out_nid[0] = nid;
5476 /* control HP volume/switch on the output mixer amp */
5477 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5478 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5479 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5482 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5483 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5486 } else if (alc880_is_multi_pin(pin)) {
5487 /* set manual connection */
5488 /* we have only a switch on HP-out PIN */
5489 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5490 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5497 /* create input playback/capture controls for the given pin */
5498 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5499 const char *ctlname, int ctlidx,
5500 int idx, hda_nid_t mix_nid)
5504 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5505 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5508 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5509 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5515 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5517 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5518 return (pincap & AC_PINCAP_IN) != 0;
5521 /* create playback/capture controls for input pins */
5522 static int alc_auto_create_input_ctls(struct hda_codec *codec,
5523 const struct auto_pin_cfg *cfg,
5525 hda_nid_t cap1, hda_nid_t cap2)
5527 struct alc_spec *spec = codec->spec;
5528 struct hda_input_mux *imux = &spec->private_imux[0];
5529 int i, err, idx, type_idx = 0;
5530 const char *prev_label = NULL;
5532 for (i = 0; i < cfg->num_inputs; i++) {
5536 pin = cfg->inputs[i].pin;
5537 if (!alc_is_input_pin(codec, pin))
5540 label = hda_get_autocfg_input_label(codec, cfg, i);
5541 if (prev_label && !strcmp(label, prev_label))
5548 idx = get_connection_index(codec, mixer, pin);
5550 err = new_analog_input(spec, pin,
5560 idx = get_connection_index(codec, cap1, pin);
5561 if (idx < 0 && cap2)
5562 idx = get_connection_index(codec, cap2, pin);
5564 snd_hda_add_imux_item(imux, label, idx, NULL);
5569 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5570 const struct auto_pin_cfg *cfg)
5572 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5575 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5576 unsigned int pin_type)
5578 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5581 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5585 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5586 hda_nid_t nid, int pin_type,
5589 alc_set_pin_output(codec, nid, pin_type);
5590 /* need the manual connection? */
5591 if (alc880_is_multi_pin(nid)) {
5592 struct alc_spec *spec = codec->spec;
5593 int idx = alc880_multi_pin_idx(nid);
5594 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5595 AC_VERB_SET_CONNECT_SEL,
5596 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5600 static int get_pin_type(int line_out_type)
5602 if (line_out_type == AUTO_PIN_HP_OUT)
5608 static void alc880_auto_init_dac(struct hda_codec *codec, hda_nid_t dac)
5614 mix = alc880_idx_to_mixer(alc880_dac_to_idx(dac));
5615 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
5617 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
5622 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5624 if (query_amp_caps(codec, mix, HDA_INPUT) & AC_AMPCAP_MUTE) {
5625 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5627 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5632 static void alc880_auto_init_multi_out(struct hda_codec *codec)
5634 struct alc_spec *spec = codec->spec;
5637 for (i = 0; i < spec->autocfg.line_outs; i++) {
5638 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5639 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5640 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5643 for (i = 0; i < spec->multiout.num_dacs; i++)
5644 alc880_auto_init_dac(codec, spec->multiout.dac_nids[i]);
5647 static void alc880_auto_init_extra_out(struct hda_codec *codec)
5649 struct alc_spec *spec = codec->spec;
5653 pin = spec->autocfg.speaker_pins[0];
5654 if (pin) /* connect to front */
5655 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5656 pin = spec->autocfg.hp_pins[0];
5657 if (pin) /* connect to front */
5658 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5660 alc880_auto_init_dac(codec, spec->multiout.hp_nid);
5661 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
5662 alc880_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
5665 static void alc880_auto_init_analog_input(struct hda_codec *codec)
5667 struct alc_spec *spec = codec->spec;
5668 struct auto_pin_cfg *cfg = &spec->autocfg;
5671 for (i = 0; i < cfg->num_inputs; i++) {
5672 hda_nid_t nid = cfg->inputs[i].pin;
5673 if (alc_is_input_pin(codec, nid)) {
5674 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5675 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
5676 snd_hda_codec_write(codec, nid, 0,
5677 AC_VERB_SET_AMP_GAIN_MUTE,
5682 /* mute all loopback inputs */
5683 if (spec->mixer_nid) {
5684 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
5685 for (i = 0; i < nums; i++)
5686 snd_hda_codec_write(codec, spec->mixer_nid, 0,
5687 AC_VERB_SET_AMP_GAIN_MUTE,
5692 static void alc880_auto_init_input_src(struct hda_codec *codec)
5694 struct alc_spec *spec = codec->spec;
5697 for (c = 0; c < spec->num_adc_nids; c++) {
5698 unsigned int mux_idx;
5699 const struct hda_input_mux *imux;
5700 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5701 imux = &spec->input_mux[mux_idx];
5702 if (!imux->num_items && mux_idx > 0)
5703 imux = &spec->input_mux[0];
5705 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5706 AC_VERB_SET_CONNECT_SEL,
5707 imux->items[0].index);
5708 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5709 AC_VERB_SET_AMP_GAIN_MUTE,
5714 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
5715 int (*fill_dac)(struct hda_codec *));
5717 /* parse the BIOS configuration and set up the alc_spec */
5718 /* return 1 if successful, 0 if the proper config is not found,
5719 * or a negative error code
5721 static int alc880_parse_auto_config(struct hda_codec *codec)
5723 struct alc_spec *spec = codec->spec;
5725 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5727 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5731 if (!spec->autocfg.line_outs)
5732 return 0; /* can't find valid BIOS pin config */
5734 err = alc880_auto_fill_dac_nids(codec);
5737 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
5740 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5743 err = alc880_auto_create_extra_out(spec,
5744 spec->autocfg.speaker_pins[0],
5748 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5752 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5756 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5758 alc_auto_parse_digital(codec);
5760 if (spec->kctls.list)
5761 add_mixer(spec, spec->kctls.list);
5763 spec->num_mux_defs = 1;
5764 spec->input_mux = &spec->private_imux[0];
5766 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5771 /* additional initialization for auto-configuration model */
5772 static void alc880_auto_init(struct hda_codec *codec)
5774 struct alc_spec *spec = codec->spec;
5775 alc880_auto_init_multi_out(codec);
5776 alc880_auto_init_extra_out(codec);
5777 alc880_auto_init_analog_input(codec);
5778 alc880_auto_init_input_src(codec);
5779 alc_auto_init_digital(codec);
5780 if (spec->unsol_event)
5781 alc_inithook(codec);
5784 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5785 * one of two digital mic pins, e.g. on ALC272
5787 static void fixup_automic_adc(struct hda_codec *codec)
5789 struct alc_spec *spec = codec->spec;
5792 for (i = 0; i < spec->num_adc_nids; i++) {
5793 hda_nid_t cap = spec->capsrc_nids ?
5794 spec->capsrc_nids[i] : spec->adc_nids[i];
5797 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5800 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5803 spec->int_mic.mux_idx = iidx;
5804 spec->ext_mic.mux_idx = eidx;
5805 if (spec->capsrc_nids)
5806 spec->capsrc_nids += i;
5807 spec->adc_nids += i;
5808 spec->num_adc_nids = 1;
5809 /* optional dock-mic */
5810 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5812 spec->dock_mic.pin = 0;
5814 spec->dock_mic.mux_idx = eidx;
5817 snd_printd(KERN_INFO "hda_codec: %s: "
5818 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5819 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5820 spec->auto_mic = 0; /* disable auto-mic to be sure */
5823 /* select or unmute the given capsrc route */
5824 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5827 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5828 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5831 snd_hda_codec_write_cache(codec, cap, 0,
5832 AC_VERB_SET_CONNECT_SEL, idx);
5836 /* set the default connection to that pin */
5837 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5839 struct alc_spec *spec = codec->spec;
5844 for (i = 0; i < spec->num_adc_nids; i++) {
5845 hda_nid_t cap = spec->capsrc_nids ?
5846 spec->capsrc_nids[i] : spec->adc_nids[i];
5849 idx = get_connection_index(codec, cap, pin);
5852 select_or_unmute_capsrc(codec, cap, idx);
5853 return i; /* return the found index */
5855 return -1; /* not found */
5858 /* choose the ADC/MUX containing the input pin and initialize the setup */
5859 static void fixup_single_adc(struct hda_codec *codec)
5861 struct alc_spec *spec = codec->spec;
5862 struct auto_pin_cfg *cfg = &spec->autocfg;
5865 /* search for the input pin; there must be only one */
5866 if (cfg->num_inputs != 1)
5868 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5870 /* use only this ADC */
5871 if (spec->capsrc_nids)
5872 spec->capsrc_nids += i;
5873 spec->adc_nids += i;
5874 spec->num_adc_nids = 1;
5875 spec->single_input_src = 1;
5879 /* initialize dual adcs */
5880 static void fixup_dual_adc_switch(struct hda_codec *codec)
5882 struct alc_spec *spec = codec->spec;
5883 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5884 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5885 init_capsrc_for_pin(codec, spec->int_mic.pin);
5888 /* initialize some special cases for input sources */
5889 static void alc_init_special_input_src(struct hda_codec *codec)
5891 struct alc_spec *spec = codec->spec;
5892 if (spec->dual_adc_switch)
5893 fixup_dual_adc_switch(codec);
5894 else if (spec->single_input_src)
5895 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5898 static void set_capture_mixer(struct hda_codec *codec)
5900 struct alc_spec *spec = codec->spec;
5901 static const struct snd_kcontrol_new *caps[2][3] = {
5902 { alc_capture_mixer_nosrc1,
5903 alc_capture_mixer_nosrc2,
5904 alc_capture_mixer_nosrc3 },
5905 { alc_capture_mixer1,
5907 alc_capture_mixer3 },
5909 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5911 int num_adcs = spec->num_adc_nids;
5912 if (spec->dual_adc_switch)
5914 else if (spec->auto_mic)
5915 fixup_automic_adc(codec);
5916 else if (spec->input_mux) {
5917 if (spec->input_mux->num_items > 1)
5919 else if (spec->input_mux->num_items == 1)
5920 fixup_single_adc(codec);
5922 spec->cap_mixer = caps[mux][num_adcs - 1];
5926 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5927 static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
5930 struct alc_spec *spec = codec->spec;
5931 struct auto_pin_cfg *cfg = &spec->autocfg;
5933 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5935 for (n = 0; n < num_nids; n++) {
5937 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5941 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5944 nconns = snd_hda_get_connections(codec, cap, conn,
5948 nconns = snd_hda_get_connections(codec, cap, conn,
5953 if (!fallback_adc) {
5957 for (i = 0; i < cfg->num_inputs; i++) {
5958 hda_nid_t nid = cfg->inputs[i].pin;
5959 for (j = 0; j < nconns; j++) {
5966 if (i >= cfg->num_inputs) {
5967 int num_adcs = spec->num_adc_nids;
5968 spec->private_adc_nids[num_adcs] = adc;
5969 spec->private_capsrc_nids[num_adcs] = cap;
5970 spec->num_adc_nids++;
5971 spec->adc_nids = spec->private_adc_nids;
5973 spec->capsrc_nids = spec->private_capsrc_nids;
5976 if (!spec->num_adc_nids) {
5977 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5978 " using fallback 0x%x\n",
5979 codec->chip_name, fallback_adc);
5980 spec->private_adc_nids[0] = fallback_adc;
5981 spec->adc_nids = spec->private_adc_nids;
5982 if (fallback_adc != fallback_cap) {
5983 spec->private_capsrc_nids[0] = fallback_cap;
5984 spec->capsrc_nids = spec->private_adc_nids;
5989 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5990 #define set_beep_amp(spec, nid, idx, dir) \
5991 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5993 static const struct snd_pci_quirk beep_white_list[] = {
5994 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5995 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5996 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5997 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5998 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
6002 static inline int has_cdefine_beep(struct hda_codec *codec)
6004 struct alc_spec *spec = codec->spec;
6005 const struct snd_pci_quirk *q;
6006 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
6009 return spec->cdefine.enable_pcbeep;
6012 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
6013 #define has_cdefine_beep(codec) 0
6017 * OK, here we have finally the patch for ALC880
6020 static int patch_alc880(struct hda_codec *codec)
6022 struct alc_spec *spec;
6026 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6032 spec->mixer_nid = 0x0b;
6034 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
6037 if (board_config < 0) {
6038 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6040 board_config = ALC880_AUTO;
6043 if (board_config == ALC880_AUTO) {
6044 /* automatic parse from the BIOS config */
6045 err = alc880_parse_auto_config(codec);
6051 "hda_codec: Cannot set up configuration "
6052 "from BIOS. Using 3-stack mode...\n");
6053 board_config = ALC880_3ST;
6057 err = snd_hda_attach_beep_device(codec, 0x1);
6063 if (board_config != ALC880_AUTO)
6064 setup_preset(codec, &alc880_presets[board_config]);
6066 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6067 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6068 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6070 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6071 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6073 if (!spec->adc_nids && spec->input_mux) {
6074 /* check whether NID 0x07 is valid */
6075 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
6077 wcap = get_wcaps_type(wcap);
6078 if (wcap != AC_WID_AUD_IN) {
6079 spec->adc_nids = alc880_adc_nids_alt;
6080 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
6082 spec->adc_nids = alc880_adc_nids;
6083 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
6086 set_capture_mixer(codec);
6087 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6089 spec->vmaster_nid = 0x0c;
6091 codec->patch_ops = alc_patch_ops;
6092 if (board_config == ALC880_AUTO)
6093 spec->init_hook = alc880_auto_init;
6094 #ifdef CONFIG_SND_HDA_POWER_SAVE
6095 if (!spec->loopback.amplist)
6096 spec->loopback.amplist = alc880_loopbacks;
6107 static const hda_nid_t alc260_dac_nids[1] = {
6112 static const hda_nid_t alc260_adc_nids[1] = {
6117 static const hda_nid_t alc260_adc_nids_alt[1] = {
6122 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
6123 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6125 static const hda_nid_t alc260_dual_adc_nids[2] = {
6130 #define ALC260_DIGOUT_NID 0x03
6131 #define ALC260_DIGIN_NID 0x06
6133 static const struct hda_input_mux alc260_capture_source = {
6137 { "Front Mic", 0x1 },
6143 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6144 * headphone jack and the internal CD lines since these are the only pins at
6145 * which audio can appear. For flexibility, also allow the option of
6146 * recording the mixer output on the second ADC (ADC0 doesn't have a
6147 * connection to the mixer output).
6149 static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6153 { "Mic/Line", 0x0 },
6155 { "Headphone", 0x2 },
6161 { "Mic/Line", 0x0 },
6163 { "Headphone", 0x2 },
6170 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6171 * the Fujitsu S702x, but jacks are marked differently.
6173 static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6180 { "Headphone", 0x5 },
6189 { "Headphone", 0x6 },
6195 /* Maxdata Favorit 100XS */
6196 static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6200 { "Line/Mic", 0x0 },
6207 { "Line/Mic", 0x0 },
6215 * This is just place-holder, so there's something for alc_build_pcms to look
6216 * at when it calculates the maximum number of channels. ALC260 has no mixer
6217 * element which allows changing the channel mode, so the verb list is
6220 static const struct hda_channel_mode alc260_modes[1] = {
6225 /* Mixer combinations
6227 * basic: base_output + input + pc_beep + capture
6228 * HP: base_output + input + capture_alt
6229 * HP_3013: hp_3013 + input + capture
6230 * fujitsu: fujitsu + capture
6231 * acer: acer + capture
6234 static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6235 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6236 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6237 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6238 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6239 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6240 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6244 static const struct snd_kcontrol_new alc260_input_mixer[] = {
6245 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6246 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6247 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6248 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6250 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6251 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6252 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6256 /* update HP, line and mono out pins according to the master switch */
6257 static void alc260_hp_master_update(struct hda_codec *codec)
6259 update_speakers(codec);
6262 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6263 struct snd_ctl_elem_value *ucontrol)
6265 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6266 struct alc_spec *spec = codec->spec;
6267 *ucontrol->value.integer.value = !spec->master_mute;
6271 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6272 struct snd_ctl_elem_value *ucontrol)
6274 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6275 struct alc_spec *spec = codec->spec;
6276 int val = !*ucontrol->value.integer.value;
6278 if (val == spec->master_mute)
6280 spec->master_mute = val;
6281 alc260_hp_master_update(codec);
6285 static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6288 .name = "Master Playback Switch",
6289 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6290 .info = snd_ctl_boolean_mono_info,
6291 .get = alc260_hp_master_sw_get,
6292 .put = alc260_hp_master_sw_put,
6294 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6295 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6296 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6297 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6298 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6300 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6304 static const struct hda_verb alc260_hp_unsol_verbs[] = {
6305 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6309 static void alc260_hp_setup(struct hda_codec *codec)
6311 struct alc_spec *spec = codec->spec;
6313 spec->autocfg.hp_pins[0] = 0x0f;
6314 spec->autocfg.speaker_pins[0] = 0x10;
6315 spec->autocfg.speaker_pins[1] = 0x11;
6317 spec->automute_mode = ALC_AUTOMUTE_PIN;
6320 static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6323 .name = "Master Playback Switch",
6324 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6325 .info = snd_ctl_boolean_mono_info,
6326 .get = alc260_hp_master_sw_get,
6327 .put = alc260_hp_master_sw_put,
6329 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6330 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6331 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6332 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6333 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6334 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6335 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6336 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6340 static void alc260_hp_3013_setup(struct hda_codec *codec)
6342 struct alc_spec *spec = codec->spec;
6344 spec->autocfg.hp_pins[0] = 0x15;
6345 spec->autocfg.speaker_pins[0] = 0x10;
6346 spec->autocfg.speaker_pins[1] = 0x11;
6348 spec->automute_mode = ALC_AUTOMUTE_PIN;
6351 static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6352 .ops = &snd_hda_bind_vol,
6354 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6355 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6356 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6361 static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6362 .ops = &snd_hda_bind_sw,
6364 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6365 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6370 static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6371 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6372 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6373 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6374 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6378 static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6379 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6383 static void alc260_hp_3012_setup(struct hda_codec *codec)
6385 struct alc_spec *spec = codec->spec;
6387 spec->autocfg.hp_pins[0] = 0x10;
6388 spec->autocfg.speaker_pins[0] = 0x0f;
6389 spec->autocfg.speaker_pins[1] = 0x11;
6390 spec->autocfg.speaker_pins[2] = 0x15;
6392 spec->automute_mode = ALC_AUTOMUTE_PIN;
6395 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6396 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6398 static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6399 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6400 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6401 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6402 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6403 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6404 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6405 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6406 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6407 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6408 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6412 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6413 * versions of the ALC260 don't act on requests to enable mic bias from NID
6414 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6415 * datasheet doesn't mention this restriction. At this stage it's not clear
6416 * whether this behaviour is intentional or is a hardware bug in chip
6417 * revisions available in early 2006. Therefore for now allow the
6418 * "Headphone Jack Mode" control to span all choices, but if it turns out
6419 * that the lack of mic bias for this NID is intentional we could change the
6420 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6422 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6423 * don't appear to make the mic bias available from the "line" jack, even
6424 * though the NID used for this jack (0x14) can supply it. The theory is
6425 * that perhaps Acer have included blocking capacitors between the ALC260
6426 * and the output jack. If this turns out to be the case for all such
6427 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6428 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6430 * The C20x Tablet series have a mono internal speaker which is controlled
6431 * via the chip's Mono sum widget and pin complex, so include the necessary
6432 * controls for such models. On models without a "mono speaker" the control
6433 * won't do anything.
6435 static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6436 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6437 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6438 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6439 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6441 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6443 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6444 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6446 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6447 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6448 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6449 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6450 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6454 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
6456 static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6457 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6458 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6459 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6460 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6461 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6462 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6466 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6467 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6469 static const struct snd_kcontrol_new alc260_will_mixer[] = {
6470 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6471 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6473 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6474 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6475 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6476 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6477 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6478 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6479 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6483 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6484 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6486 static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6487 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6488 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6489 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6490 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6491 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6492 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6493 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6494 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6495 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6496 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6501 * initialization verbs
6503 static const struct hda_verb alc260_init_verbs[] = {
6504 /* Line In pin widget for input */
6505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6506 /* CD pin widget for input */
6507 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6508 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6509 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6510 /* Mic2 (front panel) pin widget for input and vref at 80% */
6511 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6512 /* LINE-2 is used for line-out in rear */
6513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6514 /* select line-out */
6515 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6517 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6519 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6521 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6522 /* mute capture amp left and right */
6523 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6524 /* set connection select to line in (default select for this ADC) */
6525 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6526 /* mute capture amp left and right */
6527 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6528 /* set connection select to line in (default select for this ADC) */
6529 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6530 /* set vol=0 Line-Out mixer amp left and right */
6531 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6532 /* unmute pin widget amp left and right (no gain on this amp) */
6533 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6534 /* set vol=0 HP mixer amp left and right */
6535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6536 /* unmute pin widget amp left and right (no gain on this amp) */
6537 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6538 /* set vol=0 Mono mixer amp left and right */
6539 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6540 /* unmute pin widget amp left and right (no gain on this amp) */
6541 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6542 /* unmute LINE-2 out pin */
6543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6544 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6547 /* mute analog inputs */
6548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6553 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6554 /* mute Front out path */
6555 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6557 /* mute Headphone out path */
6558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6560 /* mute Mono out path */
6561 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6566 #if 0 /* should be identical with alc260_init_verbs? */
6567 static const struct hda_verb alc260_hp_init_verbs[] = {
6568 /* Headphone and output */
6569 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6571 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6572 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6573 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6574 /* Mic2 (front panel) pin widget for input and vref at 80% */
6575 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6576 /* Line In pin widget for input */
6577 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6578 /* Line-2 pin widget for output */
6579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6580 /* CD pin widget for input */
6581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6582 /* unmute amp left and right */
6583 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6584 /* set connection select to line in (default select for this ADC) */
6585 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6586 /* unmute Line-Out mixer amp left and right (volume = 0) */
6587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6588 /* mute pin widget amp left and right (no gain on this amp) */
6589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6590 /* unmute HP mixer amp left and right (volume = 0) */
6591 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6592 /* mute pin widget amp left and right (no gain on this amp) */
6593 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6594 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6597 /* mute analog inputs */
6598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6603 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6604 /* Unmute Front out path */
6605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6607 /* Unmute Headphone out path */
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6610 /* Unmute Mono out path */
6611 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6617 static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6618 /* Line out and output */
6619 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6621 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6622 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6623 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6624 /* Mic2 (front panel) pin widget for input and vref at 80% */
6625 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6626 /* Line In pin widget for input */
6627 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6628 /* Headphone pin widget for output */
6629 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6630 /* CD pin widget for input */
6631 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6632 /* unmute amp left and right */
6633 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6634 /* set connection select to line in (default select for this ADC) */
6635 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6636 /* unmute Line-Out mixer amp left and right (volume = 0) */
6637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6638 /* mute pin widget amp left and right (no gain on this amp) */
6639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6640 /* unmute HP mixer amp left and right (volume = 0) */
6641 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6642 /* mute pin widget amp left and right (no gain on this amp) */
6643 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6644 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6647 /* mute analog inputs */
6648 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6649 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6650 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6651 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6652 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6653 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6654 /* Unmute Front out path */
6655 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6657 /* Unmute Headphone out path */
6658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6660 /* Unmute Mono out path */
6661 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6662 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6666 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6667 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6668 * audio = 0x16, internal speaker = 0x10.
6670 static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6671 /* Disable all GPIOs */
6672 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6673 /* Internal speaker is connected to headphone pin */
6674 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6675 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6677 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6678 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6679 /* Ensure all other unused pins are disabled and muted. */
6680 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6681 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6682 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6683 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6684 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6685 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6686 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6689 /* Disable digital (SPDIF) pins */
6690 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6691 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6693 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6694 * when acting as an output.
6696 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6698 /* Start with output sum widgets muted and their output gains at min */
6699 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6700 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6701 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6703 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6704 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6705 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6706 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6707 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6709 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6710 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6711 /* Unmute Line1 pin widget output buffer since it starts as an output.
6712 * If the pin mode is changed by the user the pin mode control will
6713 * take care of enabling the pin's input/output buffers as needed.
6714 * Therefore there's no need to enable the input buffer at this
6717 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6718 /* Unmute input buffer of pin widget used for Line-in (no equiv
6721 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6723 /* Mute capture amp left and right */
6724 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6725 /* Set ADC connection select to match default mixer setting - line
6728 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6730 /* Do the same for the second ADC: mute capture input amp and
6731 * set ADC connection to line in (on mic1 pin)
6733 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6734 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6736 /* Mute all inputs to mixer widget (even unconnected ones) */
6737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6740 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6741 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6749 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6750 * similar laptops (adapted from Fujitsu init verbs).
6752 static const struct hda_verb alc260_acer_init_verbs[] = {
6753 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6754 * the headphone jack. Turn this on and rely on the standard mute
6755 * methods whenever the user wants to turn these outputs off.
6757 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6758 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6759 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6760 /* Internal speaker/Headphone jack is connected to Line-out pin */
6761 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6762 /* Internal microphone/Mic jack is connected to Mic1 pin */
6763 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6764 /* Line In jack is connected to Line1 pin */
6765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6766 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6767 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6768 /* Ensure all other unused pins are disabled and muted. */
6769 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6770 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6771 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6772 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6775 /* Disable digital (SPDIF) pins */
6776 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6777 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6779 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6780 * bus when acting as outputs.
6782 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6783 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6785 /* Start with output sum widgets muted and their output gains at min */
6786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6789 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6792 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6793 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6794 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6796 /* Unmute Line-out pin widget amp left and right
6797 * (no equiv mixer ctrl)
6799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6800 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6801 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6802 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6803 * inputs. If the pin mode is changed by the user the pin mode control
6804 * will take care of enabling the pin's input/output buffers as needed.
6805 * Therefore there's no need to enable the input buffer at this
6808 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6809 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6811 /* Mute capture amp left and right */
6812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6813 /* Set ADC connection select to match default mixer setting - mic
6816 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6818 /* Do similar with the second ADC: mute capture input amp and
6819 * set ADC connection to mic to match ALSA's default state.
6821 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6822 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6824 /* Mute all inputs to mixer widget (even unconnected ones) */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6837 /* Initialisation sequence for Maxdata Favorit 100XS
6838 * (adapted from Acer init verbs).
6840 static const struct hda_verb alc260_favorit100_init_verbs[] = {
6841 /* GPIO 0 enables the output jack.
6842 * Turn this on and rely on the standard mute
6843 * methods whenever the user wants to turn these outputs off.
6845 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6846 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6847 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6848 /* Line/Mic input jack is connected to Mic1 pin */
6849 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6850 /* Ensure all other unused pins are disabled and muted. */
6851 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6852 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6853 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6854 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6856 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6857 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6858 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6861 /* Disable digital (SPDIF) pins */
6862 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6863 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6865 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6866 * bus when acting as outputs.
6868 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6869 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6871 /* Start with output sum widgets muted and their output gains at min */
6872 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6873 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6874 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6875 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6876 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6877 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6878 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6879 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6880 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6882 /* Unmute Line-out pin widget amp left and right
6883 * (no equiv mixer ctrl)
6885 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6886 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6887 * inputs. If the pin mode is changed by the user the pin mode control
6888 * will take care of enabling the pin's input/output buffers as needed.
6889 * Therefore there's no need to enable the input buffer at this
6892 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6894 /* Mute capture amp left and right */
6895 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6896 /* Set ADC connection select to match default mixer setting - mic
6899 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6901 /* Do similar with the second ADC: mute capture input amp and
6902 * set ADC connection to mic to match ALSA's default state.
6904 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6905 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6907 /* Mute all inputs to mixer widget (even unconnected ones) */
6908 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6914 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6920 static const struct hda_verb alc260_will_verbs[] = {
6921 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6922 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6923 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6924 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6925 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6926 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6930 static const struct hda_verb alc260_replacer_672v_verbs[] = {
6931 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6932 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6933 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6935 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6936 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6937 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6939 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6943 /* toggle speaker-output according to the hp-jack state */
6944 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6946 unsigned int present;
6948 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6949 present = snd_hda_jack_detect(codec, 0x0f);
6951 snd_hda_codec_write_cache(codec, 0x01, 0,
6952 AC_VERB_SET_GPIO_DATA, 1);
6953 snd_hda_codec_write_cache(codec, 0x0f, 0,
6954 AC_VERB_SET_PIN_WIDGET_CONTROL,
6957 snd_hda_codec_write_cache(codec, 0x01, 0,
6958 AC_VERB_SET_GPIO_DATA, 0);
6959 snd_hda_codec_write_cache(codec, 0x0f, 0,
6960 AC_VERB_SET_PIN_WIDGET_CONTROL,
6965 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6968 if ((res >> 26) == ALC880_HP_EVENT)
6969 alc260_replacer_672v_automute(codec);
6972 static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6973 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6974 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6975 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6976 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6977 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6979 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6980 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6981 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6982 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6986 /* Test configuration for debugging, modelled after the ALC880 test
6989 #ifdef CONFIG_SND_DEBUG
6990 static const hda_nid_t alc260_test_dac_nids[1] = {
6993 static const hda_nid_t alc260_test_adc_nids[2] = {
6996 /* For testing the ALC260, each input MUX needs its own definition since
6997 * the signal assignments are different. This assumes that the first ADC
7000 static const struct hda_input_mux alc260_test_capture_sources[2] = {
7004 { "MIC1 pin", 0x0 },
7005 { "MIC2 pin", 0x1 },
7006 { "LINE1 pin", 0x2 },
7007 { "LINE2 pin", 0x3 },
7009 { "LINE-OUT pin", 0x5 },
7010 { "HP-OUT pin", 0x6 },
7016 { "MIC1 pin", 0x0 },
7017 { "MIC2 pin", 0x1 },
7018 { "LINE1 pin", 0x2 },
7019 { "LINE2 pin", 0x3 },
7022 { "LINE-OUT pin", 0x6 },
7023 { "HP-OUT pin", 0x7 },
7027 static const struct snd_kcontrol_new alc260_test_mixer[] = {
7028 /* Output driver widgets */
7029 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
7030 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
7031 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
7032 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
7033 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
7034 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
7036 /* Modes for retasking pin widgets
7037 * Note: the ALC260 doesn't seem to act on requests to enable mic
7038 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
7039 * mention this restriction. At this stage it's not clear whether
7040 * this behaviour is intentional or is a hardware bug in chip
7041 * revisions available at least up until early 2006. Therefore for
7042 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
7043 * choices, but if it turns out that the lack of mic bias for these
7044 * NIDs is intentional we could change their modes from
7045 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
7047 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
7048 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7049 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7050 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7051 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7052 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7054 /* Loopback mixer controls */
7055 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7056 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7057 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7058 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7059 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7060 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7061 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7062 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7063 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7064 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7065 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7066 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7067 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7068 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
7070 /* Controls for GPIO pins, assuming they are configured as outputs */
7071 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7072 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7073 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7074 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7076 /* Switches to allow the digital IO pins to be enabled. The datasheet
7077 * is ambigious as to which NID is which; testing on laptops which
7078 * make this output available should provide clarification.
7080 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7081 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7083 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7084 * this output to turn on an external amplifier.
7086 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7087 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7091 static const struct hda_verb alc260_test_init_verbs[] = {
7092 /* Enable all GPIOs as outputs with an initial value of 0 */
7093 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7094 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7095 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7097 /* Enable retasking pins as output, initially without power amp */
7098 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7099 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7101 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7102 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7103 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7105 /* Disable digital (SPDIF) pins initially, but users can enable
7106 * them via a mixer switch. In the case of SPDIF-out, this initverb
7107 * payload also sets the generation to 0, output to be in "consumer"
7108 * PCM format, copyright asserted, no pre-emphasis and no validity
7111 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7112 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7114 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7115 * OUT1 sum bus when acting as an output.
7117 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7118 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7119 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7120 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7122 /* Start with output sum widgets muted and their output gains at min */
7123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7125 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7128 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7129 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7130 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7131 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7133 /* Unmute retasking pin widget output buffers since the default
7134 * state appears to be output. As the pin mode is changed by the
7135 * user the pin mode control will take care of enabling the pin's
7136 * input/output buffers as needed.
7138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7139 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7140 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7142 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7143 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7144 /* Also unmute the mono-out pin widget */
7145 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7147 /* Mute capture amp left and right */
7148 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7149 /* Set ADC connection select to match default mixer setting (mic1
7152 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7154 /* Do the same for the second ADC: mute capture input amp and
7155 * set ADC connection to mic1 pin
7157 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7158 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7160 /* Mute all inputs to mixer widget (even unconnected ones) */
7161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7162 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7163 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7174 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7175 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
7177 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
7178 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
7181 * for BIOS auto-configuration
7184 /* convert from pin to volume-mixer widget */
7185 static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7187 if (nid >= 0x0f && nid <= 0x11)
7189 else if (nid >= 0x12 && nid <= 0x15)
7195 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
7196 const char *pfx, int *vol_bits)
7199 unsigned long vol_val, sw_val;
7202 nid_vol = alc260_pin_to_vol_mix(nid);
7209 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, chs, 0, HDA_OUTPUT);
7210 sw_val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
7212 if (!(*vol_bits & (1 << nid_vol))) {
7213 /* first control for the volume widget */
7214 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7217 *vol_bits |= (1 << nid_vol);
7219 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7225 /* add playback controls from the parsed DAC table */
7226 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7227 const struct auto_pin_cfg *cfg)
7233 spec->multiout.num_dacs = 1;
7234 spec->multiout.dac_nids = spec->private_dac_nids;
7235 spec->private_dac_nids[0] = 0x02;
7237 nid = cfg->line_out_pins[0];
7241 pfx = alc_get_line_out_pfx(spec, 0, true, &index);
7242 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7247 nid = cfg->speaker_pins[0];
7249 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
7254 nid = cfg->hp_pins[0];
7256 err = alc260_add_playback_controls(spec, nid, "Headphone",
7264 /* create playback/capture controls for input pins */
7265 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
7266 const struct auto_pin_cfg *cfg)
7268 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
7271 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7272 hda_nid_t nid, int pin_type,
7277 alc_set_pin_output(codec, nid, pin_type);
7278 /* need the manual connection? */
7280 int idx = nid - 0x12;
7281 snd_hda_codec_write(codec, idx + 0x0b, 0,
7282 AC_VERB_SET_CONNECT_SEL, sel_idx);
7285 mix = alc260_pin_to_vol_mix(nid);
7288 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7290 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7292 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7296 static void alc260_auto_init_multi_out(struct hda_codec *codec)
7298 struct alc_spec *spec = codec->spec;
7301 nid = spec->autocfg.line_out_pins[0];
7303 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7304 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7307 nid = spec->autocfg.speaker_pins[0];
7309 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7311 nid = spec->autocfg.hp_pins[0];
7313 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7316 #define alc260_auto_init_analog_input alc880_auto_init_analog_input
7317 #define alc260_auto_init_input_src alc880_auto_init_input_src
7319 static int alc260_parse_auto_config(struct hda_codec *codec)
7321 struct alc_spec *spec = codec->spec;
7323 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7325 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7329 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7332 if (!spec->kctls.list)
7333 return 0; /* can't find valid BIOS pin config */
7334 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7338 spec->multiout.max_channels = 2;
7340 if (spec->autocfg.dig_outs)
7341 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7342 if (spec->kctls.list)
7343 add_mixer(spec, spec->kctls.list);
7345 spec->num_mux_defs = 1;
7346 spec->input_mux = &spec->private_imux[0];
7348 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7353 /* additional initialization for auto-configuration model */
7354 static void alc260_auto_init(struct hda_codec *codec)
7356 struct alc_spec *spec = codec->spec;
7357 alc260_auto_init_multi_out(codec);
7358 alc260_auto_init_analog_input(codec);
7359 alc260_auto_init_input_src(codec);
7360 alc_auto_init_digital(codec);
7361 if (spec->unsol_event)
7362 alc_inithook(codec);
7365 #ifdef CONFIG_SND_HDA_POWER_SAVE
7366 static const struct hda_amp_list alc260_loopbacks[] = {
7367 { 0x07, HDA_INPUT, 0 },
7368 { 0x07, HDA_INPUT, 1 },
7369 { 0x07, HDA_INPUT, 2 },
7370 { 0x07, HDA_INPUT, 3 },
7371 { 0x07, HDA_INPUT, 4 },
7383 static const struct alc_fixup alc260_fixups[] = {
7384 [PINFIX_HP_DC5750] = {
7385 .type = ALC_FIXUP_PINS,
7386 .v.pins = (const struct alc_pincfg[]) {
7387 { 0x11, 0x90130110 }, /* speaker */
7393 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7394 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7399 * ALC260 configurations
7401 static const char * const alc260_models[ALC260_MODEL_LAST] = {
7402 [ALC260_BASIC] = "basic",
7404 [ALC260_HP_3013] = "hp-3013",
7405 [ALC260_HP_DC7600] = "hp-dc7600",
7406 [ALC260_FUJITSU_S702X] = "fujitsu",
7407 [ALC260_ACER] = "acer",
7408 [ALC260_WILL] = "will",
7409 [ALC260_REPLACER_672V] = "replacer",
7410 [ALC260_FAVORIT100] = "favorit100",
7411 #ifdef CONFIG_SND_DEBUG
7412 [ALC260_TEST] = "test",
7414 [ALC260_AUTO] = "auto",
7417 static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7418 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7419 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7420 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7421 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7422 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7423 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7424 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7425 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7426 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7427 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7428 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7429 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7430 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7431 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7432 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7433 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7434 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7435 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7436 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7437 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7441 static const struct alc_config_preset alc260_presets[] = {
7443 .mixers = { alc260_base_output_mixer,
7444 alc260_input_mixer },
7445 .init_verbs = { alc260_init_verbs },
7446 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7447 .dac_nids = alc260_dac_nids,
7448 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7449 .adc_nids = alc260_dual_adc_nids,
7450 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7451 .channel_mode = alc260_modes,
7452 .input_mux = &alc260_capture_source,
7455 .mixers = { alc260_hp_output_mixer,
7456 alc260_input_mixer },
7457 .init_verbs = { alc260_init_verbs,
7458 alc260_hp_unsol_verbs },
7459 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7460 .dac_nids = alc260_dac_nids,
7461 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7462 .adc_nids = alc260_adc_nids_alt,
7463 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7464 .channel_mode = alc260_modes,
7465 .input_mux = &alc260_capture_source,
7466 .unsol_event = alc_sku_unsol_event,
7467 .setup = alc260_hp_setup,
7468 .init_hook = alc_inithook,
7470 [ALC260_HP_DC7600] = {
7471 .mixers = { alc260_hp_dc7600_mixer,
7472 alc260_input_mixer },
7473 .init_verbs = { alc260_init_verbs,
7474 alc260_hp_dc7600_verbs },
7475 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7476 .dac_nids = alc260_dac_nids,
7477 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7478 .adc_nids = alc260_adc_nids_alt,
7479 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7480 .channel_mode = alc260_modes,
7481 .input_mux = &alc260_capture_source,
7482 .unsol_event = alc_sku_unsol_event,
7483 .setup = alc260_hp_3012_setup,
7484 .init_hook = alc_inithook,
7486 [ALC260_HP_3013] = {
7487 .mixers = { alc260_hp_3013_mixer,
7488 alc260_input_mixer },
7489 .init_verbs = { alc260_hp_3013_init_verbs,
7490 alc260_hp_3013_unsol_verbs },
7491 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7492 .dac_nids = alc260_dac_nids,
7493 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7494 .adc_nids = alc260_adc_nids_alt,
7495 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7496 .channel_mode = alc260_modes,
7497 .input_mux = &alc260_capture_source,
7498 .unsol_event = alc_sku_unsol_event,
7499 .setup = alc260_hp_3013_setup,
7500 .init_hook = alc_inithook,
7502 [ALC260_FUJITSU_S702X] = {
7503 .mixers = { alc260_fujitsu_mixer },
7504 .init_verbs = { alc260_fujitsu_init_verbs },
7505 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7506 .dac_nids = alc260_dac_nids,
7507 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7508 .adc_nids = alc260_dual_adc_nids,
7509 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7510 .channel_mode = alc260_modes,
7511 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7512 .input_mux = alc260_fujitsu_capture_sources,
7515 .mixers = { alc260_acer_mixer },
7516 .init_verbs = { alc260_acer_init_verbs },
7517 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7518 .dac_nids = alc260_dac_nids,
7519 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7520 .adc_nids = alc260_dual_adc_nids,
7521 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7522 .channel_mode = alc260_modes,
7523 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7524 .input_mux = alc260_acer_capture_sources,
7526 [ALC260_FAVORIT100] = {
7527 .mixers = { alc260_favorit100_mixer },
7528 .init_verbs = { alc260_favorit100_init_verbs },
7529 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7530 .dac_nids = alc260_dac_nids,
7531 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7532 .adc_nids = alc260_dual_adc_nids,
7533 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7534 .channel_mode = alc260_modes,
7535 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7536 .input_mux = alc260_favorit100_capture_sources,
7539 .mixers = { alc260_will_mixer },
7540 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7541 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7542 .dac_nids = alc260_dac_nids,
7543 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7544 .adc_nids = alc260_adc_nids,
7545 .dig_out_nid = ALC260_DIGOUT_NID,
7546 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7547 .channel_mode = alc260_modes,
7548 .input_mux = &alc260_capture_source,
7550 [ALC260_REPLACER_672V] = {
7551 .mixers = { alc260_replacer_672v_mixer },
7552 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7553 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7554 .dac_nids = alc260_dac_nids,
7555 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7556 .adc_nids = alc260_adc_nids,
7557 .dig_out_nid = ALC260_DIGOUT_NID,
7558 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7559 .channel_mode = alc260_modes,
7560 .input_mux = &alc260_capture_source,
7561 .unsol_event = alc260_replacer_672v_unsol_event,
7562 .init_hook = alc260_replacer_672v_automute,
7564 #ifdef CONFIG_SND_DEBUG
7566 .mixers = { alc260_test_mixer },
7567 .init_verbs = { alc260_test_init_verbs },
7568 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7569 .dac_nids = alc260_test_dac_nids,
7570 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7571 .adc_nids = alc260_test_adc_nids,
7572 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7573 .channel_mode = alc260_modes,
7574 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7575 .input_mux = alc260_test_capture_sources,
7580 static int patch_alc260(struct hda_codec *codec)
7582 struct alc_spec *spec;
7583 int err, board_config;
7585 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7591 spec->mixer_nid = 0x07;
7593 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7596 if (board_config < 0) {
7597 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7599 board_config = ALC260_AUTO;
7602 if (board_config == ALC260_AUTO) {
7603 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7604 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7607 if (board_config == ALC260_AUTO) {
7608 /* automatic parse from the BIOS config */
7609 err = alc260_parse_auto_config(codec);
7615 "hda_codec: Cannot set up configuration "
7616 "from BIOS. Using base mode...\n");
7617 board_config = ALC260_BASIC;
7621 err = snd_hda_attach_beep_device(codec, 0x1);
7627 if (board_config != ALC260_AUTO)
7628 setup_preset(codec, &alc260_presets[board_config]);
7630 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7631 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7632 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7634 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7635 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7637 if (!spec->adc_nids && spec->input_mux) {
7638 /* check whether NID 0x04 is valid */
7639 unsigned int wcap = get_wcaps(codec, 0x04);
7640 wcap = get_wcaps_type(wcap);
7642 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7643 spec->adc_nids = alc260_adc_nids_alt;
7644 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7646 spec->adc_nids = alc260_adc_nids;
7647 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7650 set_capture_mixer(codec);
7651 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7653 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7655 spec->vmaster_nid = 0x08;
7657 codec->patch_ops = alc_patch_ops;
7658 if (board_config == ALC260_AUTO)
7659 spec->init_hook = alc260_auto_init;
7660 spec->shutup = alc_eapd_shutup;
7661 #ifdef CONFIG_SND_HDA_POWER_SAVE
7662 if (!spec->loopback.amplist)
7663 spec->loopback.amplist = alc260_loopbacks;
7671 * ALC882/883/885/888/889 support
7673 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7674 * configuration. Each pin widget can choose any input DACs and a mixer.
7675 * Each ADC is connected from a mixer of all inputs. This makes possible
7676 * 6-channel independent captures.
7678 * In addition, an independent DAC for the multi-playback (not used in this
7681 #define ALC882_DIGOUT_NID 0x06
7682 #define ALC882_DIGIN_NID 0x0a
7683 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7684 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7685 #define ALC1200_DIGOUT_NID 0x10
7688 static const struct hda_channel_mode alc882_ch_modes[1] = {
7693 static const hda_nid_t alc882_dac_nids[4] = {
7694 /* front, rear, clfe, rear_surr */
7695 0x02, 0x03, 0x04, 0x05
7697 #define alc883_dac_nids alc882_dac_nids
7700 #define alc882_adc_nids alc880_adc_nids
7701 #define alc882_adc_nids_alt alc880_adc_nids_alt
7702 #define alc883_adc_nids alc882_adc_nids_alt
7703 static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7704 static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7705 #define alc889_adc_nids alc880_adc_nids
7707 static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7708 static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7709 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7710 static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7711 #define alc889_capsrc_nids alc882_capsrc_nids
7714 /* FIXME: should be a matrix-type input source selection */
7716 static const struct hda_input_mux alc882_capture_source = {
7720 { "Front Mic", 0x1 },
7726 #define alc883_capture_source alc882_capture_source
7728 static const struct hda_input_mux alc889_capture_source = {
7731 { "Front Mic", 0x0 },
7737 static const struct hda_input_mux mb5_capture_source = {
7746 static const struct hda_input_mux macmini3_capture_source = {
7754 static const struct hda_input_mux alc883_3stack_6ch_intel = {
7758 { "Front Mic", 0x0 },
7764 static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7772 static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7776 { "Internal Mic", 0x1 },
7782 static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7786 { "Internal Mic", 0x1 },
7790 static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7794 { "Front Mic", 0x1 },
7799 static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7807 static const struct hda_input_mux alc889A_mb31_capture_source = {
7811 /* Front Mic (0x01) unused */
7813 /* Line 2 (0x03) unused */
7814 /* CD (0x04) unused? */
7818 static const struct hda_input_mux alc889A_imac91_capture_source = {
7822 { "Line", 0x2 }, /* Not sure! */
7829 static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7836 static const struct hda_verb alc882_3ST_ch2_init[] = {
7837 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7838 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7847 static const struct hda_verb alc882_3ST_ch4_init[] = {
7848 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7849 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7850 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7851 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7852 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7859 static const struct hda_verb alc882_3ST_ch6_init[] = {
7860 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7861 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7862 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7869 static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7870 { 2, alc882_3ST_ch2_init },
7871 { 4, alc882_3ST_ch4_init },
7872 { 6, alc882_3ST_ch6_init },
7875 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7880 static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7881 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7882 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7883 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7884 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7885 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7892 static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7893 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7895 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7896 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7897 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7898 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7905 static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7909 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7911 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7912 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7916 static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7917 { 2, alc883_3ST_ch2_clevo_init },
7918 { 4, alc883_3ST_ch4_clevo_init },
7919 { 6, alc883_3ST_ch6_clevo_init },
7926 static const struct hda_verb alc882_sixstack_ch6_init[] = {
7927 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7928 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7937 static const struct hda_verb alc882_sixstack_ch8_init[] = {
7938 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7945 static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7946 { 6, alc882_sixstack_ch6_init },
7947 { 8, alc882_sixstack_ch8_init },
7951 /* Macbook Air 2,1 */
7953 static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7958 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7964 static const struct hda_verb alc885_mbp_ch2_init[] = {
7965 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7967 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7974 static const struct hda_verb alc885_mbp_ch4_init[] = {
7975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7977 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7978 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7979 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7983 static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7984 { 2, alc885_mbp_ch2_init },
7985 { 4, alc885_mbp_ch4_init },
7990 * Speakers/Woofer/HP = Front
7993 static const struct hda_verb alc885_mb5_ch2_init[] = {
7994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7995 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8001 * Speakers/HP = Front
8005 static const struct hda_verb alc885_mb5_ch6_init[] = {
8006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8012 static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
8013 { 2, alc885_mb5_ch2_init },
8014 { 6, alc885_mb5_ch6_init },
8017 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
8022 static const struct hda_verb alc883_4ST_ch2_init[] = {
8023 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8024 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8025 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8026 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8027 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8028 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8035 static const struct hda_verb alc883_4ST_ch4_init[] = {
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8038 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8039 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8040 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8041 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8042 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8049 static const struct hda_verb alc883_4ST_ch6_init[] = {
8050 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8051 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8052 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8053 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8054 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8055 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8056 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8057 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8064 static const struct hda_verb alc883_4ST_ch8_init[] = {
8065 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8066 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8067 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8068 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8069 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8070 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8071 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8072 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8073 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8077 static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8078 { 2, alc883_4ST_ch2_init },
8079 { 4, alc883_4ST_ch4_init },
8080 { 6, alc883_4ST_ch6_init },
8081 { 8, alc883_4ST_ch8_init },
8088 static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
8089 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8090 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8091 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8092 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8099 static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
8100 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8101 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8102 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8103 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8104 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8111 static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
8112 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8113 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8114 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8117 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8121 static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8122 { 2, alc883_3ST_ch2_intel_init },
8123 { 4, alc883_3ST_ch4_intel_init },
8124 { 6, alc883_3ST_ch6_intel_init },
8130 static const struct hda_verb alc889_ch2_intel_init[] = {
8131 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8132 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8133 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8135 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8136 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8143 static const struct hda_verb alc889_ch6_intel_init[] = {
8144 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8145 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8146 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8147 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8156 static const struct hda_verb alc889_ch8_intel_init[] = {
8157 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8158 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8159 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8160 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8161 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8167 static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8168 { 2, alc889_ch2_intel_init },
8169 { 6, alc889_ch6_intel_init },
8170 { 8, alc889_ch8_intel_init },
8176 static const struct hda_verb alc883_sixstack_ch6_init[] = {
8177 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8178 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8179 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8187 static const struct hda_verb alc883_sixstack_ch8_init[] = {
8188 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8189 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8190 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8195 static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8196 { 6, alc883_sixstack_ch6_init },
8197 { 8, alc883_sixstack_ch8_init },
8201 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8202 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8204 static const struct snd_kcontrol_new alc882_base_mixer[] = {
8205 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8207 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8208 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8209 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8210 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8211 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8212 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8213 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8214 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8223 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8224 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8225 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8229 /* Macbook Air 2,1 same control for HP and internal Speaker */
8231 static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8232 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8233 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8238 static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8240 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8241 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8242 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8243 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8245 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8247 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8248 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8253 static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8254 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8255 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8256 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8257 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8258 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8259 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8260 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8261 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8262 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8263 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8264 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8265 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8266 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8267 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8271 static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8272 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8273 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8274 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8275 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8276 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8277 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8279 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8280 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8281 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8282 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8286 static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8287 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8288 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8293 static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8294 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8295 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8298 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8299 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8306 static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8312 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8317 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8318 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8319 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8323 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8324 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8326 static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8328 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8336 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8339 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8343 static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8345 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8352 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8357 static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8360 .name = "Channel Mode",
8361 .info = alc_ch_mode_info,
8362 .get = alc_ch_mode_get,
8363 .put = alc_ch_mode_put,
8368 static const struct hda_verb alc882_base_init_verbs[] = {
8369 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8382 /* Front Pin: output 0 (0x0c) */
8383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8386 /* Rear Pin: output 1 (0x0d) */
8387 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8390 /* CLFE Pin: output 2 (0x0e) */
8391 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8392 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8394 /* Side Pin: output 3 (0x0f) */
8395 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8396 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8397 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8398 /* Mic (rear) pin: input vref at 80% */
8399 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8401 /* Front Mic pin: input vref at 80% */
8402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8403 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8404 /* Line In pin: input */
8405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8406 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8407 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8411 /* CD pin widget for input */
8412 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8414 /* FIXME: use matrix-type input source selection */
8415 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8420 /* ADC2: mute amp left and right */
8421 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8422 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8423 /* ADC3: mute amp left and right */
8424 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8425 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8430 static const struct hda_verb alc882_adc1_init_verbs[] = {
8431 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8436 /* ADC1: mute amp left and right */
8437 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8442 static const struct hda_verb alc882_eapd_verbs[] = {
8443 /* change to EAPD mode */
8444 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8445 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8449 static const struct hda_verb alc889_eapd_verbs[] = {
8450 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8455 static const struct hda_verb alc_hp15_unsol_verbs[] = {
8456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8461 static const struct hda_verb alc885_init_verbs[] = {
8462 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8467 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8475 /* Front HP Pin: output 0 (0x0c) */
8476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8477 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8478 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 /* Front Pin: output 0 (0x0c) */
8480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 /* Rear Pin: output 1 (0x0d) */
8484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8485 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8486 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8487 /* CLFE Pin: output 2 (0x0e) */
8488 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8489 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8491 /* Side Pin: output 3 (0x0f) */
8492 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8493 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8494 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8495 /* Mic (rear) pin: input vref at 80% */
8496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8498 /* Front Mic pin: input vref at 80% */
8499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8501 /* Line In pin: input */
8502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8505 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8509 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8512 /* ADC2: mute amp left and right */
8513 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 /* ADC3: mute amp left and right */
8515 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8520 static const struct hda_verb alc885_init_input_verbs[] = {
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8528 /* Unmute Selector 24h and set the default input to front mic */
8529 static const struct hda_verb alc889_init_input_verbs[] = {
8530 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8536 #define alc883_init_verbs alc882_base_init_verbs
8539 static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8541 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8543 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8544 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8545 /* FIXME: this looks suspicious...
8546 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8547 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8552 static const struct hda_verb alc882_macpro_init_verbs[] = {
8553 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8557 /* Front Pin: output 0 (0x0c) */
8558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 /* Front Mic pin: input vref at 80% */
8562 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8563 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8564 /* Speaker: output */
8565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8568 /* Headphone output (output 0 - 0x0c) */
8569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8571 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8573 /* FIXME: use matrix-type input source selection */
8574 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8575 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8579 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8584 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8590 /* ADC1: mute amp left and right */
8591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8592 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8593 /* ADC2: mute amp left and right */
8594 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8595 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8596 /* ADC3: mute amp left and right */
8597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8598 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8604 static const struct hda_verb alc885_mb5_init_verbs[] = {
8606 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8609 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8614 /* Surround mixer */
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8623 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8625 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8626 /* Front Pin (0x0c) */
8627 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8628 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8629 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8630 /* LFE Pin (0x0e) */
8631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8632 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8638 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8639 /* Front Mic pin: input vref at 80% */
8640 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8641 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8653 static const struct hda_verb alc885_macmini3_init_verbs[] = {
8655 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8663 /* Surround mixer */
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8666 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8670 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8673 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8674 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8675 /* Front Pin (0x0c) */
8676 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8677 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8678 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8679 /* LFE Pin (0x0e) */
8680 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8682 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8687 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8700 static const struct hda_verb alc885_mba21_init_verbs[] = {
8701 /*Internal and HP Speaker Mixer*/
8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8705 /*Internal Speaker Pin (0x0c)*/
8706 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8707 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8708 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8709 /* HP Pin: output 0 (0x0e) */
8710 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8712 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8713 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8714 /* Line in (is hp when jack connected)*/
8715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8716 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8722 /* Macbook Pro rev3 */
8723 static const struct hda_verb alc885_mbp3_init_verbs[] = {
8724 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8736 /* Front Pin: output 0 (0x0c) */
8737 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8738 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8739 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8740 /* HP Pin: output 0 (0x0e) */
8741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8744 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8745 /* Mic (rear) pin: input vref at 80% */
8746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8748 /* Front Mic pin: input vref at 80% */
8749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8751 /* Line In pin: use output 1 when in LineOut mode */
8752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8754 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8756 /* FIXME: use matrix-type input source selection */
8757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8758 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8773 /* ADC1: mute amp left and right */
8774 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8775 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8776 /* ADC2: mute amp left and right */
8777 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8778 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8779 /* ADC3: mute amp left and right */
8780 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8781 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8787 static const struct hda_verb alc885_imac91_init_verbs[] = {
8788 /* Internal Speaker Pin (0x0c) */
8789 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8790 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8792 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8794 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8799 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8803 /* Front Mic pin: input vref at 80% */
8804 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8805 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8810 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8814 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8818 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8819 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8821 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8823 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8824 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8828 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8829 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8831 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8832 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8835 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8837 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8841 /* iMac 24 mixer. */
8842 static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8843 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8844 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8848 /* iMac 24 init verbs. */
8849 static const struct hda_verb alc885_imac24_init_verbs[] = {
8850 /* Internal speakers: output 0 (0x0c) */
8851 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8852 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8853 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 /* Internal speakers: output 0 (0x0c) */
8855 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8856 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8857 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8858 /* Headphone: output 0 (0x0c) */
8859 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8861 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8862 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8863 /* Front Mic: input vref at 80% */
8864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8869 /* Toggle speaker-output according to the hp-jack state */
8870 static void alc885_imac24_setup(struct hda_codec *codec)
8872 struct alc_spec *spec = codec->spec;
8874 spec->autocfg.hp_pins[0] = 0x14;
8875 spec->autocfg.speaker_pins[0] = 0x18;
8876 spec->autocfg.speaker_pins[1] = 0x1a;
8878 spec->automute_mode = ALC_AUTOMUTE_AMP;
8881 #define alc885_mb5_setup alc885_imac24_setup
8882 #define alc885_macmini3_setup alc885_imac24_setup
8884 /* Macbook Air 2,1 */
8885 static void alc885_mba21_setup(struct hda_codec *codec)
8887 struct alc_spec *spec = codec->spec;
8889 spec->autocfg.hp_pins[0] = 0x14;
8890 spec->autocfg.speaker_pins[0] = 0x18;
8892 spec->automute_mode = ALC_AUTOMUTE_AMP;
8897 static void alc885_mbp3_setup(struct hda_codec *codec)
8899 struct alc_spec *spec = codec->spec;
8901 spec->autocfg.hp_pins[0] = 0x15;
8902 spec->autocfg.speaker_pins[0] = 0x14;
8904 spec->automute_mode = ALC_AUTOMUTE_AMP;
8907 static void alc885_imac91_setup(struct hda_codec *codec)
8909 struct alc_spec *spec = codec->spec;
8911 spec->autocfg.hp_pins[0] = 0x14;
8912 spec->autocfg.speaker_pins[0] = 0x18;
8913 spec->autocfg.speaker_pins[1] = 0x1a;
8915 spec->automute_mode = ALC_AUTOMUTE_AMP;
8918 static const struct hda_verb alc882_targa_verbs[] = {
8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8923 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8925 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8926 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8927 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8929 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8933 /* toggle speaker-output according to the hp-jack state */
8934 static void alc882_targa_automute(struct hda_codec *codec)
8936 struct alc_spec *spec = codec->spec;
8937 alc_hp_automute(codec);
8938 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8939 spec->jack_present ? 1 : 3);
8942 static void alc882_targa_setup(struct hda_codec *codec)
8944 struct alc_spec *spec = codec->spec;
8946 spec->autocfg.hp_pins[0] = 0x14;
8947 spec->autocfg.speaker_pins[0] = 0x1b;
8949 spec->automute_mode = ALC_AUTOMUTE_AMP;
8952 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8954 if ((res >> 26) == ALC880_HP_EVENT)
8955 alc882_targa_automute(codec);
8958 static const struct hda_verb alc882_asus_a7j_verbs[] = {
8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8964 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8966 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8967 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8968 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8970 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8971 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8972 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8976 static const struct hda_verb alc882_asus_a7m_verbs[] = {
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8980 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8986 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8988 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8989 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8990 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8994 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8996 unsigned int gpiostate, gpiomask, gpiodir;
8998 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8999 AC_VERB_GET_GPIO_DATA, 0);
9002 gpiostate |= (1 << pin);
9004 gpiostate &= ~(1 << pin);
9006 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9007 AC_VERB_GET_GPIO_MASK, 0);
9008 gpiomask |= (1 << pin);
9010 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9011 AC_VERB_GET_GPIO_DIRECTION, 0);
9012 gpiodir |= (1 << pin);
9015 snd_hda_codec_write(codec, codec->afg, 0,
9016 AC_VERB_SET_GPIO_MASK, gpiomask);
9017 snd_hda_codec_write(codec, codec->afg, 0,
9018 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9022 snd_hda_codec_write(codec, codec->afg, 0,
9023 AC_VERB_SET_GPIO_DATA, gpiostate);
9026 /* set up GPIO at initialization */
9027 static void alc885_macpro_init_hook(struct hda_codec *codec)
9029 alc882_gpio_mute(codec, 0, 0);
9030 alc882_gpio_mute(codec, 1, 0);
9033 /* set up GPIO and update auto-muting at initialization */
9034 static void alc885_imac24_init_hook(struct hda_codec *codec)
9036 alc885_macpro_init_hook(codec);
9037 alc_hp_automute(codec);
9040 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9041 static const struct hda_verb alc889A_mb31_ch2_init[] = {
9042 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9043 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9044 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9045 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9049 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9050 static const struct hda_verb alc889A_mb31_ch4_init[] = {
9051 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9052 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9053 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9054 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9058 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9059 static const struct hda_verb alc889A_mb31_ch5_init[] = {
9060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9061 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9063 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9067 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9068 static const struct hda_verb alc889A_mb31_ch6_init[] = {
9069 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9070 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9076 static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9077 { 2, alc889A_mb31_ch2_init },
9078 { 4, alc889A_mb31_ch4_init },
9079 { 5, alc889A_mb31_ch5_init },
9080 { 6, alc889A_mb31_ch6_init },
9083 static const struct hda_verb alc883_medion_eapd_verbs[] = {
9084 /* eanable EAPD on medion laptop */
9085 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9086 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9090 #define alc883_base_mixer alc882_base_mixer
9092 static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
9093 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9094 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9095 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9097 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9098 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9101 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9103 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9104 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9105 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9109 static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
9110 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9111 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9112 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9113 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9117 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9118 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9119 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9123 static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
9124 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9125 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9126 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9127 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9129 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9131 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9132 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9133 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9137 static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9138 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9139 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9141 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9142 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9146 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9148 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9149 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9150 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9154 static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9155 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9156 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9157 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9158 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9159 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9160 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9161 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9162 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9164 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9165 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9166 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9167 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9171 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9173 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9177 static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9178 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9179 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9180 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9181 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9182 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9184 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9185 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9186 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9187 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9188 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9189 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9190 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9191 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9192 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9194 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9195 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9196 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9201 static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9204 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9205 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9206 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9212 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9217 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9220 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9225 static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9226 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9227 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9228 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9229 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9230 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9231 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9232 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9233 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9234 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9235 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9236 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9237 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9238 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9240 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9241 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9242 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9243 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9244 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9248 static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9249 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9250 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9252 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9253 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9254 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9255 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9256 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9257 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9258 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9259 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9260 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9262 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9264 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9265 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9269 static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9270 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9271 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9272 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9273 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9277 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9278 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9279 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9280 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9281 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9285 static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9286 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9287 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9288 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9290 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9294 static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9296 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9297 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9298 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9306 static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9307 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9308 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9313 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9314 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9315 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9319 static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9322 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9323 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9324 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9325 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9329 static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9330 /* Unmute front mixer */
9331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9334 /* Set speaker pin to front mixer */
9335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9337 /* Init headphone pin */
9338 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9339 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9340 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9341 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9346 /* toggle speaker-output according to the hp-jack state */
9347 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9349 struct alc_spec *spec = codec->spec;
9351 spec->autocfg.hp_pins[0] = 0x1a;
9352 spec->autocfg.speaker_pins[0] = 0x15;
9354 spec->automute_mode = ALC_AUTOMUTE_AMP;
9357 static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9358 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9359 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9360 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9361 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9362 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9363 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9364 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9369 static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9371 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9372 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9373 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9377 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9382 static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9383 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9384 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9385 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9386 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9387 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9388 0x0d, 1, 0x0, HDA_OUTPUT),
9389 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9390 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9391 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9392 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9393 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9394 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9395 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9396 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9397 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9399 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9401 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9402 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9403 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9407 static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9409 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9410 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9411 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9412 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9415 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9417 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9418 /* Output switches */
9419 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9420 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9421 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9423 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9424 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9433 static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9434 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9435 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9436 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9438 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9443 static const struct hda_bind_ctls alc883_bind_cap_vol = {
9444 .ops = &snd_hda_bind_vol,
9446 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9447 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9452 static const struct hda_bind_ctls alc883_bind_cap_switch = {
9453 .ops = &snd_hda_bind_sw,
9455 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9456 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9461 static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9462 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9463 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9465 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9466 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9468 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9473 static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9474 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9475 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9478 /* .name = "Capture Source", */
9479 .name = "Input Source",
9481 .info = alc_mux_enum_info,
9482 .get = alc_mux_enum_get,
9483 .put = alc_mux_enum_put,
9488 static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9491 .name = "Channel Mode",
9492 .info = alc_ch_mode_info,
9493 .get = alc_ch_mode_get,
9494 .put = alc_ch_mode_put,
9499 /* toggle speaker-output according to the hp-jack state */
9500 static void alc883_mitac_setup(struct hda_codec *codec)
9502 struct alc_spec *spec = codec->spec;
9504 spec->autocfg.hp_pins[0] = 0x15;
9505 spec->autocfg.speaker_pins[0] = 0x14;
9506 spec->autocfg.speaker_pins[1] = 0x17;
9508 spec->automute_mode = ALC_AUTOMUTE_AMP;
9511 static const struct hda_verb alc883_mitac_verbs[] = {
9513 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9516 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9517 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9519 /* enable unsolicited event */
9520 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9521 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9526 static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9528 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9531 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9533 /* enable unsolicited event */
9535 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9536 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9542 static const struct hda_verb alc883_clevo_m720_verbs[] = {
9544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9547 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9548 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9550 /* enable unsolicited event */
9551 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9552 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9557 static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9559 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9562 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9565 /* enable unsolicited event */
9566 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9571 static const struct hda_verb alc883_targa_verbs[] = {
9572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9575 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9576 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9578 /* Connect Line-Out side jack (SPDIF) to Side */
9579 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9580 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9581 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9582 /* Connect Mic jack to CLFE */
9583 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9585 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9586 /* Connect Line-in jack to Surround */
9587 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9588 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9589 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9590 /* Connect HP out jack to Front */
9591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9593 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9595 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9600 static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9602 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9603 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9607 static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9608 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9610 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9615 static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9616 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9618 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9619 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9620 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9624 static const struct hda_verb alc883_haier_w66_verbs[] = {
9625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9628 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9630 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9631 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9632 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9637 static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9640 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9641 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9642 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9643 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9644 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9645 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9649 static const struct hda_verb alc888_6st_dell_verbs[] = {
9650 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9654 static const struct hda_verb alc883_vaiott_verbs[] = {
9656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9659 /* enable unsolicited event */
9660 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9665 static void alc888_3st_hp_setup(struct hda_codec *codec)
9667 struct alc_spec *spec = codec->spec;
9669 spec->autocfg.hp_pins[0] = 0x1b;
9670 spec->autocfg.speaker_pins[0] = 0x14;
9671 spec->autocfg.speaker_pins[1] = 0x16;
9672 spec->autocfg.speaker_pins[2] = 0x18;
9674 spec->automute_mode = ALC_AUTOMUTE_AMP;
9677 static const struct hda_verb alc888_3st_hp_verbs[] = {
9678 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9679 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9680 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9681 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9688 static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9689 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9690 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9691 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9692 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9699 static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9700 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9701 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9702 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9703 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9704 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9711 static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9712 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9713 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9714 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9715 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9716 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9717 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9721 static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9722 { 2, alc888_3st_hp_2ch_init },
9723 { 4, alc888_3st_hp_4ch_init },
9724 { 6, alc888_3st_hp_6ch_init },
9727 static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9729 struct alc_spec *spec = codec->spec;
9731 spec->autocfg.hp_pins[0] = 0x1b;
9732 spec->autocfg.line_out_pins[0] = 0x14;
9733 spec->autocfg.speaker_pins[0] = 0x15;
9735 spec->automute_mode = ALC_AUTOMUTE_AMP;
9738 /* toggle speaker-output according to the hp-jack state */
9739 static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9741 struct alc_spec *spec = codec->spec;
9743 spec->autocfg.hp_pins[0] = 0x14;
9744 spec->autocfg.speaker_pins[0] = 0x15;
9746 spec->automute_mode = ALC_AUTOMUTE_AMP;
9749 /* toggle speaker-output according to the hp-jack state */
9750 #define alc883_targa_init_hook alc882_targa_init_hook
9751 #define alc883_targa_unsol_event alc882_targa_unsol_event
9753 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9755 struct alc_spec *spec = codec->spec;
9757 spec->autocfg.hp_pins[0] = 0x15;
9758 spec->autocfg.speaker_pins[0] = 0x14;
9760 spec->automute_mode = ALC_AUTOMUTE_AMP;
9763 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9765 alc_hp_automute(codec);
9766 alc88x_simple_mic_automute(codec);
9769 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9772 switch (res >> 26) {
9773 case ALC880_MIC_EVENT:
9774 alc88x_simple_mic_automute(codec);
9777 alc_sku_unsol_event(codec, res);
9782 /* toggle speaker-output according to the hp-jack state */
9783 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9785 struct alc_spec *spec = codec->spec;
9787 spec->autocfg.hp_pins[0] = 0x14;
9788 spec->autocfg.speaker_pins[0] = 0x15;
9790 spec->automute_mode = ALC_AUTOMUTE_AMP;
9793 static void alc883_haier_w66_setup(struct hda_codec *codec)
9795 struct alc_spec *spec = codec->spec;
9797 spec->autocfg.hp_pins[0] = 0x1b;
9798 spec->autocfg.speaker_pins[0] = 0x14;
9800 spec->automute_mode = ALC_AUTOMUTE_AMP;
9803 static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9805 struct alc_spec *spec = codec->spec;
9807 spec->autocfg.hp_pins[0] = 0x1b;
9808 spec->autocfg.line_out_pins[0] = 0x14;
9809 spec->autocfg.speaker_pins[0] = 0x15;
9811 spec->detect_line = 1;
9812 spec->automute_lines = 1;
9813 spec->automute_mode = ALC_AUTOMUTE_AMP;
9816 /* toggle speaker-output according to the hp-jack state */
9817 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9819 struct alc_spec *spec = codec->spec;
9821 spec->autocfg.hp_pins[0] = 0x14;
9822 spec->autocfg.speaker_pins[0] = 0x15;
9823 spec->autocfg.speaker_pins[1] = 0x16;
9825 spec->automute_mode = ALC_AUTOMUTE_AMP;
9828 static const struct hda_verb alc883_acer_eapd_verbs[] = {
9829 /* HP Pin: output 0 (0x0c) */
9830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9833 /* Front Pin: output 0 (0x0c) */
9834 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9835 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9836 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9837 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9838 /* eanable EAPD on medion laptop */
9839 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9840 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9841 /* enable unsolicited event */
9842 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9846 static void alc888_6st_dell_setup(struct hda_codec *codec)
9848 struct alc_spec *spec = codec->spec;
9850 spec->autocfg.hp_pins[0] = 0x1b;
9851 spec->autocfg.speaker_pins[0] = 0x14;
9852 spec->autocfg.speaker_pins[1] = 0x15;
9853 spec->autocfg.speaker_pins[2] = 0x16;
9854 spec->autocfg.speaker_pins[3] = 0x17;
9856 spec->automute_mode = ALC_AUTOMUTE_AMP;
9859 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9861 struct alc_spec *spec = codec->spec;
9863 spec->autocfg.hp_pins[0] = 0x1b;
9864 spec->autocfg.speaker_pins[0] = 0x14;
9865 spec->autocfg.speaker_pins[1] = 0x15;
9866 spec->autocfg.speaker_pins[2] = 0x16;
9867 spec->autocfg.speaker_pins[3] = 0x17;
9868 spec->autocfg.speaker_pins[4] = 0x1a;
9870 spec->automute_mode = ALC_AUTOMUTE_AMP;
9873 static void alc883_vaiott_setup(struct hda_codec *codec)
9875 struct alc_spec *spec = codec->spec;
9877 spec->autocfg.hp_pins[0] = 0x15;
9878 spec->autocfg.speaker_pins[0] = 0x14;
9879 spec->autocfg.speaker_pins[1] = 0x17;
9881 spec->automute_mode = ALC_AUTOMUTE_AMP;
9884 static const struct hda_verb alc888_asus_m90v_verbs[] = {
9885 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9886 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9888 /* enable unsolicited event */
9889 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9890 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9894 static void alc883_mode2_setup(struct hda_codec *codec)
9896 struct alc_spec *spec = codec->spec;
9898 spec->autocfg.hp_pins[0] = 0x1b;
9899 spec->autocfg.speaker_pins[0] = 0x14;
9900 spec->autocfg.speaker_pins[1] = 0x15;
9901 spec->autocfg.speaker_pins[2] = 0x16;
9902 spec->ext_mic.pin = 0x18;
9903 spec->int_mic.pin = 0x19;
9904 spec->ext_mic.mux_idx = 0;
9905 spec->int_mic.mux_idx = 1;
9908 spec->automute_mode = ALC_AUTOMUTE_AMP;
9911 static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9912 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9915 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9916 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9917 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9918 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9919 /* enable unsolicited event */
9920 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9924 static void alc883_eee1601_inithook(struct hda_codec *codec)
9926 struct alc_spec *spec = codec->spec;
9928 spec->autocfg.hp_pins[0] = 0x14;
9929 spec->autocfg.speaker_pins[0] = 0x1b;
9930 alc_hp_automute(codec);
9933 static const struct hda_verb alc889A_mb31_verbs[] = {
9934 /* Init rear pin (used as headphone output) */
9935 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9936 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9937 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9938 /* Init line pin (used as output in 4ch and 6ch mode) */
9939 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9940 /* Init line 2 pin (used as headphone out by default) */
9941 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9942 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9946 /* Mute speakers according to the headphone jack state */
9947 static void alc889A_mb31_automute(struct hda_codec *codec)
9949 unsigned int present;
9951 /* Mute only in 2ch or 4ch mode */
9952 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9954 present = snd_hda_jack_detect(codec, 0x15);
9955 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9956 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9957 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9958 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9962 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9964 if ((res >> 26) == ALC880_HP_EVENT)
9965 alc889A_mb31_automute(codec);
9969 #ifdef CONFIG_SND_HDA_POWER_SAVE
9970 #define alc882_loopbacks alc880_loopbacks
9973 /* pcm configuration: identical with ALC880 */
9974 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9975 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9976 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9977 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9979 static const hda_nid_t alc883_slave_dig_outs[] = {
9980 ALC1200_DIGOUT_NID, 0,
9983 static const hda_nid_t alc1200_slave_dig_outs[] = {
9984 ALC883_DIGOUT_NID, 0,
9988 * configuration and preset
9990 static const char * const alc882_models[ALC882_MODEL_LAST] = {
9991 [ALC882_3ST_DIG] = "3stack-dig",
9992 [ALC882_6ST_DIG] = "6stack-dig",
9993 [ALC882_ARIMA] = "arima",
9994 [ALC882_W2JC] = "w2jc",
9995 [ALC882_TARGA] = "targa",
9996 [ALC882_ASUS_A7J] = "asus-a7j",
9997 [ALC882_ASUS_A7M] = "asus-a7m",
9998 [ALC885_MACPRO] = "macpro",
9999 [ALC885_MB5] = "mb5",
10000 [ALC885_MACMINI3] = "macmini3",
10001 [ALC885_MBA21] = "mba21",
10002 [ALC885_MBP3] = "mbp3",
10003 [ALC885_IMAC24] = "imac24",
10004 [ALC885_IMAC91] = "imac91",
10005 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
10006 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10007 [ALC883_3ST_6ch] = "3stack-6ch",
10008 [ALC883_6ST_DIG] = "alc883-6stack-dig",
10009 [ALC883_TARGA_DIG] = "targa-dig",
10010 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
10011 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
10012 [ALC883_ACER] = "acer",
10013 [ALC883_ACER_ASPIRE] = "acer-aspire",
10014 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
10015 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
10016 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
10017 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
10018 [ALC883_MEDION] = "medion",
10019 [ALC883_MEDION_WIM2160] = "medion-wim2160",
10020 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
10021 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
10022 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10023 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
10024 [ALC888_LENOVO_SKY] = "lenovo-sky",
10025 [ALC883_HAIER_W66] = "haier-w66",
10026 [ALC888_3ST_HP] = "3stack-hp",
10027 [ALC888_6ST_DELL] = "6stack-dell",
10028 [ALC883_MITAC] = "mitac",
10029 [ALC883_CLEVO_M540R] = "clevo-m540r",
10030 [ALC883_CLEVO_M720] = "clevo-m720",
10031 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
10032 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
10033 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
10034 [ALC889A_INTEL] = "intel-alc889a",
10035 [ALC889_INTEL] = "intel-x58",
10036 [ALC1200_ASUS_P5Q] = "asus-p5q",
10037 [ALC889A_MB31] = "mb31",
10038 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
10039 [ALC882_AUTO] = "auto",
10042 static const struct snd_pci_quirk alc882_cfg_tbl[] = {
10043 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10045 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
10046 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
10047 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
10048 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10049 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
10050 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
10051 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10052 ALC888_ACER_ASPIRE_4930G),
10053 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
10054 ALC888_ACER_ASPIRE_4930G),
10055 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10056 ALC888_ACER_ASPIRE_8930G),
10057 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10058 ALC888_ACER_ASPIRE_8930G),
10059 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10060 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
10061 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
10062 ALC888_ACER_ASPIRE_6530G),
10063 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
10064 ALC888_ACER_ASPIRE_6530G),
10065 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10066 ALC888_ACER_ASPIRE_7730G),
10067 /* default Acer -- disabled as it causes more problems.
10068 * model=auto should work fine now
10070 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
10072 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
10074 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
10075 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10076 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
10077 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
10078 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
10079 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
10081 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10082 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10083 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
10084 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
10085 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10086 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10087 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
10088 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
10089 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
10090 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
10091 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
10093 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
10094 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
10095 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
10096 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
10097 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10098 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
10099 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
10100 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
10101 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
10103 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
10104 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
10105 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
10106 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
10107 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
10108 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
10109 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
10110 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
10111 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
10112 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
10113 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10114 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
10115 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
10116 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
10117 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
10118 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10119 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10120 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
10121 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
10122 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
10123 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10124 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10125 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
10126 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
10127 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
10128 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10129 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
10130 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
10131 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
10132 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
10133 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
10135 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
10136 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
10137 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10138 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
10139 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
10140 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
10141 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
10142 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
10143 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
10144 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
10145 ALC883_FUJITSU_PI2515),
10146 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
10147 ALC888_FUJITSU_XA3530),
10148 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
10149 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10150 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10151 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10152 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
10153 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
10154 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
10155 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
10157 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10158 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
10159 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10160 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10161 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10162 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10163 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10168 /* codec SSID table for Intel Mac */
10169 static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10170 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10171 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10172 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10173 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10174 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10175 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10176 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10177 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10178 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10179 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10180 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10181 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10182 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10183 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10184 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10185 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10186 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10187 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10188 * so apparently no perfect solution yet
10190 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10191 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10192 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10193 {} /* terminator */
10196 static const struct alc_config_preset alc882_presets[] = {
10197 [ALC882_3ST_DIG] = {
10198 .mixers = { alc882_base_mixer },
10199 .init_verbs = { alc882_base_init_verbs,
10200 alc882_adc1_init_verbs },
10201 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10202 .dac_nids = alc882_dac_nids,
10203 .dig_out_nid = ALC882_DIGOUT_NID,
10204 .dig_in_nid = ALC882_DIGIN_NID,
10205 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10206 .channel_mode = alc882_ch_modes,
10208 .input_mux = &alc882_capture_source,
10210 [ALC882_6ST_DIG] = {
10211 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10212 .init_verbs = { alc882_base_init_verbs,
10213 alc882_adc1_init_verbs },
10214 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10215 .dac_nids = alc882_dac_nids,
10216 .dig_out_nid = ALC882_DIGOUT_NID,
10217 .dig_in_nid = ALC882_DIGIN_NID,
10218 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10219 .channel_mode = alc882_sixstack_modes,
10220 .input_mux = &alc882_capture_source,
10223 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10224 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10225 alc882_eapd_verbs },
10226 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10227 .dac_nids = alc882_dac_nids,
10228 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10229 .channel_mode = alc882_sixstack_modes,
10230 .input_mux = &alc882_capture_source,
10233 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10234 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10235 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10236 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10237 .dac_nids = alc882_dac_nids,
10238 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10239 .channel_mode = alc880_threestack_modes,
10241 .input_mux = &alc882_capture_source,
10242 .dig_out_nid = ALC882_DIGOUT_NID,
10245 .mixers = { alc885_mba21_mixer },
10246 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10248 .dac_nids = alc882_dac_nids,
10249 .channel_mode = alc885_mba21_ch_modes,
10250 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10251 .input_mux = &alc882_capture_source,
10252 .unsol_event = alc_sku_unsol_event,
10253 .setup = alc885_mba21_setup,
10254 .init_hook = alc_hp_automute,
10257 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10258 .init_verbs = { alc885_mbp3_init_verbs,
10259 alc880_gpio1_init_verbs },
10261 .dac_nids = alc882_dac_nids,
10263 .channel_mode = alc885_mbp_4ch_modes,
10264 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10265 .input_mux = &alc882_capture_source,
10266 .dig_out_nid = ALC882_DIGOUT_NID,
10267 .dig_in_nid = ALC882_DIGIN_NID,
10268 .unsol_event = alc_sku_unsol_event,
10269 .setup = alc885_mbp3_setup,
10270 .init_hook = alc_hp_automute,
10273 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10274 .init_verbs = { alc885_mb5_init_verbs,
10275 alc880_gpio1_init_verbs },
10276 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10277 .dac_nids = alc882_dac_nids,
10278 .channel_mode = alc885_mb5_6ch_modes,
10279 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10280 .input_mux = &mb5_capture_source,
10281 .dig_out_nid = ALC882_DIGOUT_NID,
10282 .dig_in_nid = ALC882_DIGIN_NID,
10283 .unsol_event = alc_sku_unsol_event,
10284 .setup = alc885_mb5_setup,
10285 .init_hook = alc_hp_automute,
10287 [ALC885_MACMINI3] = {
10288 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10289 .init_verbs = { alc885_macmini3_init_verbs,
10290 alc880_gpio1_init_verbs },
10291 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10292 .dac_nids = alc882_dac_nids,
10293 .channel_mode = alc885_macmini3_6ch_modes,
10294 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10295 .input_mux = &macmini3_capture_source,
10296 .dig_out_nid = ALC882_DIGOUT_NID,
10297 .dig_in_nid = ALC882_DIGIN_NID,
10298 .unsol_event = alc_sku_unsol_event,
10299 .setup = alc885_macmini3_setup,
10300 .init_hook = alc_hp_automute,
10302 [ALC885_MACPRO] = {
10303 .mixers = { alc882_macpro_mixer },
10304 .init_verbs = { alc882_macpro_init_verbs },
10305 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10306 .dac_nids = alc882_dac_nids,
10307 .dig_out_nid = ALC882_DIGOUT_NID,
10308 .dig_in_nid = ALC882_DIGIN_NID,
10309 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10310 .channel_mode = alc882_ch_modes,
10311 .input_mux = &alc882_capture_source,
10312 .init_hook = alc885_macpro_init_hook,
10314 [ALC885_IMAC24] = {
10315 .mixers = { alc885_imac24_mixer },
10316 .init_verbs = { alc885_imac24_init_verbs },
10317 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10318 .dac_nids = alc882_dac_nids,
10319 .dig_out_nid = ALC882_DIGOUT_NID,
10320 .dig_in_nid = ALC882_DIGIN_NID,
10321 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10322 .channel_mode = alc882_ch_modes,
10323 .input_mux = &alc882_capture_source,
10324 .unsol_event = alc_sku_unsol_event,
10325 .setup = alc885_imac24_setup,
10326 .init_hook = alc885_imac24_init_hook,
10328 [ALC885_IMAC91] = {
10329 .mixers = {alc885_imac91_mixer},
10330 .init_verbs = { alc885_imac91_init_verbs,
10331 alc880_gpio1_init_verbs },
10332 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10333 .dac_nids = alc882_dac_nids,
10334 .channel_mode = alc885_mba21_ch_modes,
10335 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10336 .input_mux = &alc889A_imac91_capture_source,
10337 .dig_out_nid = ALC882_DIGOUT_NID,
10338 .dig_in_nid = ALC882_DIGIN_NID,
10339 .unsol_event = alc_sku_unsol_event,
10340 .setup = alc885_imac91_setup,
10341 .init_hook = alc_hp_automute,
10344 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10345 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10346 alc880_gpio3_init_verbs, alc882_targa_verbs},
10347 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10348 .dac_nids = alc882_dac_nids,
10349 .dig_out_nid = ALC882_DIGOUT_NID,
10350 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10351 .adc_nids = alc882_adc_nids,
10352 .capsrc_nids = alc882_capsrc_nids,
10353 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10354 .channel_mode = alc882_3ST_6ch_modes,
10356 .input_mux = &alc882_capture_source,
10357 .unsol_event = alc_sku_unsol_event,
10358 .setup = alc882_targa_setup,
10359 .init_hook = alc882_targa_automute,
10361 [ALC882_ASUS_A7J] = {
10362 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10363 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10364 alc882_asus_a7j_verbs},
10365 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10366 .dac_nids = alc882_dac_nids,
10367 .dig_out_nid = ALC882_DIGOUT_NID,
10368 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10369 .adc_nids = alc882_adc_nids,
10370 .capsrc_nids = alc882_capsrc_nids,
10371 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10372 .channel_mode = alc882_3ST_6ch_modes,
10374 .input_mux = &alc882_capture_source,
10376 [ALC882_ASUS_A7M] = {
10377 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10378 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10379 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10380 alc882_asus_a7m_verbs },
10381 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10382 .dac_nids = alc882_dac_nids,
10383 .dig_out_nid = ALC882_DIGOUT_NID,
10384 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10385 .channel_mode = alc880_threestack_modes,
10387 .input_mux = &alc882_capture_source,
10389 [ALC883_3ST_2ch_DIG] = {
10390 .mixers = { alc883_3ST_2ch_mixer },
10391 .init_verbs = { alc883_init_verbs },
10392 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10393 .dac_nids = alc883_dac_nids,
10394 .dig_out_nid = ALC883_DIGOUT_NID,
10395 .dig_in_nid = ALC883_DIGIN_NID,
10396 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10397 .channel_mode = alc883_3ST_2ch_modes,
10398 .input_mux = &alc883_capture_source,
10400 [ALC883_3ST_6ch_DIG] = {
10401 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10402 .init_verbs = { alc883_init_verbs },
10403 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10404 .dac_nids = alc883_dac_nids,
10405 .dig_out_nid = ALC883_DIGOUT_NID,
10406 .dig_in_nid = ALC883_DIGIN_NID,
10407 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10408 .channel_mode = alc883_3ST_6ch_modes,
10410 .input_mux = &alc883_capture_source,
10412 [ALC883_3ST_6ch] = {
10413 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10414 .init_verbs = { alc883_init_verbs },
10415 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10416 .dac_nids = alc883_dac_nids,
10417 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10418 .channel_mode = alc883_3ST_6ch_modes,
10420 .input_mux = &alc883_capture_source,
10422 [ALC883_3ST_6ch_INTEL] = {
10423 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10424 .init_verbs = { alc883_init_verbs },
10425 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10426 .dac_nids = alc883_dac_nids,
10427 .dig_out_nid = ALC883_DIGOUT_NID,
10428 .dig_in_nid = ALC883_DIGIN_NID,
10429 .slave_dig_outs = alc883_slave_dig_outs,
10430 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10431 .channel_mode = alc883_3ST_6ch_intel_modes,
10433 .input_mux = &alc883_3stack_6ch_intel,
10435 [ALC889A_INTEL] = {
10436 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10437 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10438 alc_hp15_unsol_verbs },
10439 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10440 .dac_nids = alc883_dac_nids,
10441 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10442 .adc_nids = alc889_adc_nids,
10443 .dig_out_nid = ALC883_DIGOUT_NID,
10444 .dig_in_nid = ALC883_DIGIN_NID,
10445 .slave_dig_outs = alc883_slave_dig_outs,
10446 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10447 .channel_mode = alc889_8ch_intel_modes,
10448 .capsrc_nids = alc889_capsrc_nids,
10449 .input_mux = &alc889_capture_source,
10450 .setup = alc889_automute_setup,
10451 .init_hook = alc_hp_automute,
10452 .unsol_event = alc_sku_unsol_event,
10456 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10457 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10458 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10459 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10460 .dac_nids = alc883_dac_nids,
10461 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10462 .adc_nids = alc889_adc_nids,
10463 .dig_out_nid = ALC883_DIGOUT_NID,
10464 .dig_in_nid = ALC883_DIGIN_NID,
10465 .slave_dig_outs = alc883_slave_dig_outs,
10466 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10467 .channel_mode = alc889_8ch_intel_modes,
10468 .capsrc_nids = alc889_capsrc_nids,
10469 .input_mux = &alc889_capture_source,
10470 .setup = alc889_automute_setup,
10471 .init_hook = alc889_intel_init_hook,
10472 .unsol_event = alc_sku_unsol_event,
10475 [ALC883_6ST_DIG] = {
10476 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10477 .init_verbs = { alc883_init_verbs },
10478 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10479 .dac_nids = alc883_dac_nids,
10480 .dig_out_nid = ALC883_DIGOUT_NID,
10481 .dig_in_nid = ALC883_DIGIN_NID,
10482 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10483 .channel_mode = alc883_sixstack_modes,
10484 .input_mux = &alc883_capture_source,
10486 [ALC883_TARGA_DIG] = {
10487 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10488 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10489 alc883_targa_verbs},
10490 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10491 .dac_nids = alc883_dac_nids,
10492 .dig_out_nid = ALC883_DIGOUT_NID,
10493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10494 .channel_mode = alc883_3ST_6ch_modes,
10496 .input_mux = &alc883_capture_source,
10497 .unsol_event = alc883_targa_unsol_event,
10498 .setup = alc882_targa_setup,
10499 .init_hook = alc882_targa_automute,
10501 [ALC883_TARGA_2ch_DIG] = {
10502 .mixers = { alc883_targa_2ch_mixer},
10503 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10504 alc883_targa_verbs},
10505 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10506 .dac_nids = alc883_dac_nids,
10507 .adc_nids = alc883_adc_nids_alt,
10508 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10509 .capsrc_nids = alc883_capsrc_nids,
10510 .dig_out_nid = ALC883_DIGOUT_NID,
10511 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10512 .channel_mode = alc883_3ST_2ch_modes,
10513 .input_mux = &alc883_capture_source,
10514 .unsol_event = alc883_targa_unsol_event,
10515 .setup = alc882_targa_setup,
10516 .init_hook = alc882_targa_automute,
10518 [ALC883_TARGA_8ch_DIG] = {
10519 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10520 alc883_chmode_mixer },
10521 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10522 alc883_targa_verbs },
10523 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10524 .dac_nids = alc883_dac_nids,
10525 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10526 .adc_nids = alc883_adc_nids_rev,
10527 .capsrc_nids = alc883_capsrc_nids_rev,
10528 .dig_out_nid = ALC883_DIGOUT_NID,
10529 .dig_in_nid = ALC883_DIGIN_NID,
10530 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10531 .channel_mode = alc883_4ST_8ch_modes,
10533 .input_mux = &alc883_capture_source,
10534 .unsol_event = alc883_targa_unsol_event,
10535 .setup = alc882_targa_setup,
10536 .init_hook = alc882_targa_automute,
10539 .mixers = { alc883_base_mixer },
10540 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10541 * and the headphone jack. Turn this on and rely on the
10542 * standard mute methods whenever the user wants to turn
10543 * these outputs off.
10545 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
10548 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10549 .channel_mode = alc883_3ST_2ch_modes,
10550 .input_mux = &alc883_capture_source,
10552 [ALC883_ACER_ASPIRE] = {
10553 .mixers = { alc883_acer_aspire_mixer },
10554 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10555 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10556 .dac_nids = alc883_dac_nids,
10557 .dig_out_nid = ALC883_DIGOUT_NID,
10558 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10559 .channel_mode = alc883_3ST_2ch_modes,
10560 .input_mux = &alc883_capture_source,
10561 .unsol_event = alc_sku_unsol_event,
10562 .setup = alc883_acer_aspire_setup,
10563 .init_hook = alc_hp_automute,
10565 [ALC888_ACER_ASPIRE_4930G] = {
10566 .mixers = { alc888_acer_aspire_4930g_mixer,
10567 alc883_chmode_mixer },
10568 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10569 alc888_acer_aspire_4930g_verbs },
10570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10571 .dac_nids = alc883_dac_nids,
10572 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10573 .adc_nids = alc883_adc_nids_rev,
10574 .capsrc_nids = alc883_capsrc_nids_rev,
10575 .dig_out_nid = ALC883_DIGOUT_NID,
10576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10577 .channel_mode = alc883_3ST_6ch_modes,
10579 .const_channel_count = 6,
10581 ARRAY_SIZE(alc888_2_capture_sources),
10582 .input_mux = alc888_2_capture_sources,
10583 .unsol_event = alc_sku_unsol_event,
10584 .setup = alc888_acer_aspire_4930g_setup,
10585 .init_hook = alc_hp_automute,
10587 [ALC888_ACER_ASPIRE_6530G] = {
10588 .mixers = { alc888_acer_aspire_6530_mixer },
10589 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10590 alc888_acer_aspire_6530g_verbs },
10591 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10592 .dac_nids = alc883_dac_nids,
10593 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10594 .adc_nids = alc883_adc_nids_rev,
10595 .capsrc_nids = alc883_capsrc_nids_rev,
10596 .dig_out_nid = ALC883_DIGOUT_NID,
10597 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10598 .channel_mode = alc883_3ST_2ch_modes,
10600 ARRAY_SIZE(alc888_2_capture_sources),
10601 .input_mux = alc888_acer_aspire_6530_sources,
10602 .unsol_event = alc_sku_unsol_event,
10603 .setup = alc888_acer_aspire_6530g_setup,
10604 .init_hook = alc_hp_automute,
10606 [ALC888_ACER_ASPIRE_8930G] = {
10607 .mixers = { alc889_acer_aspire_8930g_mixer,
10608 alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10610 alc889_acer_aspire_8930g_verbs,
10611 alc889_eapd_verbs},
10612 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10613 .dac_nids = alc883_dac_nids,
10614 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10615 .adc_nids = alc889_adc_nids,
10616 .capsrc_nids = alc889_capsrc_nids,
10617 .dig_out_nid = ALC883_DIGOUT_NID,
10618 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10619 .channel_mode = alc883_3ST_6ch_modes,
10621 .const_channel_count = 6,
10623 ARRAY_SIZE(alc889_capture_sources),
10624 .input_mux = alc889_capture_sources,
10625 .unsol_event = alc_sku_unsol_event,
10626 .setup = alc889_acer_aspire_8930g_setup,
10627 .init_hook = alc_hp_automute,
10628 #ifdef CONFIG_SND_HDA_POWER_SAVE
10629 .power_hook = alc_power_eapd,
10632 [ALC888_ACER_ASPIRE_7730G] = {
10633 .mixers = { alc883_3ST_6ch_mixer,
10634 alc883_chmode_mixer },
10635 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10636 alc888_acer_aspire_7730G_verbs },
10637 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10638 .dac_nids = alc883_dac_nids,
10639 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10640 .adc_nids = alc883_adc_nids_rev,
10641 .capsrc_nids = alc883_capsrc_nids_rev,
10642 .dig_out_nid = ALC883_DIGOUT_NID,
10643 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10644 .channel_mode = alc883_3ST_6ch_modes,
10646 .const_channel_count = 6,
10647 .input_mux = &alc883_capture_source,
10648 .unsol_event = alc_sku_unsol_event,
10649 .setup = alc888_acer_aspire_7730g_setup,
10650 .init_hook = alc_hp_automute,
10652 [ALC883_MEDION] = {
10653 .mixers = { alc883_fivestack_mixer,
10654 alc883_chmode_mixer },
10655 .init_verbs = { alc883_init_verbs,
10656 alc883_medion_eapd_verbs },
10657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10658 .dac_nids = alc883_dac_nids,
10659 .adc_nids = alc883_adc_nids_alt,
10660 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10661 .capsrc_nids = alc883_capsrc_nids,
10662 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10663 .channel_mode = alc883_sixstack_modes,
10664 .input_mux = &alc883_capture_source,
10666 [ALC883_MEDION_WIM2160] = {
10667 .mixers = { alc883_medion_wim2160_mixer },
10668 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10669 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10670 .dac_nids = alc883_dac_nids,
10671 .dig_out_nid = ALC883_DIGOUT_NID,
10672 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10673 .adc_nids = alc883_adc_nids,
10674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10675 .channel_mode = alc883_3ST_2ch_modes,
10676 .input_mux = &alc883_capture_source,
10677 .unsol_event = alc_sku_unsol_event,
10678 .setup = alc883_medion_wim2160_setup,
10679 .init_hook = alc_hp_automute,
10681 [ALC883_LAPTOP_EAPD] = {
10682 .mixers = { alc883_base_mixer },
10683 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10684 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10685 .dac_nids = alc883_dac_nids,
10686 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10687 .channel_mode = alc883_3ST_2ch_modes,
10688 .input_mux = &alc883_capture_source,
10690 [ALC883_CLEVO_M540R] = {
10691 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10692 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10693 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10694 .dac_nids = alc883_dac_nids,
10695 .dig_out_nid = ALC883_DIGOUT_NID,
10696 .dig_in_nid = ALC883_DIGIN_NID,
10697 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10698 .channel_mode = alc883_3ST_6ch_clevo_modes,
10700 .input_mux = &alc883_capture_source,
10701 /* This machine has the hardware HP auto-muting, thus
10702 * we need no software mute via unsol event
10705 [ALC883_CLEVO_M720] = {
10706 .mixers = { alc883_clevo_m720_mixer },
10707 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10708 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10709 .dac_nids = alc883_dac_nids,
10710 .dig_out_nid = ALC883_DIGOUT_NID,
10711 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10712 .channel_mode = alc883_3ST_2ch_modes,
10713 .input_mux = &alc883_capture_source,
10714 .unsol_event = alc883_clevo_m720_unsol_event,
10715 .setup = alc883_clevo_m720_setup,
10716 .init_hook = alc883_clevo_m720_init_hook,
10718 [ALC883_LENOVO_101E_2ch] = {
10719 .mixers = { alc883_lenovo_101e_2ch_mixer},
10720 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10721 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10722 .dac_nids = alc883_dac_nids,
10723 .adc_nids = alc883_adc_nids_alt,
10724 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10725 .capsrc_nids = alc883_capsrc_nids,
10726 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10727 .channel_mode = alc883_3ST_2ch_modes,
10728 .input_mux = &alc883_lenovo_101e_capture_source,
10729 .setup = alc883_lenovo_101e_setup,
10730 .unsol_event = alc_sku_unsol_event,
10731 .init_hook = alc_inithook,
10733 [ALC883_LENOVO_NB0763] = {
10734 .mixers = { alc883_lenovo_nb0763_mixer },
10735 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10736 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10737 .dac_nids = alc883_dac_nids,
10738 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10739 .channel_mode = alc883_3ST_2ch_modes,
10741 .input_mux = &alc883_lenovo_nb0763_capture_source,
10742 .unsol_event = alc_sku_unsol_event,
10743 .setup = alc883_lenovo_nb0763_setup,
10744 .init_hook = alc_hp_automute,
10746 [ALC888_LENOVO_MS7195_DIG] = {
10747 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10748 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .dac_nids = alc883_dac_nids,
10751 .dig_out_nid = ALC883_DIGOUT_NID,
10752 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10753 .channel_mode = alc883_3ST_6ch_modes,
10755 .input_mux = &alc883_capture_source,
10756 .unsol_event = alc_sku_unsol_event,
10757 .setup = alc888_lenovo_ms7195_setup,
10758 .init_hook = alc_inithook,
10760 [ALC883_HAIER_W66] = {
10761 .mixers = { alc883_targa_2ch_mixer},
10762 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10764 .dac_nids = alc883_dac_nids,
10765 .dig_out_nid = ALC883_DIGOUT_NID,
10766 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10767 .channel_mode = alc883_3ST_2ch_modes,
10768 .input_mux = &alc883_capture_source,
10769 .unsol_event = alc_sku_unsol_event,
10770 .setup = alc883_haier_w66_setup,
10771 .init_hook = alc_hp_automute,
10773 [ALC888_3ST_HP] = {
10774 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10775 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10776 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10777 .dac_nids = alc883_dac_nids,
10778 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10779 .channel_mode = alc888_3st_hp_modes,
10781 .input_mux = &alc883_capture_source,
10782 .unsol_event = alc_sku_unsol_event,
10783 .setup = alc888_3st_hp_setup,
10784 .init_hook = alc_hp_automute,
10786 [ALC888_6ST_DELL] = {
10787 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10788 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10789 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10790 .dac_nids = alc883_dac_nids,
10791 .dig_out_nid = ALC883_DIGOUT_NID,
10792 .dig_in_nid = ALC883_DIGIN_NID,
10793 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10794 .channel_mode = alc883_sixstack_modes,
10795 .input_mux = &alc883_capture_source,
10796 .unsol_event = alc_sku_unsol_event,
10797 .setup = alc888_6st_dell_setup,
10798 .init_hook = alc_hp_automute,
10801 .mixers = { alc883_mitac_mixer },
10802 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10803 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10804 .dac_nids = alc883_dac_nids,
10805 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10806 .channel_mode = alc883_3ST_2ch_modes,
10807 .input_mux = &alc883_capture_source,
10808 .unsol_event = alc_sku_unsol_event,
10809 .setup = alc883_mitac_setup,
10810 .init_hook = alc_hp_automute,
10812 [ALC883_FUJITSU_PI2515] = {
10813 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10814 .init_verbs = { alc883_init_verbs,
10815 alc883_2ch_fujitsu_pi2515_verbs},
10816 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10817 .dac_nids = alc883_dac_nids,
10818 .dig_out_nid = ALC883_DIGOUT_NID,
10819 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10820 .channel_mode = alc883_3ST_2ch_modes,
10821 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10822 .unsol_event = alc_sku_unsol_event,
10823 .setup = alc883_2ch_fujitsu_pi2515_setup,
10824 .init_hook = alc_hp_automute,
10826 [ALC888_FUJITSU_XA3530] = {
10827 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10828 .init_verbs = { alc883_init_verbs,
10829 alc888_fujitsu_xa3530_verbs },
10830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10831 .dac_nids = alc883_dac_nids,
10832 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10833 .adc_nids = alc883_adc_nids_rev,
10834 .capsrc_nids = alc883_capsrc_nids_rev,
10835 .dig_out_nid = ALC883_DIGOUT_NID,
10836 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10837 .channel_mode = alc888_4ST_8ch_intel_modes,
10839 ARRAY_SIZE(alc888_2_capture_sources),
10840 .input_mux = alc888_2_capture_sources,
10841 .unsol_event = alc_sku_unsol_event,
10842 .setup = alc888_fujitsu_xa3530_setup,
10843 .init_hook = alc_hp_automute,
10845 [ALC888_LENOVO_SKY] = {
10846 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10847 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10848 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10849 .dac_nids = alc883_dac_nids,
10850 .dig_out_nid = ALC883_DIGOUT_NID,
10851 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10852 .channel_mode = alc883_sixstack_modes,
10854 .input_mux = &alc883_lenovo_sky_capture_source,
10855 .unsol_event = alc_sku_unsol_event,
10856 .setup = alc888_lenovo_sky_setup,
10857 .init_hook = alc_hp_automute,
10859 [ALC888_ASUS_M90V] = {
10860 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10861 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10862 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10863 .dac_nids = alc883_dac_nids,
10864 .dig_out_nid = ALC883_DIGOUT_NID,
10865 .dig_in_nid = ALC883_DIGIN_NID,
10866 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10867 .channel_mode = alc883_3ST_6ch_modes,
10869 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10870 .unsol_event = alc_sku_unsol_event,
10871 .setup = alc883_mode2_setup,
10872 .init_hook = alc_inithook,
10874 [ALC888_ASUS_EEE1601] = {
10875 .mixers = { alc883_asus_eee1601_mixer },
10876 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10877 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10878 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10879 .dac_nids = alc883_dac_nids,
10880 .dig_out_nid = ALC883_DIGOUT_NID,
10881 .dig_in_nid = ALC883_DIGIN_NID,
10882 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10883 .channel_mode = alc883_3ST_2ch_modes,
10885 .input_mux = &alc883_asus_eee1601_capture_source,
10886 .unsol_event = alc_sku_unsol_event,
10887 .init_hook = alc883_eee1601_inithook,
10889 [ALC1200_ASUS_P5Q] = {
10890 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10891 .init_verbs = { alc883_init_verbs },
10892 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10893 .dac_nids = alc883_dac_nids,
10894 .dig_out_nid = ALC1200_DIGOUT_NID,
10895 .dig_in_nid = ALC883_DIGIN_NID,
10896 .slave_dig_outs = alc1200_slave_dig_outs,
10897 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10898 .channel_mode = alc883_sixstack_modes,
10899 .input_mux = &alc883_capture_source,
10902 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10903 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10904 alc880_gpio1_init_verbs },
10905 .adc_nids = alc883_adc_nids,
10906 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10907 .capsrc_nids = alc883_capsrc_nids,
10908 .dac_nids = alc883_dac_nids,
10909 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10910 .channel_mode = alc889A_mb31_6ch_modes,
10911 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10912 .input_mux = &alc889A_mb31_capture_source,
10913 .dig_out_nid = ALC883_DIGOUT_NID,
10914 .unsol_event = alc889A_mb31_unsol_event,
10915 .init_hook = alc889A_mb31_automute,
10917 [ALC883_SONY_VAIO_TT] = {
10918 .mixers = { alc883_vaiott_mixer },
10919 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10920 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10921 .dac_nids = alc883_dac_nids,
10922 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10923 .channel_mode = alc883_3ST_2ch_modes,
10924 .input_mux = &alc883_capture_source,
10925 .unsol_event = alc_sku_unsol_event,
10926 .setup = alc883_vaiott_setup,
10927 .init_hook = alc_hp_automute,
10936 PINFIX_ABIT_AW9D_MAX,
10937 PINFIX_LENOVO_Y530,
10939 PINFIX_ACER_ASPIRE_7736,
10942 static const struct alc_fixup alc882_fixups[] = {
10943 [PINFIX_ABIT_AW9D_MAX] = {
10944 .type = ALC_FIXUP_PINS,
10945 .v.pins = (const struct alc_pincfg[]) {
10946 { 0x15, 0x01080104 }, /* side */
10947 { 0x16, 0x01011012 }, /* rear */
10948 { 0x17, 0x01016011 }, /* clfe */
10952 [PINFIX_LENOVO_Y530] = {
10953 .type = ALC_FIXUP_PINS,
10954 .v.pins = (const struct alc_pincfg[]) {
10955 { 0x15, 0x99130112 }, /* rear int speakers */
10956 { 0x16, 0x99130111 }, /* subwoofer */
10960 [PINFIX_PB_M5210] = {
10961 .type = ALC_FIXUP_VERBS,
10962 .v.verbs = (const struct hda_verb[]) {
10963 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10967 [PINFIX_ACER_ASPIRE_7736] = {
10968 .type = ALC_FIXUP_SKU,
10969 .v.sku = ALC_FIXUP_SKU_IGNORE,
10973 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
10974 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10975 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
10976 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10977 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10982 * BIOS auto configuration
10984 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10985 const struct auto_pin_cfg *cfg)
10987 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10990 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10991 hda_nid_t nid, int pin_type,
10996 /* set as output */
10997 alc_set_pin_output(codec, nid, pin_type);
10999 if (snd_hda_get_conn_list(codec, nid, NULL) < 2)
11004 else if (dac >= 0x02 && dac <= 0x05)
11008 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
11011 #define alc882_auto_init_dac alc880_auto_init_dac
11013 static void alc882_auto_init_multi_out(struct hda_codec *codec)
11015 struct alc_spec *spec = codec->spec;
11018 for (i = 0; i <= HDA_SIDE; i++) {
11019 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11020 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11022 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
11023 spec->multiout.dac_nids[i]);
11026 for (i = 0; i < spec->multiout.num_dacs; i++)
11027 alc882_auto_init_dac(codec, spec->multiout.dac_nids[i]);
11030 static void alc882_auto_init_hp_out(struct hda_codec *codec)
11032 struct alc_spec *spec = codec->spec;
11033 hda_nid_t pin, dac;
11036 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11037 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11038 pin = spec->autocfg.hp_pins[i];
11041 dac = spec->multiout.hp_nid;
11043 dac = spec->multiout.dac_nids[0]; /* to front */
11044 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11048 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11049 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11050 pin = spec->autocfg.speaker_pins[i];
11053 dac = spec->multiout.extra_out_nid[0];
11055 dac = spec->multiout.dac_nids[0]; /* to front */
11056 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11061 alc882_auto_init_dac(codec, spec->multiout.hp_nid);
11062 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
11063 alc882_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
11066 #define alc882_auto_init_analog_input alc880_auto_init_analog_input
11068 static void alc882_auto_init_input_src(struct hda_codec *codec)
11070 struct alc_spec *spec = codec->spec;
11073 for (c = 0; c < spec->num_adc_nids; c++) {
11074 hda_nid_t nid = spec->capsrc_nids[c];
11075 unsigned int mux_idx;
11076 const struct hda_input_mux *imux;
11077 int conns, mute, idx, item;
11080 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11081 AC_VERB_SET_AMP_GAIN_MUTE,
11084 conns = snd_hda_get_conn_list(codec, nid, NULL);
11087 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11088 imux = &spec->input_mux[mux_idx];
11089 if (!imux->num_items && mux_idx > 0)
11090 imux = &spec->input_mux[0];
11091 for (idx = 0; idx < conns; idx++) {
11092 /* if the current connection is the selected one,
11093 * unmute it as default - otherwise mute it
11095 mute = AMP_IN_MUTE(idx);
11096 for (item = 0; item < imux->num_items; item++) {
11097 if (imux->items[item].index == idx) {
11098 if (spec->cur_mux[c] == item)
11099 mute = AMP_IN_UNMUTE(idx);
11103 /* check if we have a selector or mixer
11104 * we could check for the widget type instead, but
11105 * just check for Amp-In presence (in case of mixer
11106 * without amp-in there is something wrong, this
11107 * function shouldn't be used or capsrc nid is wrong)
11109 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
11110 snd_hda_codec_write(codec, nid, 0,
11111 AC_VERB_SET_AMP_GAIN_MUTE,
11113 else if (mute != AMP_IN_MUTE(idx))
11114 snd_hda_codec_write(codec, nid, 0,
11115 AC_VERB_SET_CONNECT_SEL,
11121 /* add mic boosts if needed */
11122 static int alc_auto_add_mic_boost(struct hda_codec *codec)
11124 struct alc_spec *spec = codec->spec;
11125 struct auto_pin_cfg *cfg = &spec->autocfg;
11129 const char *prev_label = NULL;
11131 for (i = 0; i < cfg->num_inputs; i++) {
11132 if (cfg->inputs[i].type > AUTO_PIN_MIC)
11134 nid = cfg->inputs[i].pin;
11135 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
11137 char boost_label[32];
11139 label = hda_get_autocfg_input_label(codec, cfg, i);
11140 if (prev_label && !strcmp(label, prev_label))
11144 prev_label = label;
11146 snprintf(boost_label, sizeof(boost_label),
11147 "%s Boost Volume", label);
11148 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11149 boost_label, type_idx,
11150 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11158 /* almost identical with ALC880 parser... */
11159 static int alc882_parse_auto_config(struct hda_codec *codec)
11161 struct alc_spec *spec = codec->spec;
11162 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11165 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11169 if (!spec->autocfg.line_outs)
11170 return 0; /* can't find valid BIOS pin config */
11172 err = alc880_auto_fill_dac_nids(codec);
11175 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
11178 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
11181 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11185 err = alc880_auto_create_extra_out(spec,
11186 spec->autocfg.speaker_pins[0],
11190 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
11194 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11196 alc_auto_parse_digital(codec);
11198 if (spec->kctls.list)
11199 add_mixer(spec, spec->kctls.list);
11201 /* if ADC 0x07 is available, initialize it, too */
11202 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
11203 add_verb(spec, alc882_adc1_init_verbs);
11205 spec->num_mux_defs = 1;
11206 spec->input_mux = &spec->private_imux[0];
11208 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11210 err = alc_auto_add_mic_boost(codec);
11214 return 1; /* config found */
11217 /* additional initialization for auto-configuration model */
11218 static void alc882_auto_init(struct hda_codec *codec)
11220 struct alc_spec *spec = codec->spec;
11221 alc882_auto_init_multi_out(codec);
11222 alc882_auto_init_hp_out(codec);
11223 alc882_auto_init_analog_input(codec);
11224 alc882_auto_init_input_src(codec);
11225 alc_auto_init_digital(codec);
11226 if (spec->unsol_event)
11227 alc_inithook(codec);
11230 static int patch_alc882(struct hda_codec *codec)
11232 struct alc_spec *spec;
11233 int err, board_config;
11235 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11239 codec->spec = spec;
11241 spec->mixer_nid = 0x0b;
11243 switch (codec->vendor_id) {
11248 /* ALC883 and variants */
11249 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11253 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11257 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11258 board_config = snd_hda_check_board_codec_sid_config(codec,
11259 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11261 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11262 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11264 board_config = ALC882_AUTO;
11267 if (board_config == ALC882_AUTO) {
11268 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11269 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11272 alc_auto_parse_customize_define(codec);
11274 if (board_config == ALC882_AUTO) {
11275 /* automatic parse from the BIOS config */
11276 err = alc882_parse_auto_config(codec);
11282 "hda_codec: Cannot set up configuration "
11283 "from BIOS. Using base mode...\n");
11284 board_config = ALC882_3ST_DIG;
11288 if (has_cdefine_beep(codec)) {
11289 err = snd_hda_attach_beep_device(codec, 0x1);
11296 if (board_config != ALC882_AUTO)
11297 setup_preset(codec, &alc882_presets[board_config]);
11299 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11300 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11301 /* FIXME: setup DAC5 */
11302 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11303 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11305 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11306 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11308 if (!spec->adc_nids && spec->input_mux) {
11310 spec->num_adc_nids = 0;
11311 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11312 const struct hda_input_mux *imux = spec->input_mux;
11314 hda_nid_t nid = alc882_adc_nids[i];
11315 unsigned int wcap = get_wcaps(codec, nid);
11317 wcap = get_wcaps_type(wcap);
11318 if (wcap != AC_WID_AUD_IN)
11320 spec->private_adc_nids[spec->num_adc_nids] = nid;
11321 err = snd_hda_get_connections(codec, nid, &cap, 1);
11324 err = snd_hda_get_conn_list(codec, cap, NULL);
11327 for (j = 0; j < imux->num_items; j++)
11328 if (imux->items[j].index >= err)
11330 if (j < imux->num_items)
11332 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11333 spec->num_adc_nids++;
11335 spec->adc_nids = spec->private_adc_nids;
11336 spec->capsrc_nids = spec->private_capsrc_nids;
11339 set_capture_mixer(codec);
11341 if (has_cdefine_beep(codec))
11342 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11344 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11346 spec->vmaster_nid = 0x0c;
11348 codec->patch_ops = alc_patch_ops;
11349 if (board_config == ALC882_AUTO)
11350 spec->init_hook = alc882_auto_init;
11352 alc_init_jacks(codec);
11353 #ifdef CONFIG_SND_HDA_POWER_SAVE
11354 if (!spec->loopback.amplist)
11355 spec->loopback.amplist = alc882_loopbacks;
11366 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11367 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
11369 #define alc262_dac_nids alc260_dac_nids
11370 #define alc262_adc_nids alc882_adc_nids
11371 #define alc262_adc_nids_alt alc882_adc_nids_alt
11372 #define alc262_capsrc_nids alc882_capsrc_nids
11373 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11375 #define alc262_modes alc260_modes
11376 #define alc262_capture_source alc882_capture_source
11378 static const hda_nid_t alc262_dmic_adc_nids[1] = {
11383 static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11385 static const struct snd_kcontrol_new alc262_base_mixer[] = {
11386 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11387 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11388 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11389 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11390 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11391 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11394 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11395 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11396 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11397 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11398 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11400 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11401 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11405 /* update HP, line and mono-out pins according to the master switch */
11406 #define alc262_hp_master_update alc260_hp_master_update
11408 static void alc262_hp_bpc_setup(struct hda_codec *codec)
11410 struct alc_spec *spec = codec->spec;
11412 spec->autocfg.hp_pins[0] = 0x1b;
11413 spec->autocfg.speaker_pins[0] = 0x16;
11414 spec->automute = 1;
11415 spec->automute_mode = ALC_AUTOMUTE_PIN;
11418 static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11420 struct alc_spec *spec = codec->spec;
11422 spec->autocfg.hp_pins[0] = 0x15;
11423 spec->autocfg.speaker_pins[0] = 0x16;
11424 spec->automute = 1;
11425 spec->automute_mode = ALC_AUTOMUTE_PIN;
11428 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11429 #define alc262_hp_master_sw_put alc260_hp_master_sw_put
11431 #define ALC262_HP_MASTER_SWITCH \
11433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11434 .name = "Master Playback Switch", \
11435 .info = snd_ctl_boolean_mono_info, \
11436 .get = alc262_hp_master_sw_get, \
11437 .put = alc262_hp_master_sw_put, \
11440 .iface = NID_MAPPING, \
11441 .name = "Master Playback Switch", \
11442 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11446 static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11447 ALC262_HP_MASTER_SWITCH,
11448 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11449 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11451 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11453 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11455 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11456 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11457 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11458 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11460 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11461 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11462 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11463 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11464 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11465 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11466 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11470 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11471 ALC262_HP_MASTER_SWITCH,
11472 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11473 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11474 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11476 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11478 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11480 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11481 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11482 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11483 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11484 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11485 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11486 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11490 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11491 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11492 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11493 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11497 /* mute/unmute internal speaker according to the hp jack and mute state */
11498 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11500 struct alc_spec *spec = codec->spec;
11502 spec->autocfg.hp_pins[0] = 0x15;
11503 spec->autocfg.speaker_pins[0] = 0x14;
11504 spec->automute = 1;
11505 spec->automute_mode = ALC_AUTOMUTE_PIN;
11508 static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11509 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11510 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11511 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11515 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11519 static const struct hda_verb alc262_hp_t5735_verbs[] = {
11520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11523 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11527 static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11528 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11529 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11530 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11531 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11537 static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11538 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11539 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11540 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11541 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11542 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11543 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11547 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11551 static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11558 /* bind hp and internal speaker mute (with plug check) as master switch */
11559 #define alc262_hippo_master_update alc262_hp_master_update
11560 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11561 #define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11563 #define ALC262_HIPPO_MASTER_SWITCH \
11565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11566 .name = "Master Playback Switch", \
11567 .info = snd_ctl_boolean_mono_info, \
11568 .get = alc262_hippo_master_sw_get, \
11569 .put = alc262_hippo_master_sw_put, \
11572 .iface = NID_MAPPING, \
11573 .name = "Master Playback Switch", \
11574 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11575 (SUBDEV_SPEAKER(0) << 16), \
11578 static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11579 ALC262_HIPPO_MASTER_SWITCH,
11580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11581 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11582 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11584 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11587 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11588 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11589 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11590 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11591 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11595 static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11596 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11597 ALC262_HIPPO_MASTER_SWITCH,
11598 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11599 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11600 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11601 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11602 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11604 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11607 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11611 /* mute/unmute internal speaker according to the hp jack and mute state */
11612 static void alc262_hippo_setup(struct hda_codec *codec)
11614 struct alc_spec *spec = codec->spec;
11616 spec->autocfg.hp_pins[0] = 0x15;
11617 spec->autocfg.speaker_pins[0] = 0x14;
11618 spec->automute = 1;
11619 spec->automute_mode = ALC_AUTOMUTE_AMP;
11622 static void alc262_hippo1_setup(struct hda_codec *codec)
11624 struct alc_spec *spec = codec->spec;
11626 spec->autocfg.hp_pins[0] = 0x1b;
11627 spec->autocfg.speaker_pins[0] = 0x14;
11628 spec->automute = 1;
11629 spec->automute_mode = ALC_AUTOMUTE_AMP;
11633 static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11634 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11635 ALC262_HIPPO_MASTER_SWITCH,
11636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11638 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11639 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11643 static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11644 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11645 ALC262_HIPPO_MASTER_SWITCH,
11646 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11649 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11650 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11654 static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11655 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11656 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11657 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11658 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11660 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11663 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11664 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11665 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11666 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11670 static const struct hda_verb alc262_tyan_verbs[] = {
11671 /* Headphone automute */
11672 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11674 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11676 /* P11 AUX_IN, white 4-pin connector */
11677 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11678 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11679 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11680 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11685 /* unsolicited event for HP jack sensing */
11686 static void alc262_tyan_setup(struct hda_codec *codec)
11688 struct alc_spec *spec = codec->spec;
11690 spec->autocfg.hp_pins[0] = 0x1b;
11691 spec->autocfg.speaker_pins[0] = 0x15;
11692 spec->automute = 1;
11693 spec->automute_mode = ALC_AUTOMUTE_AMP;
11697 #define alc262_capture_mixer alc882_capture_mixer
11698 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11701 * generic initialization of ADC, input mixers and output mixers
11703 static const struct hda_verb alc262_init_verbs[] = {
11705 * Unmute ADC0-2 and set the default input to mic-in
11707 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11709 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11710 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11711 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11712 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11714 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11716 * Note: PASD motherboards uses the Line In 2 as the input for
11717 * front panel mic (mic 2)
11719 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11727 * Set up output mixers (0x0c - 0x0e)
11729 /* set vol=0 to output mixers */
11730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11733 /* set up input amps for analog loopback */
11734 /* Amp Indices: DAC = 0, mixer = 1 */
11735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11737 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11738 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11739 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11740 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11744 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11746 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11747 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11752 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11755 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11756 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11758 /* FIXME: use matrix-type input source selection */
11759 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11760 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11768 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11769 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11779 static const struct hda_verb alc262_eapd_verbs[] = {
11780 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11781 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11785 static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11786 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11787 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11790 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11791 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11795 static const struct hda_verb alc262_sony_unsol_verbs[] = {
11796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11797 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11798 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11800 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11805 static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11806 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11807 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11808 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11814 static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11815 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11816 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11818 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11819 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11821 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11822 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11826 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11828 struct alc_spec *spec = codec->spec;
11830 spec->autocfg.hp_pins[0] = 0x15;
11831 spec->autocfg.speaker_pins[0] = 0x14;
11832 spec->ext_mic.pin = 0x18;
11833 spec->ext_mic.mux_idx = 0;
11834 spec->int_mic.pin = 0x12;
11835 spec->int_mic.mux_idx = 9;
11836 spec->auto_mic = 1;
11837 spec->automute = 1;
11838 spec->automute_mode = ALC_AUTOMUTE_PIN;
11844 * 0x16 = internal speaker
11845 * 0x18 = external mic
11848 static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11849 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11850 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11854 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11856 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11857 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11861 static const struct hda_verb alc262_nec_verbs[] = {
11862 /* Unmute Speaker */
11863 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11866 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11869 /* External mic to headphone */
11870 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11871 /* External mic to speaker */
11872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11878 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11879 * 0x1b = port replicator headphone out
11882 #define ALC_HP_EVENT ALC880_HP_EVENT
11884 static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11885 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11886 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11887 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11888 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11892 static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11893 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11894 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11898 static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11899 /* Front Mic pin: input vref at 50% */
11900 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11901 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11905 static const struct hda_input_mux alc262_fujitsu_capture_source = {
11909 { "Internal Mic", 0x1 },
11914 static const struct hda_input_mux alc262_HP_capture_source = {
11918 { "Front Mic", 0x1 },
11925 static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11929 { "Front Mic", 0x2 },
11935 static void alc262_fujitsu_setup(struct hda_codec *codec)
11937 struct alc_spec *spec = codec->spec;
11939 spec->autocfg.hp_pins[0] = 0x14;
11940 spec->autocfg.hp_pins[1] = 0x1b;
11941 spec->autocfg.speaker_pins[0] = 0x15;
11942 spec->automute = 1;
11943 spec->automute_mode = ALC_AUTOMUTE_AMP;
11946 /* bind volumes of both NID 0x0c and 0x0d */
11947 static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11948 .ops = &snd_hda_bind_vol,
11950 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11951 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11956 static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11957 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11959 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11960 .name = "Master Playback Switch",
11961 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11962 .info = snd_ctl_boolean_mono_info,
11963 .get = alc262_hp_master_sw_get,
11964 .put = alc262_hp_master_sw_put,
11967 .iface = NID_MAPPING,
11968 .name = "Master Playback Switch",
11969 .private_value = 0x1b,
11971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11973 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11976 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11977 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11978 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11982 static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11984 struct alc_spec *spec = codec->spec;
11986 spec->autocfg.hp_pins[0] = 0x1b;
11987 spec->autocfg.speaker_pins[0] = 0x14;
11988 spec->autocfg.speaker_pins[1] = 0x16;
11989 spec->automute = 1;
11990 spec->automute_mode = ALC_AUTOMUTE_AMP;
11993 static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11994 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11996 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11997 .name = "Master Playback Switch",
11998 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11999 .info = snd_ctl_boolean_mono_info,
12000 .get = alc262_hp_master_sw_get,
12001 .put = alc262_hp_master_sw_put,
12003 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12004 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12005 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12008 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12009 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12010 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12014 static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
12015 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12016 ALC262_HIPPO_MASTER_SWITCH,
12017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12019 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12022 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12026 /* additional init verbs for Benq laptops */
12027 static const struct hda_verb alc262_EAPD_verbs[] = {
12028 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12029 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12033 static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12035 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12037 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12038 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12042 /* Samsung Q1 Ultra Vista model setup */
12043 static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
12044 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12045 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12047 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12048 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12049 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12053 static const struct hda_verb alc262_ultra_verbs[] = {
12055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12056 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12057 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12061 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12062 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12067 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12068 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12070 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12071 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12072 /* ADC, choose mic */
12073 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12081 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12082 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12086 /* mute/unmute internal speaker according to the hp jack and mute state */
12087 static void alc262_ultra_automute(struct hda_codec *codec)
12089 struct alc_spec *spec = codec->spec;
12093 /* auto-mute only when HP is used as HP */
12094 if (!spec->cur_mux[0]) {
12095 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12096 if (spec->jack_present)
12097 mute = HDA_AMP_MUTE;
12099 /* mute/unmute internal speaker */
12100 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12101 HDA_AMP_MUTE, mute);
12102 /* mute/unmute HP */
12103 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12104 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12107 /* unsolicited event for HP jack sensing */
12108 static void alc262_ultra_unsol_event(struct hda_codec *codec,
12111 if ((res >> 26) != ALC880_HP_EVENT)
12113 alc262_ultra_automute(codec);
12116 static const struct hda_input_mux alc262_ultra_capture_source = {
12120 { "Headphone", 0x7 },
12124 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12125 struct snd_ctl_elem_value *ucontrol)
12127 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12128 struct alc_spec *spec = codec->spec;
12131 ret = alc_mux_enum_put(kcontrol, ucontrol);
12134 /* reprogram the HP pin as mic or HP according to the input source */
12135 snd_hda_codec_write_cache(codec, 0x15, 0,
12136 AC_VERB_SET_PIN_WIDGET_CONTROL,
12137 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12138 alc262_ultra_automute(codec); /* mute/unmute HP */
12142 static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12143 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12144 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12147 .name = "Capture Source",
12148 .info = alc_mux_enum_info,
12149 .get = alc_mux_enum_get,
12150 .put = alc262_ultra_mux_enum_put,
12153 .iface = NID_MAPPING,
12154 .name = "Capture Source",
12155 .private_value = 0x15,
12160 /* We use two mixers depending on the output pin; 0x16 is a mono output
12161 * and thus it's bound with a different mixer.
12162 * This function returns which mixer amp should be used.
12164 static int alc262_check_volbit(hda_nid_t nid)
12168 else if (nid == 0x16)
12174 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12175 const char *pfx, int *vbits, int idx)
12180 vbit = alc262_check_volbit(nid);
12183 if (*vbits & vbit) /* a volume control for this mixer already there */
12187 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12189 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12190 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12193 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12194 const char *pfx, int idx)
12201 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12203 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12204 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12207 /* add playback controls from the parsed DAC table */
12208 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12209 const struct auto_pin_cfg *cfg)
12215 spec->multiout.num_dacs = 1; /* only use one dac */
12216 spec->multiout.dac_nids = spec->private_dac_nids;
12217 spec->private_dac_nids[0] = 2;
12219 for (i = 0; i < 2; i++) {
12220 pfx = alc_get_line_out_pfx(spec, i, true, &index);
12223 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
12227 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12228 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12233 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12234 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12241 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12242 alc262_check_volbit(cfg->speaker_pins[0]) |
12243 alc262_check_volbit(cfg->hp_pins[0]);
12245 for (i = 0; i < 2; i++) {
12246 pfx = alc_get_line_out_pfx(spec, i, true, &index);
12249 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12253 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12254 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12255 "Speaker", &vbits, i);
12259 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12260 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12261 "Headphone", &vbits, i);
12269 #define alc262_auto_create_input_ctls \
12270 alc882_auto_create_input_ctls
12272 static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12274 * Unmute ADC0-2 and set the default input to mic-in
12276 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12278 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12279 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12280 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12281 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12283 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12285 * Note: PASD motherboards uses the Line In 2 as the input for
12286 * front panel mic (mic 2)
12288 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12291 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12292 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12293 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12294 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12295 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12298 * Set up output mixers (0x0c - 0x0e)
12300 /* set vol=0 to output mixers */
12301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12302 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12303 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12305 /* set up input amps for analog loopback */
12306 /* Amp Indices: DAC = 0, mixer = 1 */
12307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12308 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12309 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12310 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12311 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12312 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12314 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12315 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12316 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12318 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12319 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12321 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12322 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12324 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12325 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12326 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12327 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12328 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12330 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12331 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12332 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12333 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12334 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12335 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12338 /* FIXME: use matrix-type input source selection */
12339 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12340 /* Input mixer1: only unmute Mic */
12341 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12342 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12343 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12345 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12349 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12351 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12354 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12355 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12356 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12359 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12363 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12364 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12365 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12366 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12368 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12369 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12371 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12376 static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12378 * Unmute ADC0-2 and set the default input to mic-in
12380 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12381 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12382 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12384 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12385 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12387 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12389 * Note: PASD motherboards uses the Line In 2 as the input for front
12390 * panel mic (mic 2)
12392 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12393 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12394 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12395 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12402 * Set up output mixers (0x0c - 0x0e)
12404 /* set vol=0 to output mixers */
12405 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12406 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12407 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12409 /* set up input amps for analog loopback */
12410 /* Amp Indices: DAC = 0, mixer = 1 */
12411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12413 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12414 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12415 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12416 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12419 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12420 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12421 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12422 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12423 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12424 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12425 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12427 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12428 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12430 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12431 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12433 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12434 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12435 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12437 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12438 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12440 /* FIXME: use matrix-type input source selection */
12441 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12442 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12448 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12456 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12457 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12462 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12464 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12467 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12472 static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12475 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12476 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12478 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12479 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12481 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12483 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12484 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12485 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12497 static const struct alc_fixup alc262_fixups[] = {
12498 [PINFIX_FSC_H270] = {
12499 .type = ALC_FIXUP_PINS,
12500 .v.pins = (const struct alc_pincfg[]) {
12501 { 0x14, 0x99130110 }, /* speaker */
12502 { 0x15, 0x0221142f }, /* front HP */
12503 { 0x1b, 0x0121141f }, /* rear HP */
12507 [PINFIX_HP_Z200] = {
12508 .type = ALC_FIXUP_PINS,
12509 .v.pins = (const struct alc_pincfg[]) {
12510 { 0x16, 0x99130120 }, /* internal speaker */
12516 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12517 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12518 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12523 #ifdef CONFIG_SND_HDA_POWER_SAVE
12524 #define alc262_loopbacks alc880_loopbacks
12527 /* pcm configuration: identical with ALC880 */
12528 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12529 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12530 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12531 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12534 * BIOS auto configuration
12536 static int alc262_parse_auto_config(struct hda_codec *codec)
12538 struct alc_spec *spec = codec->spec;
12540 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12542 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12546 if (!spec->autocfg.line_outs) {
12547 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12548 spec->multiout.max_channels = 2;
12549 spec->no_analog = 1;
12552 return 0; /* can't find valid BIOS pin config */
12554 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12557 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12561 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12564 alc_auto_parse_digital(codec);
12566 if (spec->kctls.list)
12567 add_mixer(spec, spec->kctls.list);
12569 spec->num_mux_defs = 1;
12570 spec->input_mux = &spec->private_imux[0];
12572 err = alc_auto_add_mic_boost(codec);
12576 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12581 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12582 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12583 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12584 #define alc262_auto_init_input_src alc882_auto_init_input_src
12587 /* init callback for auto-configuration model -- overriding the default init */
12588 static void alc262_auto_init(struct hda_codec *codec)
12590 struct alc_spec *spec = codec->spec;
12591 alc262_auto_init_multi_out(codec);
12592 alc262_auto_init_hp_out(codec);
12593 alc262_auto_init_analog_input(codec);
12594 alc262_auto_init_input_src(codec);
12595 alc_auto_init_digital(codec);
12596 if (spec->unsol_event)
12597 alc_inithook(codec);
12601 * configuration and preset
12603 static const char * const alc262_models[ALC262_MODEL_LAST] = {
12604 [ALC262_BASIC] = "basic",
12605 [ALC262_HIPPO] = "hippo",
12606 [ALC262_HIPPO_1] = "hippo_1",
12607 [ALC262_FUJITSU] = "fujitsu",
12608 [ALC262_HP_BPC] = "hp-bpc",
12609 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12610 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12611 [ALC262_HP_RP5700] = "hp-rp5700",
12612 [ALC262_BENQ_ED8] = "benq",
12613 [ALC262_BENQ_T31] = "benq-t31",
12614 [ALC262_SONY_ASSAMD] = "sony-assamd",
12615 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12616 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12617 [ALC262_ULTRA] = "ultra",
12618 [ALC262_LENOVO_3000] = "lenovo-3000",
12619 [ALC262_NEC] = "nec",
12620 [ALC262_TYAN] = "tyan",
12621 [ALC262_AUTO] = "auto",
12624 static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12625 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12626 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12627 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12629 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12631 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12633 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12635 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12637 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12638 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12639 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12640 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12641 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12642 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12643 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12644 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12645 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12646 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12647 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12648 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12649 ALC262_HP_TC_T5735),
12650 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12651 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12652 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12653 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12654 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12655 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12656 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12657 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12658 #if 0 /* disable the quirk since model=auto works better in recent versions */
12659 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12660 ALC262_SONY_ASSAMD),
12662 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12663 ALC262_TOSHIBA_RX1),
12664 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12665 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12666 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12667 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12668 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12670 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12671 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12672 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12673 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12674 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12678 static const struct alc_config_preset alc262_presets[] = {
12680 .mixers = { alc262_base_mixer },
12681 .init_verbs = { alc262_init_verbs },
12682 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12683 .dac_nids = alc262_dac_nids,
12685 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12686 .channel_mode = alc262_modes,
12687 .input_mux = &alc262_capture_source,
12690 .mixers = { alc262_hippo_mixer },
12691 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12692 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12693 .dac_nids = alc262_dac_nids,
12695 .dig_out_nid = ALC262_DIGOUT_NID,
12696 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12697 .channel_mode = alc262_modes,
12698 .input_mux = &alc262_capture_source,
12699 .unsol_event = alc_sku_unsol_event,
12700 .setup = alc262_hippo_setup,
12701 .init_hook = alc_inithook,
12703 [ALC262_HIPPO_1] = {
12704 .mixers = { alc262_hippo1_mixer },
12705 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12706 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12707 .dac_nids = alc262_dac_nids,
12709 .dig_out_nid = ALC262_DIGOUT_NID,
12710 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12711 .channel_mode = alc262_modes,
12712 .input_mux = &alc262_capture_source,
12713 .unsol_event = alc_sku_unsol_event,
12714 .setup = alc262_hippo1_setup,
12715 .init_hook = alc_inithook,
12717 [ALC262_FUJITSU] = {
12718 .mixers = { alc262_fujitsu_mixer },
12719 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12720 alc262_fujitsu_unsol_verbs },
12721 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12722 .dac_nids = alc262_dac_nids,
12724 .dig_out_nid = ALC262_DIGOUT_NID,
12725 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12726 .channel_mode = alc262_modes,
12727 .input_mux = &alc262_fujitsu_capture_source,
12728 .unsol_event = alc_sku_unsol_event,
12729 .setup = alc262_fujitsu_setup,
12730 .init_hook = alc_inithook,
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 = alc_sku_unsol_event,
12742 .setup = alc262_hp_bpc_setup,
12743 .init_hook = alc_inithook,
12745 [ALC262_HP_BPC_D7000_WF] = {
12746 .mixers = { alc262_HP_BPC_WildWest_mixer },
12747 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12748 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12749 .dac_nids = alc262_dac_nids,
12751 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12752 .channel_mode = alc262_modes,
12753 .input_mux = &alc262_HP_D7000_capture_source,
12754 .unsol_event = alc_sku_unsol_event,
12755 .setup = alc262_hp_wildwest_setup,
12756 .init_hook = alc_inithook,
12758 [ALC262_HP_BPC_D7000_WL] = {
12759 .mixers = { alc262_HP_BPC_WildWest_mixer,
12760 alc262_HP_BPC_WildWest_option_mixer },
12761 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12762 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12763 .dac_nids = alc262_dac_nids,
12765 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12766 .channel_mode = alc262_modes,
12767 .input_mux = &alc262_HP_D7000_capture_source,
12768 .unsol_event = alc_sku_unsol_event,
12769 .setup = alc262_hp_wildwest_setup,
12770 .init_hook = alc_inithook,
12772 [ALC262_HP_TC_T5735] = {
12773 .mixers = { alc262_hp_t5735_mixer },
12774 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12775 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12776 .dac_nids = alc262_dac_nids,
12778 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12779 .channel_mode = alc262_modes,
12780 .input_mux = &alc262_capture_source,
12781 .unsol_event = alc_sku_unsol_event,
12782 .setup = alc262_hp_t5735_setup,
12783 .init_hook = alc_inithook,
12785 [ALC262_HP_RP5700] = {
12786 .mixers = { alc262_hp_rp5700_mixer },
12787 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12788 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12789 .dac_nids = alc262_dac_nids,
12790 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12791 .channel_mode = alc262_modes,
12792 .input_mux = &alc262_hp_rp5700_capture_source,
12794 [ALC262_BENQ_ED8] = {
12795 .mixers = { alc262_base_mixer },
12796 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12797 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12798 .dac_nids = alc262_dac_nids,
12800 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12801 .channel_mode = alc262_modes,
12802 .input_mux = &alc262_capture_source,
12804 [ALC262_SONY_ASSAMD] = {
12805 .mixers = { alc262_sony_mixer },
12806 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12807 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12808 .dac_nids = alc262_dac_nids,
12810 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12811 .channel_mode = alc262_modes,
12812 .input_mux = &alc262_capture_source,
12813 .unsol_event = alc_sku_unsol_event,
12814 .setup = alc262_hippo_setup,
12815 .init_hook = alc_inithook,
12817 [ALC262_BENQ_T31] = {
12818 .mixers = { alc262_benq_t31_mixer },
12819 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12820 alc_hp15_unsol_verbs },
12821 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12822 .dac_nids = alc262_dac_nids,
12824 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12825 .channel_mode = alc262_modes,
12826 .input_mux = &alc262_capture_source,
12827 .unsol_event = alc_sku_unsol_event,
12828 .setup = alc262_hippo_setup,
12829 .init_hook = alc_inithook,
12832 .mixers = { alc262_ultra_mixer },
12833 .cap_mixer = alc262_ultra_capture_mixer,
12834 .init_verbs = { alc262_ultra_verbs },
12835 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12836 .dac_nids = alc262_dac_nids,
12837 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12838 .channel_mode = alc262_modes,
12839 .input_mux = &alc262_ultra_capture_source,
12840 .adc_nids = alc262_adc_nids, /* ADC0 */
12841 .capsrc_nids = alc262_capsrc_nids,
12842 .num_adc_nids = 1, /* single ADC */
12843 .unsol_event = alc262_ultra_unsol_event,
12844 .init_hook = alc262_ultra_automute,
12846 [ALC262_LENOVO_3000] = {
12847 .mixers = { alc262_lenovo_3000_mixer },
12848 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12849 alc262_lenovo_3000_unsol_verbs,
12850 alc262_lenovo_3000_init_verbs },
12851 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12852 .dac_nids = alc262_dac_nids,
12854 .dig_out_nid = ALC262_DIGOUT_NID,
12855 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12856 .channel_mode = alc262_modes,
12857 .input_mux = &alc262_fujitsu_capture_source,
12858 .unsol_event = alc_sku_unsol_event,
12859 .setup = alc262_lenovo_3000_setup,
12860 .init_hook = alc_inithook,
12863 .mixers = { alc262_nec_mixer },
12864 .init_verbs = { alc262_nec_verbs },
12865 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12866 .dac_nids = alc262_dac_nids,
12868 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12869 .channel_mode = alc262_modes,
12870 .input_mux = &alc262_capture_source,
12872 [ALC262_TOSHIBA_S06] = {
12873 .mixers = { alc262_toshiba_s06_mixer },
12874 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12875 alc262_eapd_verbs },
12876 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12877 .capsrc_nids = alc262_dmic_capsrc_nids,
12878 .dac_nids = alc262_dac_nids,
12879 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12880 .num_adc_nids = 1, /* single ADC */
12881 .dig_out_nid = ALC262_DIGOUT_NID,
12882 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12883 .channel_mode = alc262_modes,
12884 .unsol_event = alc_sku_unsol_event,
12885 .setup = alc262_toshiba_s06_setup,
12886 .init_hook = alc_inithook,
12888 [ALC262_TOSHIBA_RX1] = {
12889 .mixers = { alc262_toshiba_rx1_mixer },
12890 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12891 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12892 .dac_nids = alc262_dac_nids,
12894 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12895 .channel_mode = alc262_modes,
12896 .input_mux = &alc262_capture_source,
12897 .unsol_event = alc_sku_unsol_event,
12898 .setup = alc262_hippo_setup,
12899 .init_hook = alc_inithook,
12902 .mixers = { alc262_tyan_mixer },
12903 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12904 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12905 .dac_nids = alc262_dac_nids,
12907 .dig_out_nid = ALC262_DIGOUT_NID,
12908 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12909 .channel_mode = alc262_modes,
12910 .input_mux = &alc262_capture_source,
12911 .unsol_event = alc_sku_unsol_event,
12912 .setup = alc262_tyan_setup,
12913 .init_hook = alc_hp_automute,
12917 static int patch_alc262(struct hda_codec *codec)
12919 struct alc_spec *spec;
12923 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12927 codec->spec = spec;
12929 spec->mixer_nid = 0x0b;
12932 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12937 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12938 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12939 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12940 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12943 alc_auto_parse_customize_define(codec);
12945 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12947 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12951 if (board_config < 0) {
12952 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12954 board_config = ALC262_AUTO;
12957 if (board_config == ALC262_AUTO) {
12958 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12959 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12962 if (board_config == ALC262_AUTO) {
12963 /* automatic parse from the BIOS config */
12964 err = alc262_parse_auto_config(codec);
12970 "hda_codec: Cannot set up configuration "
12971 "from BIOS. Using base mode...\n");
12972 board_config = ALC262_BASIC;
12976 if (!spec->no_analog && has_cdefine_beep(codec)) {
12977 err = snd_hda_attach_beep_device(codec, 0x1);
12984 if (board_config != ALC262_AUTO)
12985 setup_preset(codec, &alc262_presets[board_config]);
12987 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12988 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12990 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12991 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12993 if (!spec->adc_nids && spec->input_mux) {
12995 /* check whether the digital-mic has to be supported */
12996 for (i = 0; i < spec->input_mux->num_items; i++) {
12997 if (spec->input_mux->items[i].index >= 9)
13000 if (i < spec->input_mux->num_items) {
13001 /* use only ADC0 */
13002 spec->adc_nids = alc262_dmic_adc_nids;
13003 spec->num_adc_nids = 1;
13004 spec->capsrc_nids = alc262_dmic_capsrc_nids;
13006 /* all analog inputs */
13007 /* check whether NID 0x07 is valid */
13008 unsigned int wcap = get_wcaps(codec, 0x07);
13011 wcap = get_wcaps_type(wcap);
13012 if (wcap != AC_WID_AUD_IN) {
13013 spec->adc_nids = alc262_adc_nids_alt;
13014 spec->num_adc_nids =
13015 ARRAY_SIZE(alc262_adc_nids_alt);
13016 spec->capsrc_nids = alc262_capsrc_nids_alt;
13018 spec->adc_nids = alc262_adc_nids;
13019 spec->num_adc_nids =
13020 ARRAY_SIZE(alc262_adc_nids);
13021 spec->capsrc_nids = alc262_capsrc_nids;
13025 if (!spec->cap_mixer && !spec->no_analog)
13026 set_capture_mixer(codec);
13027 if (!spec->no_analog && has_cdefine_beep(codec))
13028 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13030 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13032 spec->vmaster_nid = 0x0c;
13034 codec->patch_ops = alc_patch_ops;
13035 if (board_config == ALC262_AUTO)
13036 spec->init_hook = alc262_auto_init;
13037 spec->shutup = alc_eapd_shutup;
13039 alc_init_jacks(codec);
13040 #ifdef CONFIG_SND_HDA_POWER_SAVE
13041 if (!spec->loopback.amplist)
13042 spec->loopback.amplist = alc262_loopbacks;
13049 * ALC268 channel source setting (2 channel)
13051 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13052 #define alc268_modes alc260_modes
13054 static const hda_nid_t alc268_dac_nids[2] = {
13059 static const hda_nid_t alc268_adc_nids[2] = {
13064 static const hda_nid_t alc268_adc_nids_alt[1] = {
13069 static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13071 static const struct snd_kcontrol_new alc268_base_mixer[] = {
13072 /* output mixer control */
13073 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13074 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13075 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13076 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13077 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13078 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13079 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13083 static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13084 /* output mixer control */
13085 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13086 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13087 ALC262_HIPPO_MASTER_SWITCH,
13088 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13089 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13090 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13094 /* bind Beep switches of both NID 0x0f and 0x10 */
13095 static const struct hda_bind_ctls alc268_bind_beep_sw = {
13096 .ops = &snd_hda_bind_sw,
13098 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13099 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13104 static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13105 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13106 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13110 static const struct hda_verb alc268_eapd_verbs[] = {
13111 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13112 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13116 /* Toshiba specific */
13117 static const struct hda_verb alc268_toshiba_verbs[] = {
13118 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13122 /* Acer specific */
13123 /* bind volumes of both NID 0x02 and 0x03 */
13124 static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13125 .ops = &snd_hda_bind_vol,
13127 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13128 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13133 static void alc268_acer_setup(struct hda_codec *codec)
13135 struct alc_spec *spec = codec->spec;
13137 spec->autocfg.hp_pins[0] = 0x14;
13138 spec->autocfg.speaker_pins[0] = 0x15;
13139 spec->automute = 1;
13140 spec->automute_mode = ALC_AUTOMUTE_AMP;
13143 #define alc268_acer_master_sw_get alc262_hp_master_sw_get
13144 #define alc268_acer_master_sw_put alc262_hp_master_sw_put
13146 static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13147 /* output mixer control */
13148 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13150 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13151 .name = "Master Playback Switch",
13152 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13153 .info = snd_ctl_boolean_mono_info,
13154 .get = alc268_acer_master_sw_get,
13155 .put = alc268_acer_master_sw_put,
13157 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13161 static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13162 /* output mixer control */
13163 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13165 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13166 .name = "Master Playback Switch",
13167 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13168 .info = snd_ctl_boolean_mono_info,
13169 .get = alc268_acer_master_sw_get,
13170 .put = alc268_acer_master_sw_put,
13172 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13174 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13178 static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13179 /* output mixer control */
13180 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13183 .name = "Master Playback Switch",
13184 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13185 .info = snd_ctl_boolean_mono_info,
13186 .get = alc268_acer_master_sw_get,
13187 .put = alc268_acer_master_sw_put,
13189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13190 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13194 static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13195 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13196 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13197 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13198 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13199 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13200 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13204 static const struct hda_verb alc268_acer_verbs[] = {
13205 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13206 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13207 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13209 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13210 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13211 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13215 /* unsolicited event for HP jack sensing */
13216 #define alc268_toshiba_setup alc262_hippo_setup
13218 static void alc268_acer_lc_setup(struct hda_codec *codec)
13220 struct alc_spec *spec = codec->spec;
13221 spec->autocfg.hp_pins[0] = 0x15;
13222 spec->autocfg.speaker_pins[0] = 0x14;
13223 spec->automute = 1;
13224 spec->automute_mode = ALC_AUTOMUTE_AMP;
13225 spec->ext_mic.pin = 0x18;
13226 spec->ext_mic.mux_idx = 0;
13227 spec->int_mic.pin = 0x12;
13228 spec->int_mic.mux_idx = 6;
13229 spec->auto_mic = 1;
13232 static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13233 /* output mixer control */
13234 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13235 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13236 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13238 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13239 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13243 static const struct hda_verb alc268_dell_verbs[] = {
13244 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13245 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13246 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13247 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13251 /* mute/unmute internal speaker according to the hp jack and mute state */
13252 static void alc268_dell_setup(struct hda_codec *codec)
13254 struct alc_spec *spec = codec->spec;
13256 spec->autocfg.hp_pins[0] = 0x15;
13257 spec->autocfg.speaker_pins[0] = 0x14;
13258 spec->ext_mic.pin = 0x18;
13259 spec->ext_mic.mux_idx = 0;
13260 spec->int_mic.pin = 0x19;
13261 spec->int_mic.mux_idx = 1;
13262 spec->auto_mic = 1;
13263 spec->automute = 1;
13264 spec->automute_mode = ALC_AUTOMUTE_PIN;
13267 static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13268 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13269 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13270 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13271 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13272 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13273 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13274 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13275 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13279 static const struct hda_verb alc267_quanta_il1_verbs[] = {
13280 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13281 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13285 static void alc267_quanta_il1_setup(struct hda_codec *codec)
13287 struct alc_spec *spec = codec->spec;
13288 spec->autocfg.hp_pins[0] = 0x15;
13289 spec->autocfg.speaker_pins[0] = 0x14;
13290 spec->ext_mic.pin = 0x18;
13291 spec->ext_mic.mux_idx = 0;
13292 spec->int_mic.pin = 0x19;
13293 spec->int_mic.mux_idx = 1;
13294 spec->auto_mic = 1;
13295 spec->automute = 1;
13296 spec->automute_mode = ALC_AUTOMUTE_PIN;
13300 * generic initialization of ADC, input mixers and output mixers
13302 static const struct hda_verb alc268_base_init_verbs[] = {
13303 /* Unmute DAC0-1 and set vol = 0 */
13304 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13305 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13308 * Set up output mixers (0x0c - 0x0e)
13310 /* set vol=0 to output mixers */
13311 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13312 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13314 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13315 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13318 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13319 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13320 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13321 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13322 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13323 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13324 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13327 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13328 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13329 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13330 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13332 /* set PCBEEP vol = 0, mute connections */
13333 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13334 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13335 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13337 /* Unmute Selector 23h,24h and set the default input to mic-in */
13339 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13340 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13341 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13342 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13347 /* only for model=test */
13348 #ifdef CONFIG_SND_DEBUG
13350 * generic initialization of ADC, input mixers and output mixers
13352 static const struct hda_verb alc268_volume_init_verbs[] = {
13353 /* set output DAC */
13354 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13355 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13357 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13358 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13359 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13360 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13361 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13363 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13364 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13365 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13367 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13368 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13371 #endif /* CONFIG_SND_DEBUG */
13373 /* set PCBEEP vol = 0, mute connections */
13374 static const struct hda_verb alc268_beep_init_verbs[] = {
13375 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13376 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13377 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13381 static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13382 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13383 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13387 static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13388 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13389 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13394 static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13395 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13396 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13397 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13398 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13403 static const struct hda_input_mux alc268_capture_source = {
13407 { "Front Mic", 0x1 },
13413 static const struct hda_input_mux alc268_acer_capture_source = {
13417 { "Internal Mic", 0x1 },
13422 static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13426 { "Internal Mic", 0x6 },
13431 #ifdef CONFIG_SND_DEBUG
13432 static const struct snd_kcontrol_new alc268_test_mixer[] = {
13433 /* Volume widgets */
13434 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13435 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13436 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13437 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13438 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13439 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13440 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13441 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13442 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13443 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13444 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13445 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13446 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13447 /* The below appears problematic on some hardwares */
13448 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13449 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13450 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13451 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13452 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13454 /* Modes for retasking pin widgets */
13455 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13456 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13457 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13458 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13460 /* Controls for GPIO pins, assuming they are configured as outputs */
13461 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13462 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13463 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13464 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13466 /* Switches to allow the digital SPDIF output pin to be enabled.
13467 * The ALC268 does not have an SPDIF input.
13469 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13471 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13472 * this output to turn on an external amplifier.
13474 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13475 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13481 /* create input playback/capture controls for the given pin */
13482 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13483 const char *ctlname, int idx)
13494 case 0x1a: /* ALC259/269 only */
13495 case 0x1b: /* ALC259/269 only */
13496 case 0x21: /* ALC269vb has this pin, too */
13500 snd_printd(KERN_WARNING "hda_codec: "
13501 "ignoring pin 0x%x as unknown\n", nid);
13504 if (spec->multiout.dac_nids[0] != dac &&
13505 spec->multiout.dac_nids[1] != dac) {
13506 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13507 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13511 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13515 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13516 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13518 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13519 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13525 /* add playback controls from the parsed DAC table */
13526 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13527 const struct auto_pin_cfg *cfg)
13532 spec->multiout.dac_nids = spec->private_dac_nids;
13534 nid = cfg->line_out_pins[0];
13538 name = alc_get_line_out_pfx(spec, 0, true, &index);
13539 err = alc268_new_analog_output(spec, nid, name, 0);
13544 nid = cfg->speaker_pins[0];
13546 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13547 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13551 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13555 nid = cfg->hp_pins[0];
13557 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13562 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13564 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13565 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13572 /* create playback/capture controls for input pins */
13573 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13574 const struct auto_pin_cfg *cfg)
13576 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13579 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13580 hda_nid_t nid, int pin_type)
13584 alc_set_pin_output(codec, nid, pin_type);
13585 if (nid == 0x14 || nid == 0x16)
13589 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13592 static void alc268_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
13596 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13600 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13602 struct alc_spec *spec = codec->spec;
13605 for (i = 0; i < spec->autocfg.line_outs; i++) {
13606 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13607 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13608 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13611 for (i = 0; i < spec->multiout.num_dacs; i++)
13612 alc268_auto_init_dac(codec, spec->multiout.dac_nids[i]);
13615 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13617 struct alc_spec *spec = codec->spec;
13621 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13622 pin = spec->autocfg.hp_pins[i];
13623 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13625 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13626 pin = spec->autocfg.speaker_pins[i];
13627 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13629 if (spec->autocfg.mono_out_pin)
13630 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13631 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13633 alc268_auto_init_dac(codec, spec->multiout.hp_nid);
13634 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
13635 alc268_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
13638 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13640 struct alc_spec *spec = codec->spec;
13641 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13642 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13643 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13644 unsigned int dac_vol1, dac_vol2;
13646 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13647 snd_hda_codec_write(codec, speaker_nid, 0,
13648 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13649 /* mute mixer inputs from 0x1d */
13650 snd_hda_codec_write(codec, 0x0f, 0,
13651 AC_VERB_SET_AMP_GAIN_MUTE,
13653 snd_hda_codec_write(codec, 0x10, 0,
13654 AC_VERB_SET_AMP_GAIN_MUTE,
13657 /* unmute mixer inputs from 0x1d */
13658 snd_hda_codec_write(codec, 0x0f, 0,
13659 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13660 snd_hda_codec_write(codec, 0x10, 0,
13661 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13664 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13665 if (line_nid == 0x14)
13666 dac_vol2 = AMP_OUT_ZERO;
13667 else if (line_nid == 0x15)
13668 dac_vol1 = AMP_OUT_ZERO;
13669 if (hp_nid == 0x14)
13670 dac_vol2 = AMP_OUT_ZERO;
13671 else if (hp_nid == 0x15)
13672 dac_vol1 = AMP_OUT_ZERO;
13673 if (line_nid != 0x16 || hp_nid != 0x16 ||
13674 spec->autocfg.line_out_pins[1] != 0x16 ||
13675 spec->autocfg.line_out_pins[2] != 0x16)
13676 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13678 snd_hda_codec_write(codec, 0x02, 0,
13679 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13680 snd_hda_codec_write(codec, 0x03, 0,
13681 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13684 /* pcm configuration: identical with ALC880 */
13685 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13686 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13687 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13688 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13691 * BIOS auto configuration
13693 static int alc268_parse_auto_config(struct hda_codec *codec)
13695 struct alc_spec *spec = codec->spec;
13697 static const hda_nid_t alc268_ignore[] = { 0 };
13699 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13703 if (!spec->autocfg.line_outs) {
13704 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13705 spec->multiout.max_channels = 2;
13706 spec->no_analog = 1;
13709 return 0; /* can't find valid BIOS pin config */
13711 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13714 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13718 spec->multiout.max_channels = 2;
13721 /* digital only support output */
13722 alc_auto_parse_digital(codec);
13723 if (spec->kctls.list)
13724 add_mixer(spec, spec->kctls.list);
13726 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13727 add_mixer(spec, alc268_beep_mixer);
13729 add_verb(spec, alc268_beep_init_verbs);
13730 spec->num_mux_defs = 2;
13731 spec->input_mux = &spec->private_imux[0];
13733 err = alc_auto_add_mic_boost(codec);
13737 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13742 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13743 #define alc268_auto_init_input_src alc882_auto_init_input_src
13745 /* init callback for auto-configuration model -- overriding the default init */
13746 static void alc268_auto_init(struct hda_codec *codec)
13748 struct alc_spec *spec = codec->spec;
13749 alc268_auto_init_multi_out(codec);
13750 alc268_auto_init_hp_out(codec);
13751 alc268_auto_init_mono_speaker_out(codec);
13752 alc268_auto_init_analog_input(codec);
13753 alc268_auto_init_input_src(codec);
13754 alc_auto_init_digital(codec);
13755 if (spec->unsol_event)
13756 alc_inithook(codec);
13760 * configuration and preset
13762 static const char * const alc268_models[ALC268_MODEL_LAST] = {
13763 [ALC267_QUANTA_IL1] = "quanta-il1",
13764 [ALC268_3ST] = "3stack",
13765 [ALC268_TOSHIBA] = "toshiba",
13766 [ALC268_ACER] = "acer",
13767 [ALC268_ACER_DMIC] = "acer-dmic",
13768 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13769 [ALC268_DELL] = "dell",
13770 [ALC268_ZEPTO] = "zepto",
13771 #ifdef CONFIG_SND_DEBUG
13772 [ALC268_TEST] = "test",
13774 [ALC268_AUTO] = "auto",
13777 static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13778 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13779 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13780 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13781 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13782 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13783 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13784 ALC268_ACER_ASPIRE_ONE),
13785 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13786 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13787 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13788 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13789 /* almost compatible with toshiba but with optional digital outs;
13790 * auto-probing seems working fine
13792 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13794 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13795 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13796 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13797 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13801 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13802 static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13803 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13804 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13805 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13810 static const struct alc_config_preset alc268_presets[] = {
13811 [ALC267_QUANTA_IL1] = {
13812 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13813 alc268_capture_nosrc_mixer },
13814 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13815 alc267_quanta_il1_verbs },
13816 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13817 .dac_nids = alc268_dac_nids,
13818 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13819 .adc_nids = alc268_adc_nids_alt,
13821 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13822 .channel_mode = alc268_modes,
13823 .unsol_event = alc_sku_unsol_event,
13824 .setup = alc267_quanta_il1_setup,
13825 .init_hook = alc_inithook,
13828 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13829 alc268_beep_mixer },
13830 .init_verbs = { alc268_base_init_verbs },
13831 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13832 .dac_nids = alc268_dac_nids,
13833 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13834 .adc_nids = alc268_adc_nids_alt,
13835 .capsrc_nids = alc268_capsrc_nids,
13837 .dig_out_nid = ALC268_DIGOUT_NID,
13838 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13839 .channel_mode = alc268_modes,
13840 .input_mux = &alc268_capture_source,
13842 [ALC268_TOSHIBA] = {
13843 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13844 alc268_beep_mixer },
13845 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13846 alc268_toshiba_verbs },
13847 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13848 .dac_nids = alc268_dac_nids,
13849 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13850 .adc_nids = alc268_adc_nids_alt,
13851 .capsrc_nids = alc268_capsrc_nids,
13853 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13854 .channel_mode = alc268_modes,
13855 .input_mux = &alc268_capture_source,
13856 .unsol_event = alc_sku_unsol_event,
13857 .setup = alc268_toshiba_setup,
13858 .init_hook = alc_inithook,
13861 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13862 alc268_beep_mixer },
13863 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13864 alc268_acer_verbs },
13865 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13866 .dac_nids = alc268_dac_nids,
13867 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13868 .adc_nids = alc268_adc_nids_alt,
13869 .capsrc_nids = alc268_capsrc_nids,
13871 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13872 .channel_mode = alc268_modes,
13873 .input_mux = &alc268_acer_capture_source,
13874 .unsol_event = alc_sku_unsol_event,
13875 .setup = alc268_acer_setup,
13876 .init_hook = alc_inithook,
13878 [ALC268_ACER_DMIC] = {
13879 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13880 alc268_beep_mixer },
13881 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13882 alc268_acer_verbs },
13883 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13884 .dac_nids = alc268_dac_nids,
13885 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13886 .adc_nids = alc268_adc_nids_alt,
13887 .capsrc_nids = alc268_capsrc_nids,
13889 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13890 .channel_mode = alc268_modes,
13891 .input_mux = &alc268_acer_dmic_capture_source,
13892 .unsol_event = alc_sku_unsol_event,
13893 .setup = alc268_acer_setup,
13894 .init_hook = alc_inithook,
13896 [ALC268_ACER_ASPIRE_ONE] = {
13897 .mixers = { alc268_acer_aspire_one_mixer,
13899 alc268_capture_nosrc_mixer },
13900 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13901 alc268_acer_aspire_one_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 .unsol_event = alc_sku_unsol_event,
13911 .setup = alc268_acer_lc_setup,
13912 .init_hook = alc_inithook,
13915 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13916 alc268_capture_nosrc_mixer },
13917 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13918 alc268_dell_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 .unsol_event = alc_sku_unsol_event,
13928 .setup = alc268_dell_setup,
13929 .init_hook = alc_inithook,
13932 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13933 alc268_beep_mixer },
13934 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13935 alc268_toshiba_verbs },
13936 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13937 .dac_nids = alc268_dac_nids,
13938 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13939 .adc_nids = alc268_adc_nids_alt,
13940 .capsrc_nids = alc268_capsrc_nids,
13942 .dig_out_nid = ALC268_DIGOUT_NID,
13943 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13944 .channel_mode = alc268_modes,
13945 .input_mux = &alc268_capture_source,
13946 .unsol_event = alc_sku_unsol_event,
13947 .setup = alc268_toshiba_setup,
13948 .init_hook = alc_inithook,
13950 #ifdef CONFIG_SND_DEBUG
13952 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13953 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13954 alc268_volume_init_verbs,
13955 alc268_beep_init_verbs },
13956 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13957 .dac_nids = alc268_dac_nids,
13958 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13959 .adc_nids = alc268_adc_nids_alt,
13960 .capsrc_nids = alc268_capsrc_nids,
13962 .dig_out_nid = ALC268_DIGOUT_NID,
13963 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13964 .channel_mode = alc268_modes,
13965 .input_mux = &alc268_capture_source,
13970 static int patch_alc268(struct hda_codec *codec)
13972 struct alc_spec *spec;
13974 int i, has_beep, err;
13976 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13980 codec->spec = spec;
13982 /* ALC268 has no aa-loopback mixer */
13984 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13988 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13989 board_config = snd_hda_check_board_codec_sid_config(codec,
13990 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13992 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13993 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13995 board_config = ALC268_AUTO;
13998 if (board_config == ALC268_AUTO) {
13999 /* automatic parse from the BIOS config */
14000 err = alc268_parse_auto_config(codec);
14006 "hda_codec: Cannot set up configuration "
14007 "from BIOS. Using base mode...\n");
14008 board_config = ALC268_3ST;
14012 if (board_config != ALC268_AUTO)
14013 setup_preset(codec, &alc268_presets[board_config]);
14015 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14016 spec->stream_analog_capture = &alc268_pcm_analog_capture;
14017 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14019 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14022 for (i = 0; i < spec->num_mixers; i++) {
14023 if (spec->mixers[i] == alc268_beep_mixer) {
14030 err = snd_hda_attach_beep_device(codec, 0x1);
14035 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14036 /* override the amp caps for beep generator */
14037 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14038 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14039 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14040 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14041 (0 << AC_AMPCAP_MUTE_SHIFT));
14044 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14045 /* check whether NID 0x07 is valid */
14046 unsigned int wcap = get_wcaps(codec, 0x07);
14048 spec->capsrc_nids = alc268_capsrc_nids;
14050 wcap = get_wcaps_type(wcap);
14051 if (spec->auto_mic ||
14052 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14053 spec->adc_nids = alc268_adc_nids_alt;
14054 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14055 if (spec->auto_mic)
14056 fixup_automic_adc(codec);
14057 if (spec->auto_mic || spec->input_mux->num_items == 1)
14058 add_mixer(spec, alc268_capture_nosrc_mixer);
14060 add_mixer(spec, alc268_capture_alt_mixer);
14062 spec->adc_nids = alc268_adc_nids;
14063 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14064 add_mixer(spec, alc268_capture_mixer);
14068 spec->vmaster_nid = 0x02;
14070 codec->patch_ops = alc_patch_ops;
14071 if (board_config == ALC268_AUTO)
14072 spec->init_hook = alc268_auto_init;
14073 spec->shutup = alc_eapd_shutup;
14075 alc_init_jacks(codec);
14081 * ALC269 channel source setting (2 channel)
14083 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14085 #define alc269_dac_nids alc260_dac_nids
14087 static const hda_nid_t alc269_adc_nids[1] = {
14092 static const hda_nid_t alc269_capsrc_nids[1] = {
14096 static const hda_nid_t alc269vb_adc_nids[1] = {
14101 static const hda_nid_t alc269vb_capsrc_nids[1] = {
14105 static const hda_nid_t alc269_adc_candidates[] = {
14106 0x08, 0x09, 0x07, 0x11,
14109 #define alc269_modes alc260_modes
14110 #define alc269_capture_source alc880_lg_lw_capture_source
14112 static const struct snd_kcontrol_new alc269_base_mixer[] = {
14113 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14114 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14115 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14116 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14119 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14120 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14121 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14122 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14123 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14124 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14128 static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14129 /* output mixer control */
14130 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14133 .name = "Master Playback Switch",
14134 .subdevice = HDA_SUBDEV_AMP_FLAG,
14135 .info = snd_hda_mixer_amp_switch_info,
14136 .get = snd_hda_mixer_amp_switch_get,
14137 .put = alc268_acer_master_sw_put,
14138 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14140 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14141 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14143 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14144 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14145 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14149 static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14150 /* output mixer control */
14151 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14154 .name = "Master Playback Switch",
14155 .subdevice = HDA_SUBDEV_AMP_FLAG,
14156 .info = snd_hda_mixer_amp_switch_info,
14157 .get = snd_hda_mixer_amp_switch_get,
14158 .put = alc268_acer_master_sw_put,
14159 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14162 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14163 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14164 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14165 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14166 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14167 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14168 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14169 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14173 static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14174 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14175 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14177 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14181 static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14182 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14183 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14184 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14185 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14189 static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14190 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14191 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14195 /* capture mixer elements */
14196 static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14197 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14198 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14199 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14200 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14204 static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14205 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14206 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14207 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14211 static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14212 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14213 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14215 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14219 static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14220 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14221 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14222 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14227 #define alc269_fujitsu_mixer alc269_laptop_mixer
14229 static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14230 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14231 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14233 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14234 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14235 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14239 static const struct hda_verb alc269_lifebook_verbs[] = {
14240 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14241 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14242 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14243 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14244 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14245 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14247 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14248 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14249 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14253 /* toggle speaker-output according to the hp-jack state */
14254 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14256 alc_hp_automute(codec);
14258 snd_hda_codec_write(codec, 0x20, 0,
14259 AC_VERB_SET_COEF_INDEX, 0x0c);
14260 snd_hda_codec_write(codec, 0x20, 0,
14261 AC_VERB_SET_PROC_COEF, 0x680);
14263 snd_hda_codec_write(codec, 0x20, 0,
14264 AC_VERB_SET_COEF_INDEX, 0x0c);
14265 snd_hda_codec_write(codec, 0x20, 0,
14266 AC_VERB_SET_PROC_COEF, 0x480);
14269 #define alc269_lifebook_speaker_automute \
14270 alc269_quanta_fl1_speaker_automute
14272 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14274 unsigned int present_laptop;
14275 unsigned int present_dock;
14277 present_laptop = snd_hda_jack_detect(codec, 0x18);
14278 present_dock = snd_hda_jack_detect(codec, 0x1b);
14280 /* Laptop mic port overrides dock mic port, design decision */
14282 snd_hda_codec_write(codec, 0x23, 0,
14283 AC_VERB_SET_CONNECT_SEL, 0x3);
14284 if (present_laptop)
14285 snd_hda_codec_write(codec, 0x23, 0,
14286 AC_VERB_SET_CONNECT_SEL, 0x0);
14287 if (!present_dock && !present_laptop)
14288 snd_hda_codec_write(codec, 0x23, 0,
14289 AC_VERB_SET_CONNECT_SEL, 0x1);
14292 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14295 switch (res >> 26) {
14296 case ALC880_HP_EVENT:
14297 alc269_quanta_fl1_speaker_automute(codec);
14299 case ALC880_MIC_EVENT:
14300 alc_mic_automute(codec);
14305 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14308 if ((res >> 26) == ALC880_HP_EVENT)
14309 alc269_lifebook_speaker_automute(codec);
14310 if ((res >> 26) == ALC880_MIC_EVENT)
14311 alc269_lifebook_mic_autoswitch(codec);
14314 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14316 struct alc_spec *spec = codec->spec;
14317 spec->autocfg.hp_pins[0] = 0x15;
14318 spec->autocfg.speaker_pins[0] = 0x14;
14319 spec->automute_mixer_nid[0] = 0x0c;
14320 spec->automute = 1;
14321 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14322 spec->ext_mic.pin = 0x18;
14323 spec->ext_mic.mux_idx = 0;
14324 spec->int_mic.pin = 0x19;
14325 spec->int_mic.mux_idx = 1;
14326 spec->auto_mic = 1;
14329 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14331 alc269_quanta_fl1_speaker_automute(codec);
14332 alc_mic_automute(codec);
14335 static void alc269_lifebook_setup(struct hda_codec *codec)
14337 struct alc_spec *spec = codec->spec;
14338 spec->autocfg.hp_pins[0] = 0x15;
14339 spec->autocfg.hp_pins[1] = 0x1a;
14340 spec->autocfg.speaker_pins[0] = 0x14;
14341 spec->automute_mixer_nid[0] = 0x0c;
14342 spec->automute = 1;
14343 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14346 static void alc269_lifebook_init_hook(struct hda_codec *codec)
14348 alc269_lifebook_speaker_automute(codec);
14349 alc269_lifebook_mic_autoswitch(codec);
14352 static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14353 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14354 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14355 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14357 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14358 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14359 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14363 static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14364 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14365 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14366 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14367 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14368 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14369 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14373 static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14374 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14375 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14376 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14377 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14378 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14379 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14380 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14384 static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14385 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14386 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14387 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14389 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14390 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14391 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14395 static const struct hda_verb alc271_acer_dmic_verbs[] = {
14396 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14397 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14398 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14399 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14400 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14401 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14402 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14403 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14404 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14405 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14409 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14411 struct alc_spec *spec = codec->spec;
14412 spec->autocfg.hp_pins[0] = 0x15;
14413 spec->autocfg.speaker_pins[0] = 0x14;
14414 spec->automute_mixer_nid[0] = 0x0c;
14415 spec->automute = 1;
14416 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14417 spec->ext_mic.pin = 0x18;
14418 spec->ext_mic.mux_idx = 0;
14419 spec->int_mic.pin = 0x19;
14420 spec->int_mic.mux_idx = 1;
14421 spec->auto_mic = 1;
14424 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14426 struct alc_spec *spec = codec->spec;
14427 spec->autocfg.hp_pins[0] = 0x15;
14428 spec->autocfg.speaker_pins[0] = 0x14;
14429 spec->automute_mixer_nid[0] = 0x0c;
14430 spec->automute = 1;
14431 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14432 spec->ext_mic.pin = 0x18;
14433 spec->ext_mic.mux_idx = 0;
14434 spec->int_mic.pin = 0x12;
14435 spec->int_mic.mux_idx = 5;
14436 spec->auto_mic = 1;
14439 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14441 struct alc_spec *spec = codec->spec;
14442 spec->autocfg.hp_pins[0] = 0x21;
14443 spec->autocfg.speaker_pins[0] = 0x14;
14444 spec->automute_mixer_nid[0] = 0x0c;
14445 spec->automute = 1;
14446 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14447 spec->ext_mic.pin = 0x18;
14448 spec->ext_mic.mux_idx = 0;
14449 spec->int_mic.pin = 0x19;
14450 spec->int_mic.mux_idx = 1;
14451 spec->auto_mic = 1;
14454 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14456 struct alc_spec *spec = codec->spec;
14457 spec->autocfg.hp_pins[0] = 0x21;
14458 spec->autocfg.speaker_pins[0] = 0x14;
14459 spec->automute_mixer_nid[0] = 0x0c;
14460 spec->automute = 1;
14461 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14462 spec->ext_mic.pin = 0x18;
14463 spec->ext_mic.mux_idx = 0;
14464 spec->int_mic.pin = 0x12;
14465 spec->int_mic.mux_idx = 6;
14466 spec->auto_mic = 1;
14470 * generic initialization of ADC, input mixers and output mixers
14472 static const struct hda_verb alc269_init_verbs[] = {
14474 * Unmute ADC0 and set the default input to mic-in
14476 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14479 * Set up output mixers (0x02 - 0x03)
14481 /* set vol=0 to output mixers */
14482 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14483 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14485 /* set up input amps for analog loopback */
14486 /* Amp Indices: DAC = 0, mixer = 1 */
14487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14496 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14497 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14498 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14499 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14505 /* FIXME: use Mux-type input source selection */
14506 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14507 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14508 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14511 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14515 static const struct hda_verb alc269vb_init_verbs[] = {
14517 * Unmute ADC0 and set the default input to mic-in
14519 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14522 * Set up output mixers (0x02 - 0x03)
14524 /* set vol=0 to output mixers */
14525 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14526 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14528 /* set up input amps for analog loopback */
14529 /* Amp Indices: DAC = 0, mixer = 1 */
14530 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14534 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14535 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14537 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14538 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14539 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14540 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14541 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14542 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14543 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14545 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14546 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14548 /* FIXME: use Mux-type input source selection */
14549 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14550 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14551 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14554 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14558 #define alc269_auto_create_multi_out_ctls \
14559 alc268_auto_create_multi_out_ctls
14560 #define alc269_auto_create_input_ctls \
14561 alc268_auto_create_input_ctls
14563 #ifdef CONFIG_SND_HDA_POWER_SAVE
14564 #define alc269_loopbacks alc880_loopbacks
14567 /* pcm configuration: identical with ALC880 */
14568 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14569 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14570 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14571 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14573 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14577 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14578 /* NID is set in alc_build_pcms */
14580 .open = alc880_playback_pcm_open,
14581 .prepare = alc880_playback_pcm_prepare,
14582 .cleanup = alc880_playback_pcm_cleanup
14586 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14590 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14591 /* NID is set in alc_build_pcms */
14594 #ifdef CONFIG_SND_HDA_POWER_SAVE
14595 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14597 switch (codec->subsystem_id) {
14604 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14606 /* update mute-LED according to the speaker mute state */
14607 if (nid == 0x01 || nid == 0x14) {
14609 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14614 /* mic2 vref pin is used for mute LED control */
14615 snd_hda_codec_update_cache(codec, 0x19, 0,
14616 AC_VERB_SET_PIN_WIDGET_CONTROL,
14619 return alc_check_power_status(codec, nid);
14621 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14623 static int alc275_setup_dual_adc(struct hda_codec *codec)
14625 struct alc_spec *spec = codec->spec;
14627 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14629 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14630 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14631 if (spec->ext_mic.pin <= 0x12) {
14632 spec->private_adc_nids[0] = 0x08;
14633 spec->private_adc_nids[1] = 0x11;
14634 spec->private_capsrc_nids[0] = 0x23;
14635 spec->private_capsrc_nids[1] = 0x22;
14637 spec->private_adc_nids[0] = 0x11;
14638 spec->private_adc_nids[1] = 0x08;
14639 spec->private_capsrc_nids[0] = 0x22;
14640 spec->private_capsrc_nids[1] = 0x23;
14642 spec->adc_nids = spec->private_adc_nids;
14643 spec->capsrc_nids = spec->private_capsrc_nids;
14644 spec->num_adc_nids = 2;
14645 spec->dual_adc_switch = 1;
14646 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14647 spec->adc_nids[0], spec->adc_nids[1]);
14653 /* different alc269-variants */
14655 ALC269_TYPE_NORMAL,
14656 ALC269_TYPE_ALC258,
14657 ALC269_TYPE_ALC259,
14658 ALC269_TYPE_ALC269VB,
14659 ALC269_TYPE_ALC270,
14660 ALC269_TYPE_ALC271X,
14664 * BIOS auto configuration
14666 static int alc269_parse_auto_config(struct hda_codec *codec)
14668 struct alc_spec *spec = codec->spec;
14670 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14672 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14677 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14680 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14681 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14683 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14688 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14690 alc_auto_parse_digital(codec);
14692 if (spec->kctls.list)
14693 add_mixer(spec, spec->kctls.list);
14695 if (spec->codec_variant != ALC269_TYPE_NORMAL)
14696 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14698 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14700 spec->num_mux_defs = 1;
14701 spec->input_mux = &spec->private_imux[0];
14703 if (!alc275_setup_dual_adc(codec))
14704 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14705 sizeof(alc269_adc_candidates));
14707 err = alc_auto_add_mic_boost(codec);
14711 if (!spec->cap_mixer && !spec->no_analog)
14712 set_capture_mixer(codec);
14717 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14718 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14719 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14720 #define alc269_auto_init_input_src alc882_auto_init_input_src
14723 /* init callback for auto-configuration model -- overriding the default init */
14724 static void alc269_auto_init(struct hda_codec *codec)
14726 struct alc_spec *spec = codec->spec;
14727 alc269_auto_init_multi_out(codec);
14728 alc269_auto_init_hp_out(codec);
14729 alc269_auto_init_analog_input(codec);
14730 if (!spec->dual_adc_switch)
14731 alc269_auto_init_input_src(codec);
14732 alc_auto_init_digital(codec);
14733 if (spec->unsol_event)
14734 alc_inithook(codec);
14737 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14739 int val = alc_read_coef_idx(codec, 0x04);
14744 alc_write_coef_idx(codec, 0x04, val);
14747 static void alc269_shutup(struct hda_codec *codec)
14749 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14750 alc269_toggle_power_output(codec, 0);
14751 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14752 alc269_toggle_power_output(codec, 0);
14757 #ifdef SND_HDA_NEEDS_RESUME
14758 static int alc269_resume(struct hda_codec *codec)
14760 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14761 alc269_toggle_power_output(codec, 0);
14765 codec->patch_ops.init(codec);
14767 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14768 alc269_toggle_power_output(codec, 1);
14772 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14773 alc269_toggle_power_output(codec, 1);
14775 snd_hda_codec_resume_amp(codec);
14776 snd_hda_codec_resume_cache(codec);
14777 hda_call_check_power_status(codec, 0x01);
14780 #endif /* SND_HDA_NEEDS_RESUME */
14782 static void alc269_fixup_hweq(struct hda_codec *codec,
14783 const struct alc_fixup *fix, int action)
14787 if (action != ALC_FIXUP_ACT_INIT)
14789 coef = alc_read_coef_idx(codec, 0x1e);
14790 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14793 static void alc271_fixup_dmic(struct hda_codec *codec,
14794 const struct alc_fixup *fix, int action)
14796 static const struct hda_verb verbs[] = {
14797 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14798 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14803 if (strcmp(codec->chip_name, "ALC271X"))
14805 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14806 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14807 snd_hda_sequence_write(codec, verbs);
14811 ALC269_FIXUP_SONY_VAIO,
14812 ALC275_FIXUP_SONY_VAIO_GPIO2,
14813 ALC269_FIXUP_DELL_M101Z,
14814 ALC269_FIXUP_SKU_IGNORE,
14815 ALC269_FIXUP_ASUS_G73JW,
14816 ALC269_FIXUP_LENOVO_EAPD,
14817 ALC275_FIXUP_SONY_HWEQ,
14821 static const struct alc_fixup alc269_fixups[] = {
14822 [ALC269_FIXUP_SONY_VAIO] = {
14823 .type = ALC_FIXUP_VERBS,
14824 .v.verbs = (const struct hda_verb[]) {
14825 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14829 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14830 .type = ALC_FIXUP_VERBS,
14831 .v.verbs = (const struct hda_verb[]) {
14832 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14833 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14834 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14838 .chain_id = ALC269_FIXUP_SONY_VAIO
14840 [ALC269_FIXUP_DELL_M101Z] = {
14841 .type = ALC_FIXUP_VERBS,
14842 .v.verbs = (const struct hda_verb[]) {
14843 /* Enables internal speaker */
14844 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14845 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14849 [ALC269_FIXUP_SKU_IGNORE] = {
14850 .type = ALC_FIXUP_SKU,
14851 .v.sku = ALC_FIXUP_SKU_IGNORE,
14853 [ALC269_FIXUP_ASUS_G73JW] = {
14854 .type = ALC_FIXUP_PINS,
14855 .v.pins = (const struct alc_pincfg[]) {
14856 { 0x17, 0x99130111 }, /* subwoofer */
14860 [ALC269_FIXUP_LENOVO_EAPD] = {
14861 .type = ALC_FIXUP_VERBS,
14862 .v.verbs = (const struct hda_verb[]) {
14863 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14867 [ALC275_FIXUP_SONY_HWEQ] = {
14868 .type = ALC_FIXUP_FUNC,
14869 .v.func = alc269_fixup_hweq,
14871 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14873 [ALC271_FIXUP_DMIC] = {
14874 .type = ALC_FIXUP_FUNC,
14875 .v.func = alc271_fixup_dmic,
14879 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14880 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14881 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14882 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14883 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14884 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14885 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14886 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14887 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14888 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14889 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14890 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14891 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14892 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14898 * configuration and preset
14900 static const char * const alc269_models[ALC269_MODEL_LAST] = {
14901 [ALC269_BASIC] = "basic",
14902 [ALC269_QUANTA_FL1] = "quanta",
14903 [ALC269_AMIC] = "laptop-amic",
14904 [ALC269_DMIC] = "laptop-dmic",
14905 [ALC269_FUJITSU] = "fujitsu",
14906 [ALC269_LIFEBOOK] = "lifebook",
14907 [ALC269_AUTO] = "auto",
14910 static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14911 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14912 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14913 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14915 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14916 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14917 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14918 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14919 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14920 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14921 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14922 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14923 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14924 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
14925 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14926 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14927 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14928 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14929 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14930 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14931 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14932 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14933 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14934 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14935 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14936 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14937 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14938 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14939 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14940 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14941 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14942 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14943 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14944 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14945 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14946 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14947 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14949 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14950 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14951 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14953 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14955 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14956 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14957 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14958 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14959 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14960 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14961 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14962 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14963 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14964 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14968 static const struct alc_config_preset alc269_presets[] = {
14970 .mixers = { alc269_base_mixer },
14971 .init_verbs = { alc269_init_verbs },
14972 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14973 .dac_nids = alc269_dac_nids,
14975 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14976 .channel_mode = alc269_modes,
14977 .input_mux = &alc269_capture_source,
14979 [ALC269_QUANTA_FL1] = {
14980 .mixers = { alc269_quanta_fl1_mixer },
14981 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14982 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14983 .dac_nids = alc269_dac_nids,
14985 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14986 .channel_mode = alc269_modes,
14987 .input_mux = &alc269_capture_source,
14988 .unsol_event = alc269_quanta_fl1_unsol_event,
14989 .setup = alc269_quanta_fl1_setup,
14990 .init_hook = alc269_quanta_fl1_init_hook,
14993 .mixers = { alc269_laptop_mixer },
14994 .cap_mixer = alc269_laptop_analog_capture_mixer,
14995 .init_verbs = { alc269_init_verbs,
14996 alc269_laptop_amic_init_verbs },
14997 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14998 .dac_nids = alc269_dac_nids,
15000 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15001 .channel_mode = alc269_modes,
15002 .unsol_event = alc_sku_unsol_event,
15003 .setup = alc269_laptop_amic_setup,
15004 .init_hook = alc_inithook,
15007 .mixers = { alc269_laptop_mixer },
15008 .cap_mixer = alc269_laptop_digital_capture_mixer,
15009 .init_verbs = { alc269_init_verbs,
15010 alc269_laptop_dmic_init_verbs },
15011 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15012 .dac_nids = alc269_dac_nids,
15014 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15015 .channel_mode = alc269_modes,
15016 .unsol_event = alc_sku_unsol_event,
15017 .setup = alc269_laptop_dmic_setup,
15018 .init_hook = alc_inithook,
15020 [ALC269VB_AMIC] = {
15021 .mixers = { alc269vb_laptop_mixer },
15022 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15023 .init_verbs = { alc269vb_init_verbs,
15024 alc269vb_laptop_amic_init_verbs },
15025 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15026 .dac_nids = alc269_dac_nids,
15028 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15029 .channel_mode = alc269_modes,
15030 .unsol_event = alc_sku_unsol_event,
15031 .setup = alc269vb_laptop_amic_setup,
15032 .init_hook = alc_inithook,
15034 [ALC269VB_DMIC] = {
15035 .mixers = { alc269vb_laptop_mixer },
15036 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15037 .init_verbs = { alc269vb_init_verbs,
15038 alc269vb_laptop_dmic_init_verbs },
15039 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15040 .dac_nids = alc269_dac_nids,
15042 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15043 .channel_mode = alc269_modes,
15044 .unsol_event = alc_sku_unsol_event,
15045 .setup = alc269vb_laptop_dmic_setup,
15046 .init_hook = alc_inithook,
15048 [ALC269_FUJITSU] = {
15049 .mixers = { alc269_fujitsu_mixer },
15050 .cap_mixer = alc269_laptop_digital_capture_mixer,
15051 .init_verbs = { alc269_init_verbs,
15052 alc269_laptop_dmic_init_verbs },
15053 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15054 .dac_nids = alc269_dac_nids,
15056 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15057 .channel_mode = alc269_modes,
15058 .unsol_event = alc_sku_unsol_event,
15059 .setup = alc269_laptop_dmic_setup,
15060 .init_hook = alc_inithook,
15062 [ALC269_LIFEBOOK] = {
15063 .mixers = { alc269_lifebook_mixer },
15064 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15065 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15066 .dac_nids = alc269_dac_nids,
15068 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15069 .channel_mode = alc269_modes,
15070 .input_mux = &alc269_capture_source,
15071 .unsol_event = alc269_lifebook_unsol_event,
15072 .setup = alc269_lifebook_setup,
15073 .init_hook = alc269_lifebook_init_hook,
15076 .mixers = { alc269_asus_mixer },
15077 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15078 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15079 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15080 .dac_nids = alc269_dac_nids,
15081 .adc_nids = alc262_dmic_adc_nids,
15082 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15083 .capsrc_nids = alc262_dmic_capsrc_nids,
15084 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15085 .channel_mode = alc269_modes,
15086 .input_mux = &alc269_capture_source,
15087 .dig_out_nid = ALC880_DIGOUT_NID,
15088 .unsol_event = alc_sku_unsol_event,
15089 .setup = alc269vb_laptop_dmic_setup,
15090 .init_hook = alc_inithook,
15094 static int alc269_fill_coef(struct hda_codec *codec)
15098 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15099 alc_write_coef_idx(codec, 0xf, 0x960b);
15100 alc_write_coef_idx(codec, 0xe, 0x8817);
15103 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15104 alc_write_coef_idx(codec, 0xf, 0x960b);
15105 alc_write_coef_idx(codec, 0xe, 0x8814);
15108 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15109 val = alc_read_coef_idx(codec, 0x04);
15110 /* Power up output pin */
15111 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15114 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15115 val = alc_read_coef_idx(codec, 0xd);
15116 if ((val & 0x0c00) >> 10 != 0x1) {
15117 /* Capless ramp up clock control */
15118 alc_write_coef_idx(codec, 0xd, val | (1<<10));
15120 val = alc_read_coef_idx(codec, 0x17);
15121 if ((val & 0x01c0) >> 6 != 0x4) {
15122 /* Class D power on reset */
15123 alc_write_coef_idx(codec, 0x17, val | (1<<7));
15127 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15128 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15130 val = alc_read_coef_idx(codec, 0x4); /* HP */
15131 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15136 static int patch_alc269(struct hda_codec *codec)
15138 struct alc_spec *spec;
15139 int board_config, coef;
15142 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15146 codec->spec = spec;
15148 spec->mixer_nid = 0x0b;
15150 alc_auto_parse_customize_define(codec);
15152 if (codec->vendor_id == 0x10ec0269) {
15153 coef = alc_read_coef_idx(codec, 0);
15154 if ((coef & 0x00f0) == 0x0010) {
15155 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15156 spec->cdefine.platform_type == 1) {
15157 alc_codec_rename(codec, "ALC271X");
15158 spec->codec_variant = ALC269_TYPE_ALC271X;
15159 } else if ((coef & 0xf000) == 0x1000) {
15160 spec->codec_variant = ALC269_TYPE_ALC270;
15161 } else if ((coef & 0xf000) == 0x2000) {
15162 alc_codec_rename(codec, "ALC259");
15163 spec->codec_variant = ALC269_TYPE_ALC259;
15164 } else if ((coef & 0xf000) == 0x3000) {
15165 alc_codec_rename(codec, "ALC258");
15166 spec->codec_variant = ALC269_TYPE_ALC258;
15168 alc_codec_rename(codec, "ALC269VB");
15169 spec->codec_variant = ALC269_TYPE_ALC269VB;
15172 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15173 alc269_fill_coef(codec);
15176 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15180 if (board_config < 0) {
15181 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15183 board_config = ALC269_AUTO;
15186 if (board_config == ALC269_AUTO) {
15187 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15188 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15191 if (board_config == ALC269_AUTO) {
15192 /* automatic parse from the BIOS config */
15193 err = alc269_parse_auto_config(codec);
15199 "hda_codec: Cannot set up configuration "
15200 "from BIOS. Using base mode...\n");
15201 board_config = ALC269_BASIC;
15205 if (has_cdefine_beep(codec)) {
15206 err = snd_hda_attach_beep_device(codec, 0x1);
15213 if (board_config != ALC269_AUTO)
15214 setup_preset(codec, &alc269_presets[board_config]);
15216 if (board_config == ALC269_QUANTA_FL1) {
15217 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15218 * fix the sample rate of analog I/O to 44.1kHz
15220 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15221 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15222 } else if (spec->dual_adc_switch) {
15223 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15224 /* switch ADC dynamically */
15225 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15227 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15228 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15230 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15231 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15233 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15234 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15235 spec->adc_nids = alc269_adc_nids;
15236 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15237 spec->capsrc_nids = alc269_capsrc_nids;
15239 spec->adc_nids = alc269vb_adc_nids;
15240 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15241 spec->capsrc_nids = alc269vb_capsrc_nids;
15245 if (!spec->cap_mixer)
15246 set_capture_mixer(codec);
15247 if (has_cdefine_beep(codec))
15248 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15250 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15252 spec->vmaster_nid = 0x02;
15254 codec->patch_ops = alc_patch_ops;
15255 #ifdef SND_HDA_NEEDS_RESUME
15256 codec->patch_ops.resume = alc269_resume;
15258 if (board_config == ALC269_AUTO)
15259 spec->init_hook = alc269_auto_init;
15260 spec->shutup = alc269_shutup;
15262 alc_init_jacks(codec);
15263 #ifdef CONFIG_SND_HDA_POWER_SAVE
15264 if (!spec->loopback.amplist)
15265 spec->loopback.amplist = alc269_loopbacks;
15266 if (alc269_mic2_for_mute_led(codec))
15267 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15274 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15278 * set the path ways for 2 channel output
15279 * need to set the codec line out and mic 1 pin widgets to inputs
15281 static const struct hda_verb alc861_threestack_ch2_init[] = {
15282 /* set pin widget 1Ah (line in) for input */
15283 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15284 /* set pin widget 18h (mic1/2) for input, for mic also enable
15287 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15289 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15291 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15292 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15298 * need to set the codec line out and mic 1 pin widgets to outputs
15300 static const struct hda_verb alc861_threestack_ch6_init[] = {
15301 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15302 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15303 /* set pin widget 18h (mic1) for output (CLFE)*/
15304 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15306 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15307 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15309 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15311 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15312 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15317 static const struct hda_channel_mode alc861_threestack_modes[2] = {
15318 { 2, alc861_threestack_ch2_init },
15319 { 6, alc861_threestack_ch6_init },
15321 /* Set mic1 as input and unmute the mixer */
15322 static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15323 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15324 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15327 /* Set mic1 as output and mute mixer */
15328 static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15329 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15330 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15334 static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15335 { 2, alc861_uniwill_m31_ch2_init },
15336 { 4, alc861_uniwill_m31_ch4_init },
15339 /* Set mic1 and line-in as input and unmute the mixer */
15340 static const struct hda_verb alc861_asus_ch2_init[] = {
15341 /* set pin widget 1Ah (line in) for input */
15342 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15343 /* set pin widget 18h (mic1/2) for input, for mic also enable
15346 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15348 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15350 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15351 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15355 /* Set mic1 nad line-in as output and mute mixer */
15356 static const struct hda_verb alc861_asus_ch6_init[] = {
15357 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15359 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15360 /* set pin widget 18h (mic1) for output (CLFE)*/
15361 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15362 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15363 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15364 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15366 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15368 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15369 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15374 static const struct hda_channel_mode alc861_asus_modes[2] = {
15375 { 2, alc861_asus_ch2_init },
15376 { 6, alc861_asus_ch6_init },
15381 static const struct snd_kcontrol_new alc861_base_mixer[] = {
15382 /* output mixer control */
15383 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15384 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15385 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15386 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15387 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15389 /*Input mixer control */
15390 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15391 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15392 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15393 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15394 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15395 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15396 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15397 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15398 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15404 static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15405 /* output mixer control */
15406 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15407 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15408 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15409 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15410 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15412 /* Input mixer control */
15413 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15415 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15416 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15417 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15418 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15420 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15421 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15422 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15425 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15426 .name = "Channel Mode",
15427 .info = alc_ch_mode_info,
15428 .get = alc_ch_mode_get,
15429 .put = alc_ch_mode_put,
15430 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15435 static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15436 /* output mixer control */
15437 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15439 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15444 static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15445 /* output mixer control */
15446 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15448 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15449 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15450 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15452 /* Input mixer control */
15453 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15454 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15455 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15456 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15457 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15458 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15460 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15461 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15465 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15466 .name = "Channel Mode",
15467 .info = alc_ch_mode_info,
15468 .get = alc_ch_mode_get,
15469 .put = alc_ch_mode_put,
15470 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15475 static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15476 /* output mixer control */
15477 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15478 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15479 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15480 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15481 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15483 /* Input mixer control */
15484 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15485 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15486 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15487 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15488 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15489 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15491 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15492 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15493 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15496 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15497 .name = "Channel Mode",
15498 .info = alc_ch_mode_info,
15499 .get = alc_ch_mode_get,
15500 .put = alc_ch_mode_put,
15501 .private_value = ARRAY_SIZE(alc861_asus_modes),
15506 /* additional mixer */
15507 static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15508 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15509 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15514 * generic initialization of ADC, input mixers and output mixers
15516 static const struct hda_verb alc861_base_init_verbs[] = {
15518 * Unmute ADC0 and set the default input to mic-in
15520 /* port-A for surround (rear panel) */
15521 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15522 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15523 /* port-B for mic-in (rear panel) with vref */
15524 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15525 /* port-C for line-in (rear panel) */
15526 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15527 /* port-D for Front */
15528 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15529 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15530 /* port-E for HP out (front panel) */
15531 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15532 /* route front PCM to HP */
15533 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15534 /* port-F for mic-in (front panel) with vref */
15535 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15536 /* port-G for CLFE (rear panel) */
15537 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15538 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15539 /* port-H for side (rear panel) */
15540 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15541 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15543 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15544 /* route front mic to ADC1*/
15545 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15548 /* Unmute DAC0~3 & spdif out*/
15549 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15550 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15551 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15552 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15555 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15556 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15557 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15558 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15559 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15561 /* Unmute Stereo Mixer 15 */
15562 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15567 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15569 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15570 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15571 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15572 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15573 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15574 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15575 /* hp used DAC 3 (Front) */
15576 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15577 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15582 static const struct hda_verb alc861_threestack_init_verbs[] = {
15584 * Unmute ADC0 and set the default input to mic-in
15586 /* port-A for surround (rear panel) */
15587 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15588 /* port-B for mic-in (rear panel) with vref */
15589 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15590 /* port-C for line-in (rear panel) */
15591 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15592 /* port-D for Front */
15593 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15594 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15595 /* port-E for HP out (front panel) */
15596 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15597 /* route front PCM to HP */
15598 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15599 /* port-F for mic-in (front panel) with vref */
15600 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15601 /* port-G for CLFE (rear panel) */
15602 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15603 /* port-H for side (rear panel) */
15604 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15606 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15607 /* route front mic to ADC1*/
15608 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15609 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15610 /* Unmute DAC0~3 & spdif out*/
15611 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15612 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15613 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15614 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15615 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15617 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15618 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15619 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15620 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15621 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15623 /* Unmute Stereo Mixer 15 */
15624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15627 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15629 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15630 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15631 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15635 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15636 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15637 /* hp used DAC 3 (Front) */
15638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15639 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15643 static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15645 * Unmute ADC0 and set the default input to mic-in
15647 /* port-A for surround (rear panel) */
15648 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15649 /* port-B for mic-in (rear panel) with vref */
15650 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15651 /* port-C for line-in (rear panel) */
15652 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15653 /* port-D for Front */
15654 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15655 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15656 /* port-E for HP out (front panel) */
15657 /* this has to be set to VREF80 */
15658 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15659 /* route front PCM to HP */
15660 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15661 /* port-F for mic-in (front panel) with vref */
15662 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15663 /* port-G for CLFE (rear panel) */
15664 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15665 /* port-H for side (rear panel) */
15666 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15668 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15669 /* route front mic to ADC1*/
15670 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15671 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15672 /* Unmute DAC0~3 & spdif out*/
15673 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15674 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15675 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15676 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15679 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15680 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15681 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15682 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15683 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15685 /* Unmute Stereo Mixer 15 */
15686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15691 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15692 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15696 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15697 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15698 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15699 /* hp used DAC 3 (Front) */
15700 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15705 static const struct hda_verb alc861_asus_init_verbs[] = {
15707 * Unmute ADC0 and set the default input to mic-in
15709 /* port-A for surround (rear panel)
15710 * according to codec#0 this is the HP jack
15712 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15713 /* route front PCM to HP */
15714 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15715 /* port-B for mic-in (rear panel) with vref */
15716 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15717 /* port-C for line-in (rear panel) */
15718 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15719 /* port-D for Front */
15720 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15721 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15722 /* port-E for HP out (front panel) */
15723 /* this has to be set to VREF80 */
15724 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15725 /* route front PCM to HP */
15726 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15727 /* port-F for mic-in (front panel) with vref */
15728 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15729 /* port-G for CLFE (rear panel) */
15730 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15731 /* port-H for side (rear panel) */
15732 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15734 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15735 /* route front mic to ADC1*/
15736 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15738 /* Unmute DAC0~3 & spdif out*/
15739 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15740 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15741 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15742 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15744 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15745 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15746 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15747 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15748 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15750 /* Unmute Stereo Mixer 15 */
15751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15752 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15753 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15754 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15756 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15757 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15758 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15759 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15760 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15761 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15762 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15763 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15764 /* hp used DAC 3 (Front) */
15765 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15766 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15770 /* additional init verbs for ASUS laptops */
15771 static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15772 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15773 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15777 static const struct hda_verb alc861_toshiba_init_verbs[] = {
15778 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15783 /* toggle speaker-output according to the hp-jack state */
15784 static void alc861_toshiba_automute(struct hda_codec *codec)
15786 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15788 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15789 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15790 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15791 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15794 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15797 if ((res >> 26) == ALC880_HP_EVENT)
15798 alc861_toshiba_automute(codec);
15801 /* pcm configuration: identical with ALC880 */
15802 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15803 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15804 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15805 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15808 #define ALC861_DIGOUT_NID 0x07
15810 static const struct hda_channel_mode alc861_8ch_modes[1] = {
15814 static const hda_nid_t alc861_dac_nids[4] = {
15815 /* front, surround, clfe, side */
15816 0x03, 0x06, 0x05, 0x04
15819 static const hda_nid_t alc660_dac_nids[3] = {
15820 /* front, clfe, surround */
15824 static const hda_nid_t alc861_adc_nids[1] = {
15829 static const struct hda_input_mux alc861_capture_source = {
15833 { "Front Mic", 0x3 },
15840 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15842 struct alc_spec *spec = codec->spec;
15843 hda_nid_t mix, srcs[5];
15846 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15848 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15851 for (i = 0; i < num; i++) {
15853 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15854 if (type != AC_WID_AUD_OUT)
15856 if (!found_in_nid_list(srcs[i], spec->multiout.dac_nids,
15857 spec->multiout.num_dacs))
15863 /* fill in the dac_nids table from the parsed pin configuration */
15864 static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
15866 struct alc_spec *spec = codec->spec;
15867 const struct auto_pin_cfg *cfg = &spec->autocfg;
15869 hda_nid_t nid, dac;
15871 spec->multiout.dac_nids = spec->private_dac_nids;
15872 for (i = 0; i < cfg->line_outs; i++) {
15873 nid = cfg->line_out_pins[i];
15874 dac = alc861_look_for_dac(codec, nid);
15877 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
15882 static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15883 hda_nid_t nid, int idx, unsigned int chs)
15885 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
15886 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15889 #define alc861_create_out_sw(codec, pfx, nid, chs) \
15890 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15892 /* add playback controls from the parsed DAC table */
15893 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15894 const struct auto_pin_cfg *cfg)
15896 struct alc_spec *spec = codec->spec;
15898 int i, err, noutputs;
15900 noutputs = cfg->line_outs;
15901 if (spec->multi_ios > 0)
15902 noutputs += spec->multi_ios;
15904 for (i = 0; i < noutputs; i++) {
15907 nid = spec->multiout.dac_nids[i];
15910 name = alc_get_line_out_pfx(spec, i, true, &index);
15913 err = alc861_create_out_sw(codec, "Center", nid, 1);
15916 err = alc861_create_out_sw(codec, "LFE", nid, 2);
15920 err = __alc861_create_out_sw(codec, name, nid, index, 3);
15928 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
15930 struct alc_spec *spec = codec->spec;
15937 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
15938 nid = alc861_look_for_dac(codec, pin);
15940 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15943 spec->multiout.hp_nid = nid;
15949 /* create playback/capture controls for input pins */
15950 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
15951 const struct auto_pin_cfg *cfg)
15953 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
15956 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15958 int pin_type, hda_nid_t dac)
15960 hda_nid_t mix, srcs[5];
15963 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15965 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15967 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15969 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15972 for (i = 0; i < num; i++) {
15974 if (srcs[i] == dac || srcs[i] == 0x15)
15975 mute = AMP_IN_UNMUTE(i);
15977 mute = AMP_IN_MUTE(i);
15978 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15983 static void alc861_auto_init_multi_out(struct hda_codec *codec)
15985 struct alc_spec *spec = codec->spec;
15988 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
15989 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15990 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15992 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
15993 spec->multiout.dac_nids[i]);
15997 static void alc861_auto_init_hp_out(struct hda_codec *codec)
15999 struct alc_spec *spec = codec->spec;
16001 if (spec->autocfg.hp_outs)
16002 alc861_auto_set_output_and_unmute(codec,
16003 spec->autocfg.hp_pins[0],
16005 spec->multiout.hp_nid);
16006 if (spec->autocfg.speaker_outs)
16007 alc861_auto_set_output_and_unmute(codec,
16008 spec->autocfg.speaker_pins[0],
16010 spec->multiout.dac_nids[0]);
16013 #define alc861_auto_init_analog_input alc880_auto_init_analog_input
16015 /* parse the BIOS configuration and set up the alc_spec */
16016 /* return 1 if successful, 0 if the proper config is not found,
16017 * or a negative error code
16019 static int alc861_parse_auto_config(struct hda_codec *codec)
16021 struct alc_spec *spec = codec->spec;
16023 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16025 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16029 if (!spec->autocfg.line_outs)
16030 return 0; /* can't find valid BIOS pin config */
16032 err = alc861_auto_fill_dac_nids(codec);
16035 err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids);
16038 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16041 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16044 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16048 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16050 alc_auto_parse_digital(codec);
16052 if (spec->kctls.list)
16053 add_mixer(spec, spec->kctls.list);
16055 spec->num_mux_defs = 1;
16056 spec->input_mux = &spec->private_imux[0];
16058 spec->adc_nids = alc861_adc_nids;
16059 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16060 set_capture_mixer(codec);
16062 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16067 /* additional initialization for auto-configuration model */
16068 static void alc861_auto_init(struct hda_codec *codec)
16070 struct alc_spec *spec = codec->spec;
16071 alc861_auto_init_multi_out(codec);
16072 alc861_auto_init_hp_out(codec);
16073 alc861_auto_init_analog_input(codec);
16074 alc_auto_init_digital(codec);
16075 if (spec->unsol_event)
16076 alc_inithook(codec);
16079 #ifdef CONFIG_SND_HDA_POWER_SAVE
16080 static const struct hda_amp_list alc861_loopbacks[] = {
16081 { 0x15, HDA_INPUT, 0 },
16082 { 0x15, HDA_INPUT, 1 },
16083 { 0x15, HDA_INPUT, 2 },
16084 { 0x15, HDA_INPUT, 3 },
16091 * configuration and preset
16093 static const char * const alc861_models[ALC861_MODEL_LAST] = {
16094 [ALC861_3ST] = "3stack",
16095 [ALC660_3ST] = "3stack-660",
16096 [ALC861_3ST_DIG] = "3stack-dig",
16097 [ALC861_6ST_DIG] = "6stack-dig",
16098 [ALC861_UNIWILL_M31] = "uniwill-m31",
16099 [ALC861_TOSHIBA] = "toshiba",
16100 [ALC861_ASUS] = "asus",
16101 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16102 [ALC861_AUTO] = "auto",
16105 static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16106 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16107 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16108 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16109 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16110 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16111 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16112 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16113 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16114 * Any other models that need this preset?
16116 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16117 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16118 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16119 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16120 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16121 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16122 /* FIXME: the below seems conflict */
16123 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16124 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16125 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16129 static const struct alc_config_preset alc861_presets[] = {
16131 .mixers = { alc861_3ST_mixer },
16132 .init_verbs = { alc861_threestack_init_verbs },
16133 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16134 .dac_nids = alc861_dac_nids,
16135 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16136 .channel_mode = alc861_threestack_modes,
16138 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16139 .adc_nids = alc861_adc_nids,
16140 .input_mux = &alc861_capture_source,
16142 [ALC861_3ST_DIG] = {
16143 .mixers = { alc861_base_mixer },
16144 .init_verbs = { alc861_threestack_init_verbs },
16145 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16146 .dac_nids = alc861_dac_nids,
16147 .dig_out_nid = ALC861_DIGOUT_NID,
16148 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16149 .channel_mode = alc861_threestack_modes,
16151 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16152 .adc_nids = alc861_adc_nids,
16153 .input_mux = &alc861_capture_source,
16155 [ALC861_6ST_DIG] = {
16156 .mixers = { alc861_base_mixer },
16157 .init_verbs = { alc861_base_init_verbs },
16158 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16159 .dac_nids = alc861_dac_nids,
16160 .dig_out_nid = ALC861_DIGOUT_NID,
16161 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16162 .channel_mode = alc861_8ch_modes,
16163 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16164 .adc_nids = alc861_adc_nids,
16165 .input_mux = &alc861_capture_source,
16168 .mixers = { alc861_3ST_mixer },
16169 .init_verbs = { alc861_threestack_init_verbs },
16170 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16171 .dac_nids = alc660_dac_nids,
16172 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16173 .channel_mode = alc861_threestack_modes,
16175 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16176 .adc_nids = alc861_adc_nids,
16177 .input_mux = &alc861_capture_source,
16179 [ALC861_UNIWILL_M31] = {
16180 .mixers = { alc861_uniwill_m31_mixer },
16181 .init_verbs = { alc861_uniwill_m31_init_verbs },
16182 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16183 .dac_nids = alc861_dac_nids,
16184 .dig_out_nid = ALC861_DIGOUT_NID,
16185 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16186 .channel_mode = alc861_uniwill_m31_modes,
16188 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16189 .adc_nids = alc861_adc_nids,
16190 .input_mux = &alc861_capture_source,
16192 [ALC861_TOSHIBA] = {
16193 .mixers = { alc861_toshiba_mixer },
16194 .init_verbs = { alc861_base_init_verbs,
16195 alc861_toshiba_init_verbs },
16196 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16197 .dac_nids = alc861_dac_nids,
16198 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16199 .channel_mode = alc883_3ST_2ch_modes,
16200 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16201 .adc_nids = alc861_adc_nids,
16202 .input_mux = &alc861_capture_source,
16203 .unsol_event = alc861_toshiba_unsol_event,
16204 .init_hook = alc861_toshiba_automute,
16207 .mixers = { alc861_asus_mixer },
16208 .init_verbs = { alc861_asus_init_verbs },
16209 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16210 .dac_nids = alc861_dac_nids,
16211 .dig_out_nid = ALC861_DIGOUT_NID,
16212 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16213 .channel_mode = alc861_asus_modes,
16216 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16217 .adc_nids = alc861_adc_nids,
16218 .input_mux = &alc861_capture_source,
16220 [ALC861_ASUS_LAPTOP] = {
16221 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16222 .init_verbs = { alc861_asus_init_verbs,
16223 alc861_asus_laptop_init_verbs },
16224 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16225 .dac_nids = alc861_dac_nids,
16226 .dig_out_nid = ALC861_DIGOUT_NID,
16227 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16228 .channel_mode = alc883_3ST_2ch_modes,
16230 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16231 .adc_nids = alc861_adc_nids,
16232 .input_mux = &alc861_capture_source,
16236 /* Pin config fixes */
16238 PINFIX_FSC_AMILO_PI1505,
16241 static const struct alc_fixup alc861_fixups[] = {
16242 [PINFIX_FSC_AMILO_PI1505] = {
16243 .type = ALC_FIXUP_PINS,
16244 .v.pins = (const struct alc_pincfg[]) {
16245 { 0x0b, 0x0221101f }, /* HP */
16246 { 0x0f, 0x90170310 }, /* speaker */
16252 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16253 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16257 static int patch_alc861(struct hda_codec *codec)
16259 struct alc_spec *spec;
16263 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16267 codec->spec = spec;
16269 spec->mixer_nid = 0x15;
16271 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16275 if (board_config < 0) {
16276 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16278 board_config = ALC861_AUTO;
16281 if (board_config == ALC861_AUTO) {
16282 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16283 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16286 if (board_config == ALC861_AUTO) {
16287 /* automatic parse from the BIOS config */
16288 err = alc861_parse_auto_config(codec);
16294 "hda_codec: Cannot set up configuration "
16295 "from BIOS. Using base mode...\n");
16296 board_config = ALC861_3ST_DIG;
16300 err = snd_hda_attach_beep_device(codec, 0x23);
16306 if (board_config != ALC861_AUTO)
16307 setup_preset(codec, &alc861_presets[board_config]);
16309 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16310 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16312 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16313 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16315 if (!spec->cap_mixer)
16316 set_capture_mixer(codec);
16317 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16319 spec->vmaster_nid = 0x03;
16321 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16323 codec->patch_ops = alc_patch_ops;
16324 if (board_config == ALC861_AUTO) {
16325 spec->init_hook = alc861_auto_init;
16326 #ifdef CONFIG_SND_HDA_POWER_SAVE
16327 spec->power_hook = alc_power_eapd;
16330 #ifdef CONFIG_SND_HDA_POWER_SAVE
16331 if (!spec->loopback.amplist)
16332 spec->loopback.amplist = alc861_loopbacks;
16339 * ALC861-VD support
16343 * In addition, an independent DAC
16345 #define ALC861VD_DIGOUT_NID 0x06
16347 static const hda_nid_t alc861vd_dac_nids[4] = {
16348 /* front, surr, clfe, side surr */
16349 0x02, 0x03, 0x04, 0x05
16352 /* dac_nids for ALC660vd are in a different order - according to
16353 * Realtek's driver.
16354 * This should probably result in a different mixer for 6stack models
16355 * of ALC660vd codecs, but for now there is only 3stack mixer
16356 * - and it is the same as in 861vd.
16357 * adc_nids in ALC660vd are (is) the same as in 861vd
16359 static const hda_nid_t alc660vd_dac_nids[3] = {
16360 /* front, rear, clfe, rear_surr */
16364 static const hda_nid_t alc861vd_adc_nids[1] = {
16369 static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16372 /* FIXME: should be a matrix-type input source selection */
16373 static const struct hda_input_mux alc861vd_capture_source = {
16377 { "Front Mic", 0x1 },
16383 static const struct hda_input_mux alc861vd_dallas_capture_source = {
16387 { "Internal Mic", 0x1 },
16391 static const struct hda_input_mux alc861vd_hp_capture_source = {
16394 { "Front Mic", 0x0 },
16395 { "ATAPI Mic", 0x1 },
16402 static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16409 static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16410 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16411 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16412 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16413 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16420 static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16421 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16422 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16423 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16424 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16428 static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16429 { 6, alc861vd_6stack_ch6_init },
16430 { 8, alc861vd_6stack_ch8_init },
16433 static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16436 .name = "Channel Mode",
16437 .info = alc_ch_mode_info,
16438 .get = alc_ch_mode_get,
16439 .put = alc_ch_mode_put,
16444 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16445 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16447 static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16448 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16449 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16451 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16452 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16454 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16456 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16458 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16459 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16461 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16462 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16466 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16470 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16471 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16472 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16474 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16475 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16477 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16478 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16483 static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16484 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16487 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16489 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16493 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16494 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16495 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16500 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16501 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16506 static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16507 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16508 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16509 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16511 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16513 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16517 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16518 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16519 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16521 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16522 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16527 /* Pin assignment: Speaker=0x14, HP = 0x15,
16528 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16530 static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16531 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16532 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16533 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16534 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16535 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16536 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16537 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16538 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16539 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16540 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16544 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16545 * Front Mic=0x18, ATAPI Mic = 0x19,
16547 static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16548 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16549 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16550 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16551 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16552 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16553 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16554 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16555 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16561 * generic initialization of ADC, input mixers and output mixers
16563 static const struct hda_verb alc861vd_volume_init_verbs[] = {
16565 * Unmute ADC0 and set the default input to mic-in
16567 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16568 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16570 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16571 * the analog-loopback mixer widget
16573 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16578 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16580 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16583 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16587 * Set up output mixers (0x02 - 0x05)
16589 /* set vol=0 to output mixers */
16590 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16591 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16592 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16593 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16595 /* set up input amps for analog loopback */
16596 /* Amp Indices: DAC = 0, mixer = 1 */
16597 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16599 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16600 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16601 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16602 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16603 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16604 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16610 * 3-stack pin configuration:
16611 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16613 static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16615 * Set pin mode and muting
16617 /* set front pin widgets 0x14 for output */
16618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16620 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16622 /* Mic (rear) pin: input vref at 80% */
16623 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16624 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16625 /* Front Mic pin: input vref at 80% */
16626 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16627 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16628 /* Line In pin: input */
16629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16631 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16634 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16635 /* CD pin widget for input */
16636 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16642 * 6-stack pin configuration:
16644 static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16646 * Set pin mode and muting
16648 /* set front pin widgets 0x14 for output */
16649 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16650 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16651 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16653 /* Rear Pin: output 1 (0x0d) */
16654 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16655 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16657 /* CLFE Pin: output 2 (0x0e) */
16658 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16659 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16660 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16661 /* Side Pin: output 3 (0x0f) */
16662 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16663 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16664 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16666 /* Mic (rear) pin: input vref at 80% */
16667 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16668 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16669 /* Front Mic pin: input vref at 80% */
16670 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16671 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16672 /* Line In pin: input */
16673 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16674 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16675 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16676 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16677 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16678 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16679 /* CD pin widget for input */
16680 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16685 static const struct hda_verb alc861vd_eapd_verbs[] = {
16686 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16690 static const struct hda_verb alc660vd_eapd_verbs[] = {
16691 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16692 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16696 static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16699 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16700 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16701 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16705 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16707 struct alc_spec *spec = codec->spec;
16708 spec->autocfg.hp_pins[0] = 0x1b;
16709 spec->autocfg.speaker_pins[0] = 0x14;
16710 spec->automute = 1;
16711 spec->automute_mode = ALC_AUTOMUTE_AMP;
16714 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16716 alc_hp_automute(codec);
16717 alc88x_simple_mic_automute(codec);
16720 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16723 switch (res >> 26) {
16724 case ALC880_MIC_EVENT:
16725 alc88x_simple_mic_automute(codec);
16728 alc_sku_unsol_event(codec, res);
16733 static const struct hda_verb alc861vd_dallas_verbs[] = {
16734 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16735 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16736 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16737 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16741 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16742 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16743 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16744 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16745 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16746 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16748 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16750 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16752 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16754 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16755 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16757 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16759 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16760 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16761 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16762 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16763 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16764 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16766 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16771 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16772 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16773 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16778 /* toggle speaker-output according to the hp-jack state */
16779 static void alc861vd_dallas_setup(struct hda_codec *codec)
16781 struct alc_spec *spec = codec->spec;
16783 spec->autocfg.hp_pins[0] = 0x15;
16784 spec->autocfg.speaker_pins[0] = 0x14;
16785 spec->automute = 1;
16786 spec->automute_mode = ALC_AUTOMUTE_AMP;
16789 #ifdef CONFIG_SND_HDA_POWER_SAVE
16790 #define alc861vd_loopbacks alc880_loopbacks
16793 /* pcm configuration: identical with ALC880 */
16794 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16795 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16796 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16797 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16800 * configuration and preset
16802 static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16803 [ALC660VD_3ST] = "3stack-660",
16804 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16805 [ALC660VD_ASUS_V1S] = "asus-v1s",
16806 [ALC861VD_3ST] = "3stack",
16807 [ALC861VD_3ST_DIG] = "3stack-digout",
16808 [ALC861VD_6ST_DIG] = "6stack-digout",
16809 [ALC861VD_LENOVO] = "lenovo",
16810 [ALC861VD_DALLAS] = "dallas",
16811 [ALC861VD_HP] = "hp",
16812 [ALC861VD_AUTO] = "auto",
16815 static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16816 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16817 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16818 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16819 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16820 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16821 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16822 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16823 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16824 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16825 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16826 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16827 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16828 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16829 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16830 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16834 static const struct alc_config_preset alc861vd_presets[] = {
16836 .mixers = { alc861vd_3st_mixer },
16837 .init_verbs = { alc861vd_volume_init_verbs,
16838 alc861vd_3stack_init_verbs },
16839 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16840 .dac_nids = alc660vd_dac_nids,
16841 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16842 .channel_mode = alc861vd_3stack_2ch_modes,
16843 .input_mux = &alc861vd_capture_source,
16845 [ALC660VD_3ST_DIG] = {
16846 .mixers = { alc861vd_3st_mixer },
16847 .init_verbs = { alc861vd_volume_init_verbs,
16848 alc861vd_3stack_init_verbs },
16849 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16850 .dac_nids = alc660vd_dac_nids,
16851 .dig_out_nid = ALC861VD_DIGOUT_NID,
16852 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16853 .channel_mode = alc861vd_3stack_2ch_modes,
16854 .input_mux = &alc861vd_capture_source,
16857 .mixers = { alc861vd_3st_mixer },
16858 .init_verbs = { alc861vd_volume_init_verbs,
16859 alc861vd_3stack_init_verbs },
16860 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16861 .dac_nids = alc861vd_dac_nids,
16862 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16863 .channel_mode = alc861vd_3stack_2ch_modes,
16864 .input_mux = &alc861vd_capture_source,
16866 [ALC861VD_3ST_DIG] = {
16867 .mixers = { alc861vd_3st_mixer },
16868 .init_verbs = { alc861vd_volume_init_verbs,
16869 alc861vd_3stack_init_verbs },
16870 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16871 .dac_nids = alc861vd_dac_nids,
16872 .dig_out_nid = ALC861VD_DIGOUT_NID,
16873 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16874 .channel_mode = alc861vd_3stack_2ch_modes,
16875 .input_mux = &alc861vd_capture_source,
16877 [ALC861VD_6ST_DIG] = {
16878 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16879 .init_verbs = { alc861vd_volume_init_verbs,
16880 alc861vd_6stack_init_verbs },
16881 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16882 .dac_nids = alc861vd_dac_nids,
16883 .dig_out_nid = ALC861VD_DIGOUT_NID,
16884 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16885 .channel_mode = alc861vd_6stack_modes,
16886 .input_mux = &alc861vd_capture_source,
16888 [ALC861VD_LENOVO] = {
16889 .mixers = { alc861vd_lenovo_mixer },
16890 .init_verbs = { alc861vd_volume_init_verbs,
16891 alc861vd_3stack_init_verbs,
16892 alc861vd_eapd_verbs,
16893 alc861vd_lenovo_unsol_verbs },
16894 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16895 .dac_nids = alc660vd_dac_nids,
16896 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16897 .channel_mode = alc861vd_3stack_2ch_modes,
16898 .input_mux = &alc861vd_capture_source,
16899 .unsol_event = alc861vd_lenovo_unsol_event,
16900 .setup = alc861vd_lenovo_setup,
16901 .init_hook = alc861vd_lenovo_init_hook,
16903 [ALC861VD_DALLAS] = {
16904 .mixers = { alc861vd_dallas_mixer },
16905 .init_verbs = { alc861vd_dallas_verbs },
16906 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16907 .dac_nids = alc861vd_dac_nids,
16908 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16909 .channel_mode = alc861vd_3stack_2ch_modes,
16910 .input_mux = &alc861vd_dallas_capture_source,
16911 .unsol_event = alc_sku_unsol_event,
16912 .setup = alc861vd_dallas_setup,
16913 .init_hook = alc_hp_automute,
16916 .mixers = { alc861vd_hp_mixer },
16917 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16918 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16919 .dac_nids = alc861vd_dac_nids,
16920 .dig_out_nid = ALC861VD_DIGOUT_NID,
16921 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16922 .channel_mode = alc861vd_3stack_2ch_modes,
16923 .input_mux = &alc861vd_hp_capture_source,
16924 .unsol_event = alc_sku_unsol_event,
16925 .setup = alc861vd_dallas_setup,
16926 .init_hook = alc_hp_automute,
16928 [ALC660VD_ASUS_V1S] = {
16929 .mixers = { alc861vd_lenovo_mixer },
16930 .init_verbs = { alc861vd_volume_init_verbs,
16931 alc861vd_3stack_init_verbs,
16932 alc861vd_eapd_verbs,
16933 alc861vd_lenovo_unsol_verbs },
16934 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16935 .dac_nids = alc660vd_dac_nids,
16936 .dig_out_nid = ALC861VD_DIGOUT_NID,
16937 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16938 .channel_mode = alc861vd_3stack_2ch_modes,
16939 .input_mux = &alc861vd_capture_source,
16940 .unsol_event = alc861vd_lenovo_unsol_event,
16941 .setup = alc861vd_lenovo_setup,
16942 .init_hook = alc861vd_lenovo_init_hook,
16947 * BIOS auto configuration
16949 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16950 const struct auto_pin_cfg *cfg)
16952 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
16956 #define alc861vd_auto_init_multi_out alc882_auto_init_multi_out
16957 #define alc861vd_auto_init_hp_out alc882_auto_init_hp_out
16958 #define alc861vd_auto_init_analog_input alc882_auto_init_analog_input
16959 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
16961 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16962 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16964 /* add playback controls from the parsed DAC table */
16965 /* Based on ALC880 version. But ALC861VD has separate,
16966 * different NIDs for mute/unmute switch and volume control */
16967 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16968 const struct auto_pin_cfg *cfg)
16970 hda_nid_t nid_v, nid_s;
16971 int i, err, noutputs;
16973 noutputs = cfg->line_outs;
16974 if (spec->multi_ios > 0)
16975 noutputs += spec->multi_ios;
16977 for (i = 0; i < noutputs; i++) {
16980 if (!spec->multiout.dac_nids[i])
16982 nid_v = alc861vd_idx_to_mixer_vol(
16984 spec->multiout.dac_nids[i]));
16985 nid_s = alc861vd_idx_to_mixer_switch(
16987 spec->multiout.dac_nids[i]));
16989 name = alc_get_line_out_pfx(spec, i, true, &index);
16992 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16994 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16998 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17000 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17004 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17006 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17010 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17012 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17017 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17019 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17023 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17025 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17034 /* add playback controls for speaker and HP outputs */
17035 /* Based on ALC880 version. But ALC861VD has separate,
17036 * different NIDs for mute/unmute switch and volume control */
17037 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17038 hda_nid_t pin, const char *pfx)
17040 hda_nid_t nid_v, nid_s;
17046 if (alc880_is_fixed_pin(pin)) {
17047 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17048 /* specify the DAC as the extra output */
17049 if (!spec->multiout.hp_nid)
17050 spec->multiout.hp_nid = nid_v;
17052 spec->multiout.extra_out_nid[0] = nid_v;
17053 /* control HP volume/switch on the output mixer amp */
17054 nid_v = alc861vd_idx_to_mixer_vol(
17055 alc880_fixed_pin_idx(pin));
17056 nid_s = alc861vd_idx_to_mixer_switch(
17057 alc880_fixed_pin_idx(pin));
17059 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17060 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17063 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17064 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17067 } else if (alc880_is_multi_pin(pin)) {
17068 /* set manual connection */
17069 /* we have only a switch on HP-out PIN */
17070 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17071 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17078 /* parse the BIOS configuration and set up the alc_spec
17079 * return 1 if successful, 0 if the proper config is not found,
17080 * or a negative error code
17081 * Based on ALC880 version - had to change it to override
17082 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17083 static int alc861vd_parse_auto_config(struct hda_codec *codec)
17085 struct alc_spec *spec = codec->spec;
17087 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17089 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17093 if (!spec->autocfg.line_outs)
17094 return 0; /* can't find valid BIOS pin config */
17096 err = alc880_auto_fill_dac_nids(codec);
17099 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
17102 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17105 err = alc861vd_auto_create_extra_out(spec,
17106 spec->autocfg.speaker_pins[0],
17110 err = alc861vd_auto_create_extra_out(spec,
17111 spec->autocfg.hp_pins[0],
17115 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17119 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17121 alc_auto_parse_digital(codec);
17123 if (spec->kctls.list)
17124 add_mixer(spec, spec->kctls.list);
17126 spec->num_mux_defs = 1;
17127 spec->input_mux = &spec->private_imux[0];
17129 err = alc_auto_add_mic_boost(codec);
17133 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17138 /* additional initialization for auto-configuration model */
17139 static void alc861vd_auto_init(struct hda_codec *codec)
17141 struct alc_spec *spec = codec->spec;
17142 alc861vd_auto_init_multi_out(codec);
17143 alc861vd_auto_init_hp_out(codec);
17144 alc861vd_auto_init_analog_input(codec);
17145 alc861vd_auto_init_input_src(codec);
17146 alc_auto_init_digital(codec);
17147 if (spec->unsol_event)
17148 alc_inithook(codec);
17152 ALC660VD_FIX_ASUS_GPIO1
17156 static const struct alc_fixup alc861vd_fixups[] = {
17157 [ALC660VD_FIX_ASUS_GPIO1] = {
17158 .type = ALC_FIXUP_VERBS,
17159 .v.verbs = (const struct hda_verb[]) {
17160 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17161 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17162 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17168 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17169 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17173 static int patch_alc861vd(struct hda_codec *codec)
17175 struct alc_spec *spec;
17176 int err, board_config;
17178 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17182 codec->spec = spec;
17184 spec->mixer_nid = 0x0b;
17186 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17190 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17191 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17193 board_config = ALC861VD_AUTO;
17196 if (board_config == ALC861VD_AUTO) {
17197 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17198 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17201 if (board_config == ALC861VD_AUTO) {
17202 /* automatic parse from the BIOS config */
17203 err = alc861vd_parse_auto_config(codec);
17209 "hda_codec: Cannot set up configuration "
17210 "from BIOS. Using base mode...\n");
17211 board_config = ALC861VD_3ST;
17215 err = snd_hda_attach_beep_device(codec, 0x23);
17221 if (board_config != ALC861VD_AUTO)
17222 setup_preset(codec, &alc861vd_presets[board_config]);
17224 if (codec->vendor_id == 0x10ec0660) {
17225 /* always turn on EAPD */
17226 add_verb(spec, alc660vd_eapd_verbs);
17229 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17230 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17232 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17233 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17235 if (!spec->adc_nids) {
17236 spec->adc_nids = alc861vd_adc_nids;
17237 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17239 if (!spec->capsrc_nids)
17240 spec->capsrc_nids = alc861vd_capsrc_nids;
17242 set_capture_mixer(codec);
17243 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17245 spec->vmaster_nid = 0x02;
17247 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17249 codec->patch_ops = alc_patch_ops;
17251 if (board_config == ALC861VD_AUTO)
17252 spec->init_hook = alc861vd_auto_init;
17253 spec->shutup = alc_eapd_shutup;
17254 #ifdef CONFIG_SND_HDA_POWER_SAVE
17255 if (!spec->loopback.amplist)
17256 spec->loopback.amplist = alc861vd_loopbacks;
17265 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17266 * configuration. Each pin widget can choose any input DACs and a mixer.
17267 * Each ADC is connected from a mixer of all inputs. This makes possible
17268 * 6-channel independent captures.
17270 * In addition, an independent DAC for the multi-playback (not used in this
17273 #define ALC662_DIGOUT_NID 0x06
17274 #define ALC662_DIGIN_NID 0x0a
17276 static const hda_nid_t alc662_dac_nids[3] = {
17277 /* front, rear, clfe */
17281 static const hda_nid_t alc272_dac_nids[2] = {
17285 static const hda_nid_t alc662_adc_nids[2] = {
17290 static const hda_nid_t alc272_adc_nids[1] = {
17295 static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17296 static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17300 /* FIXME: should be a matrix-type input source selection */
17301 static const struct hda_input_mux alc662_capture_source = {
17305 { "Front Mic", 0x1 },
17311 static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17319 static const struct hda_input_mux alc663_capture_source = {
17323 { "Front Mic", 0x1 },
17328 #if 0 /* set to 1 for testing other input sources below */
17329 static const struct hda_input_mux alc272_nc10_capture_source = {
17332 { "Autoselect Mic", 0x0 },
17333 { "Internal Mic", 0x1 },
17334 { "In-0x02", 0x2 },
17335 { "In-0x03", 0x3 },
17336 { "In-0x04", 0x4 },
17337 { "In-0x05", 0x5 },
17338 { "In-0x06", 0x6 },
17339 { "In-0x07", 0x7 },
17340 { "In-0x08", 0x8 },
17341 { "In-0x09", 0x9 },
17342 { "In-0x0a", 0x0a },
17343 { "In-0x0b", 0x0b },
17344 { "In-0x0c", 0x0c },
17345 { "In-0x0d", 0x0d },
17346 { "In-0x0e", 0x0e },
17347 { "In-0x0f", 0x0f },
17355 static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17362 static const struct hda_verb alc662_3ST_ch2_init[] = {
17363 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17364 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17365 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17366 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17373 static const struct hda_verb alc662_3ST_ch6_init[] = {
17374 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17375 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17376 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17377 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17378 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17379 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17383 static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17384 { 2, alc662_3ST_ch2_init },
17385 { 6, alc662_3ST_ch6_init },
17391 static const struct hda_verb alc662_sixstack_ch6_init[] = {
17392 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17393 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17394 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17401 static const struct hda_verb alc662_sixstack_ch8_init[] = {
17402 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17403 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17404 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17408 static const struct hda_channel_mode alc662_5stack_modes[2] = {
17409 { 2, alc662_sixstack_ch6_init },
17410 { 6, alc662_sixstack_ch8_init },
17413 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17414 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17417 static const struct snd_kcontrol_new alc662_base_mixer[] = {
17418 /* output mixer control */
17419 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17420 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17421 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17422 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17423 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17424 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17425 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17426 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17429 /*Input mixer control */
17430 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17431 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17432 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17433 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17434 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17435 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17436 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17437 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17441 static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17442 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17443 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17445 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17446 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17447 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17448 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17449 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17450 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17451 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17452 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17456 static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17457 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17458 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17459 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17460 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17461 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17462 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17463 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17464 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17465 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17466 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17467 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17468 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17469 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17470 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17471 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17472 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17473 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17477 static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17478 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17479 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17480 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17481 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17482 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17483 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17484 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17490 static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17491 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17492 ALC262_HIPPO_MASTER_SWITCH,
17494 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17496 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17498 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17499 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17500 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17504 static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17505 ALC262_HIPPO_MASTER_SWITCH,
17506 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17507 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17508 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17509 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17510 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17511 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17512 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17518 static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17519 .ops = &snd_hda_bind_vol,
17521 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17522 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17527 static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17528 .ops = &snd_hda_bind_sw,
17530 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17531 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17536 static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17537 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17538 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17539 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17540 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17544 static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17545 .ops = &snd_hda_bind_sw,
17547 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17548 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17549 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17554 static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17555 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17556 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17557 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17558 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17559 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17560 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17565 static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17566 .ops = &snd_hda_bind_sw,
17568 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17569 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17570 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17575 static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17576 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17577 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17580 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17581 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17585 static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17586 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17587 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17588 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17589 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17591 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17592 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17596 static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17597 .ops = &snd_hda_bind_vol,
17599 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17600 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17605 static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17606 .ops = &snd_hda_bind_sw,
17608 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17609 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17614 static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17615 HDA_BIND_VOL("Master Playback Volume",
17616 &alc663_asus_two_bind_master_vol),
17617 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17618 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17619 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17621 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17625 static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17626 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17627 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17628 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17629 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17631 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17635 static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17636 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17637 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17638 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17639 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17640 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17643 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17644 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17645 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17649 static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17650 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17651 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17652 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17656 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17657 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17658 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17659 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17663 static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17664 .ops = &snd_hda_bind_sw,
17666 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17667 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17668 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17669 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17670 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17675 static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17676 .ops = &snd_hda_bind_sw,
17678 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17679 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17684 static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17685 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17686 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17687 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17688 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17689 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17690 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17691 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17697 static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17698 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17699 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17700 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17701 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17702 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17709 static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17711 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17712 .name = "Channel Mode",
17713 .info = alc_ch_mode_info,
17714 .get = alc_ch_mode_get,
17715 .put = alc_ch_mode_put,
17720 static const struct hda_verb alc662_init_verbs[] = {
17721 /* ADC: mute amp left and right */
17722 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17723 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17727 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17728 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17729 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17730 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17732 /* Front Pin: output 0 (0x0c) */
17733 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17736 /* Rear Pin: output 1 (0x0d) */
17737 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17738 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17740 /* CLFE Pin: output 2 (0x0e) */
17741 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17742 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17744 /* Mic (rear) pin: input vref at 80% */
17745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17747 /* Front Mic pin: input vref at 80% */
17748 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17749 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17750 /* Line In pin: input */
17751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17753 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17754 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17756 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17757 /* CD pin widget for input */
17758 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17760 /* FIXME: use matrix-type input source selection */
17761 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17763 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17769 static const struct hda_verb alc662_eapd_init_verbs[] = {
17770 /* always trun on EAPD */
17771 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17772 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17776 static const struct hda_verb alc662_sue_init_verbs[] = {
17777 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17778 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17782 static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17783 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17784 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17788 /* Set Unsolicited Event*/
17789 static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17790 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17791 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17795 static const struct hda_verb alc663_m51va_init_verbs[] = {
17796 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17797 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17798 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17799 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17800 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17801 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17802 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17803 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17804 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17808 static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
17809 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17810 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17811 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17812 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17813 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17814 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17815 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17819 static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17820 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17821 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17822 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17823 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17826 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17827 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17831 static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
17832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17833 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17834 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17835 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17836 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17837 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17838 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17842 static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17843 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17844 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17845 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17846 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17849 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17850 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17851 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17852 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17853 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17854 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17858 static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17860 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17861 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17862 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17864 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17865 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17866 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17867 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17868 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17869 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17870 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17874 static const struct hda_verb alc663_g71v_init_verbs[] = {
17875 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17876 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17877 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17879 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17880 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17881 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17883 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17884 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17885 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17889 static const struct hda_verb alc663_g50v_init_verbs[] = {
17890 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17891 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17892 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17894 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17895 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17899 static const struct hda_verb alc662_ecs_init_verbs[] = {
17900 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17901 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17902 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17903 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17907 static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
17908 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17909 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17910 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17911 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17912 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17913 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17914 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17917 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17918 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17922 static const struct hda_verb alc272_dell_init_verbs[] = {
17923 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17924 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17925 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17926 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17927 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17928 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17929 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17932 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17933 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17937 static const struct hda_verb alc663_mode7_init_verbs[] = {
17938 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17939 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17940 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17941 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17943 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17944 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17945 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17946 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17947 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17948 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17949 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17950 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17951 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17952 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17956 static const struct hda_verb alc663_mode8_init_verbs[] = {
17957 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17958 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17959 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17960 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17961 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17962 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17963 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17964 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17965 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17966 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17967 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17968 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17970 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17971 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17972 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17976 static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17977 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17978 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17982 static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17983 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17984 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17988 static void alc662_lenovo_101e_setup(struct hda_codec *codec)
17990 struct alc_spec *spec = codec->spec;
17992 spec->autocfg.hp_pins[0] = 0x1b;
17993 spec->autocfg.line_out_pins[0] = 0x14;
17994 spec->autocfg.speaker_pins[0] = 0x15;
17995 spec->automute = 1;
17996 spec->detect_line = 1;
17997 spec->automute_lines = 1;
17998 spec->automute_mode = ALC_AUTOMUTE_AMP;
18001 static void alc662_eeepc_setup(struct hda_codec *codec)
18003 struct alc_spec *spec = codec->spec;
18005 alc262_hippo1_setup(codec);
18006 spec->ext_mic.pin = 0x18;
18007 spec->ext_mic.mux_idx = 0;
18008 spec->int_mic.pin = 0x19;
18009 spec->int_mic.mux_idx = 1;
18010 spec->auto_mic = 1;
18013 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18015 struct alc_spec *spec = codec->spec;
18017 spec->autocfg.hp_pins[0] = 0x14;
18018 spec->autocfg.speaker_pins[0] = 0x1b;
18019 spec->automute = 1;
18020 spec->automute_mode = ALC_AUTOMUTE_AMP;
18023 static void alc663_m51va_setup(struct hda_codec *codec)
18025 struct alc_spec *spec = codec->spec;
18026 spec->autocfg.hp_pins[0] = 0x21;
18027 spec->autocfg.speaker_pins[0] = 0x14;
18028 spec->automute_mixer_nid[0] = 0x0c;
18029 spec->automute = 1;
18030 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18031 spec->ext_mic.pin = 0x18;
18032 spec->ext_mic.mux_idx = 0;
18033 spec->int_mic.pin = 0x12;
18034 spec->int_mic.mux_idx = 9;
18035 spec->auto_mic = 1;
18038 /* ***************** Mode1 ******************************/
18039 static void alc663_mode1_setup(struct hda_codec *codec)
18041 struct alc_spec *spec = codec->spec;
18042 spec->autocfg.hp_pins[0] = 0x21;
18043 spec->autocfg.speaker_pins[0] = 0x14;
18044 spec->automute_mixer_nid[0] = 0x0c;
18045 spec->automute = 1;
18046 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18047 spec->ext_mic.pin = 0x18;
18048 spec->ext_mic.mux_idx = 0;
18049 spec->int_mic.pin = 0x19;
18050 spec->int_mic.mux_idx = 1;
18051 spec->auto_mic = 1;
18054 /* ***************** Mode2 ******************************/
18055 static void alc662_mode2_setup(struct hda_codec *codec)
18057 struct alc_spec *spec = codec->spec;
18058 spec->autocfg.hp_pins[0] = 0x1b;
18059 spec->autocfg.speaker_pins[0] = 0x14;
18060 spec->automute = 1;
18061 spec->automute_mode = ALC_AUTOMUTE_PIN;
18062 spec->ext_mic.pin = 0x18;
18063 spec->ext_mic.mux_idx = 0;
18064 spec->int_mic.pin = 0x19;
18065 spec->int_mic.mux_idx = 1;
18066 spec->auto_mic = 1;
18069 /* ***************** Mode3 ******************************/
18070 static void alc663_mode3_setup(struct hda_codec *codec)
18072 struct alc_spec *spec = codec->spec;
18073 spec->autocfg.hp_pins[0] = 0x21;
18074 spec->autocfg.hp_pins[0] = 0x15;
18075 spec->autocfg.speaker_pins[0] = 0x14;
18076 spec->automute = 1;
18077 spec->automute_mode = ALC_AUTOMUTE_PIN;
18078 spec->ext_mic.pin = 0x18;
18079 spec->ext_mic.mux_idx = 0;
18080 spec->int_mic.pin = 0x19;
18081 spec->int_mic.mux_idx = 1;
18082 spec->auto_mic = 1;
18085 /* ***************** Mode4 ******************************/
18086 static void alc663_mode4_setup(struct hda_codec *codec)
18088 struct alc_spec *spec = codec->spec;
18089 spec->autocfg.hp_pins[0] = 0x21;
18090 spec->autocfg.speaker_pins[0] = 0x14;
18091 spec->autocfg.speaker_pins[1] = 0x16;
18092 spec->automute_mixer_nid[0] = 0x0c;
18093 spec->automute_mixer_nid[1] = 0x0e;
18094 spec->automute = 1;
18095 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18096 spec->ext_mic.pin = 0x18;
18097 spec->ext_mic.mux_idx = 0;
18098 spec->int_mic.pin = 0x19;
18099 spec->int_mic.mux_idx = 1;
18100 spec->auto_mic = 1;
18103 /* ***************** Mode5 ******************************/
18104 static void alc663_mode5_setup(struct hda_codec *codec)
18106 struct alc_spec *spec = codec->spec;
18107 spec->autocfg.hp_pins[0] = 0x15;
18108 spec->autocfg.speaker_pins[0] = 0x14;
18109 spec->autocfg.speaker_pins[1] = 0x16;
18110 spec->automute_mixer_nid[0] = 0x0c;
18111 spec->automute_mixer_nid[1] = 0x0e;
18112 spec->automute = 1;
18113 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18114 spec->ext_mic.pin = 0x18;
18115 spec->ext_mic.mux_idx = 0;
18116 spec->int_mic.pin = 0x19;
18117 spec->int_mic.mux_idx = 1;
18118 spec->auto_mic = 1;
18121 /* ***************** Mode6 ******************************/
18122 static void alc663_mode6_setup(struct hda_codec *codec)
18124 struct alc_spec *spec = codec->spec;
18125 spec->autocfg.hp_pins[0] = 0x1b;
18126 spec->autocfg.hp_pins[0] = 0x15;
18127 spec->autocfg.speaker_pins[0] = 0x14;
18128 spec->automute_mixer_nid[0] = 0x0c;
18129 spec->automute = 1;
18130 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18131 spec->ext_mic.pin = 0x18;
18132 spec->ext_mic.mux_idx = 0;
18133 spec->int_mic.pin = 0x19;
18134 spec->int_mic.mux_idx = 1;
18135 spec->auto_mic = 1;
18138 /* ***************** Mode7 ******************************/
18139 static void alc663_mode7_setup(struct hda_codec *codec)
18141 struct alc_spec *spec = codec->spec;
18142 spec->autocfg.hp_pins[0] = 0x1b;
18143 spec->autocfg.hp_pins[0] = 0x21;
18144 spec->autocfg.speaker_pins[0] = 0x14;
18145 spec->autocfg.speaker_pins[0] = 0x17;
18146 spec->automute = 1;
18147 spec->automute_mode = ALC_AUTOMUTE_PIN;
18148 spec->ext_mic.pin = 0x18;
18149 spec->ext_mic.mux_idx = 0;
18150 spec->int_mic.pin = 0x19;
18151 spec->int_mic.mux_idx = 1;
18152 spec->auto_mic = 1;
18155 /* ***************** Mode8 ******************************/
18156 static void alc663_mode8_setup(struct hda_codec *codec)
18158 struct alc_spec *spec = codec->spec;
18159 spec->autocfg.hp_pins[0] = 0x21;
18160 spec->autocfg.hp_pins[1] = 0x15;
18161 spec->autocfg.speaker_pins[0] = 0x14;
18162 spec->autocfg.speaker_pins[0] = 0x17;
18163 spec->automute = 1;
18164 spec->automute_mode = ALC_AUTOMUTE_PIN;
18165 spec->ext_mic.pin = 0x18;
18166 spec->ext_mic.mux_idx = 0;
18167 spec->int_mic.pin = 0x12;
18168 spec->int_mic.mux_idx = 9;
18169 spec->auto_mic = 1;
18172 static void alc663_g71v_setup(struct hda_codec *codec)
18174 struct alc_spec *spec = codec->spec;
18175 spec->autocfg.hp_pins[0] = 0x21;
18176 spec->autocfg.line_out_pins[0] = 0x15;
18177 spec->autocfg.speaker_pins[0] = 0x14;
18178 spec->automute = 1;
18179 spec->automute_mode = ALC_AUTOMUTE_AMP;
18180 spec->detect_line = 1;
18181 spec->automute_lines = 1;
18182 spec->ext_mic.pin = 0x18;
18183 spec->ext_mic.mux_idx = 0;
18184 spec->int_mic.pin = 0x12;
18185 spec->int_mic.mux_idx = 9;
18186 spec->auto_mic = 1;
18189 #define alc663_g50v_setup alc663_m51va_setup
18191 static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18192 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18193 ALC262_HIPPO_MASTER_SWITCH,
18195 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18196 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18197 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18199 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18200 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18201 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18205 static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18206 /* Master Playback automatically created from Speaker and Headphone */
18207 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18208 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18209 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18210 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18216 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18217 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18218 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18222 #ifdef CONFIG_SND_HDA_POWER_SAVE
18223 #define alc662_loopbacks alc880_loopbacks
18227 /* pcm configuration: identical with ALC880 */
18228 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
18229 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
18230 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
18231 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
18234 * configuration and preset
18236 static const char * const alc662_models[ALC662_MODEL_LAST] = {
18237 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18238 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18239 [ALC662_3ST_6ch] = "3stack-6ch",
18240 [ALC662_5ST_DIG] = "5stack-dig",
18241 [ALC662_LENOVO_101E] = "lenovo-101e",
18242 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18243 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18244 [ALC662_ECS] = "ecs",
18245 [ALC663_ASUS_M51VA] = "m51va",
18246 [ALC663_ASUS_G71V] = "g71v",
18247 [ALC663_ASUS_H13] = "h13",
18248 [ALC663_ASUS_G50V] = "g50v",
18249 [ALC663_ASUS_MODE1] = "asus-mode1",
18250 [ALC662_ASUS_MODE2] = "asus-mode2",
18251 [ALC663_ASUS_MODE3] = "asus-mode3",
18252 [ALC663_ASUS_MODE4] = "asus-mode4",
18253 [ALC663_ASUS_MODE5] = "asus-mode5",
18254 [ALC663_ASUS_MODE6] = "asus-mode6",
18255 [ALC663_ASUS_MODE7] = "asus-mode7",
18256 [ALC663_ASUS_MODE8] = "asus-mode8",
18257 [ALC272_DELL] = "dell",
18258 [ALC272_DELL_ZM1] = "dell-zm1",
18259 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18260 [ALC662_AUTO] = "auto",
18263 static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18264 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18265 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18266 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18267 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18268 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18269 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18270 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18271 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18272 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18273 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18274 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18275 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18276 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18277 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18278 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18279 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18280 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18281 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18282 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18283 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18284 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18285 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18286 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18287 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18288 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18289 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18290 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18291 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18292 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18293 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18294 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18295 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18296 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18297 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18298 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18299 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18300 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18301 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18302 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18303 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18304 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18305 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18306 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18307 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18308 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18309 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18310 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18311 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18312 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18313 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18314 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18315 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18316 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18317 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18318 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18319 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18320 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18321 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18322 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18323 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18324 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18325 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18326 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18327 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18328 ALC662_3ST_6ch_DIG),
18329 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18330 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18331 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18332 ALC662_3ST_6ch_DIG),
18333 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18334 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18335 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18336 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18337 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18338 ALC662_3ST_6ch_DIG),
18339 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18341 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18345 static const struct alc_config_preset alc662_presets[] = {
18346 [ALC662_3ST_2ch_DIG] = {
18347 .mixers = { alc662_3ST_2ch_mixer },
18348 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18349 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18350 .dac_nids = alc662_dac_nids,
18351 .dig_out_nid = ALC662_DIGOUT_NID,
18352 .dig_in_nid = ALC662_DIGIN_NID,
18353 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18354 .channel_mode = alc662_3ST_2ch_modes,
18355 .input_mux = &alc662_capture_source,
18357 [ALC662_3ST_6ch_DIG] = {
18358 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18359 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18360 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18361 .dac_nids = alc662_dac_nids,
18362 .dig_out_nid = ALC662_DIGOUT_NID,
18363 .dig_in_nid = ALC662_DIGIN_NID,
18364 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18365 .channel_mode = alc662_3ST_6ch_modes,
18367 .input_mux = &alc662_capture_source,
18369 [ALC662_3ST_6ch] = {
18370 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18371 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18372 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18373 .dac_nids = alc662_dac_nids,
18374 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18375 .channel_mode = alc662_3ST_6ch_modes,
18377 .input_mux = &alc662_capture_source,
18379 [ALC662_5ST_DIG] = {
18380 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18381 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18382 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18383 .dac_nids = alc662_dac_nids,
18384 .dig_out_nid = ALC662_DIGOUT_NID,
18385 .dig_in_nid = ALC662_DIGIN_NID,
18386 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18387 .channel_mode = alc662_5stack_modes,
18388 .input_mux = &alc662_capture_source,
18390 [ALC662_LENOVO_101E] = {
18391 .mixers = { alc662_lenovo_101e_mixer },
18392 .init_verbs = { alc662_init_verbs,
18393 alc662_eapd_init_verbs,
18394 alc662_sue_init_verbs },
18395 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18396 .dac_nids = alc662_dac_nids,
18397 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18398 .channel_mode = alc662_3ST_2ch_modes,
18399 .input_mux = &alc662_lenovo_101e_capture_source,
18400 .unsol_event = alc_sku_unsol_event,
18401 .setup = alc662_lenovo_101e_setup,
18402 .init_hook = alc_inithook,
18404 [ALC662_ASUS_EEEPC_P701] = {
18405 .mixers = { alc662_eeepc_p701_mixer },
18406 .init_verbs = { alc662_init_verbs,
18407 alc662_eapd_init_verbs,
18408 alc662_eeepc_sue_init_verbs },
18409 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18410 .dac_nids = alc662_dac_nids,
18411 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18412 .channel_mode = alc662_3ST_2ch_modes,
18413 .unsol_event = alc_sku_unsol_event,
18414 .setup = alc662_eeepc_setup,
18415 .init_hook = alc_inithook,
18417 [ALC662_ASUS_EEEPC_EP20] = {
18418 .mixers = { alc662_eeepc_ep20_mixer,
18419 alc662_chmode_mixer },
18420 .init_verbs = { alc662_init_verbs,
18421 alc662_eapd_init_verbs,
18422 alc662_eeepc_ep20_sue_init_verbs },
18423 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18424 .dac_nids = alc662_dac_nids,
18425 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18426 .channel_mode = alc662_3ST_6ch_modes,
18427 .input_mux = &alc662_lenovo_101e_capture_source,
18428 .unsol_event = alc_sku_unsol_event,
18429 .setup = alc662_eeepc_ep20_setup,
18430 .init_hook = alc_inithook,
18433 .mixers = { alc662_ecs_mixer },
18434 .init_verbs = { alc662_init_verbs,
18435 alc662_eapd_init_verbs,
18436 alc662_ecs_init_verbs },
18437 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18438 .dac_nids = alc662_dac_nids,
18439 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18440 .channel_mode = alc662_3ST_2ch_modes,
18441 .unsol_event = alc_sku_unsol_event,
18442 .setup = alc662_eeepc_setup,
18443 .init_hook = alc_inithook,
18445 [ALC663_ASUS_M51VA] = {
18446 .mixers = { alc663_m51va_mixer },
18447 .init_verbs = { alc662_init_verbs,
18448 alc662_eapd_init_verbs,
18449 alc663_m51va_init_verbs },
18450 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18451 .dac_nids = alc662_dac_nids,
18452 .dig_out_nid = ALC662_DIGOUT_NID,
18453 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18454 .channel_mode = alc662_3ST_2ch_modes,
18455 .unsol_event = alc_sku_unsol_event,
18456 .setup = alc663_m51va_setup,
18457 .init_hook = alc_inithook,
18459 [ALC663_ASUS_G71V] = {
18460 .mixers = { alc663_g71v_mixer },
18461 .init_verbs = { alc662_init_verbs,
18462 alc662_eapd_init_verbs,
18463 alc663_g71v_init_verbs },
18464 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18465 .dac_nids = alc662_dac_nids,
18466 .dig_out_nid = ALC662_DIGOUT_NID,
18467 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18468 .channel_mode = alc662_3ST_2ch_modes,
18469 .unsol_event = alc_sku_unsol_event,
18470 .setup = alc663_g71v_setup,
18471 .init_hook = alc_inithook,
18473 [ALC663_ASUS_H13] = {
18474 .mixers = { alc663_m51va_mixer },
18475 .init_verbs = { alc662_init_verbs,
18476 alc662_eapd_init_verbs,
18477 alc663_m51va_init_verbs },
18478 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18479 .dac_nids = alc662_dac_nids,
18480 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18481 .channel_mode = alc662_3ST_2ch_modes,
18482 .setup = alc663_m51va_setup,
18483 .unsol_event = alc_sku_unsol_event,
18484 .init_hook = alc_inithook,
18486 [ALC663_ASUS_G50V] = {
18487 .mixers = { alc663_g50v_mixer },
18488 .init_verbs = { alc662_init_verbs,
18489 alc662_eapd_init_verbs,
18490 alc663_g50v_init_verbs },
18491 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18492 .dac_nids = alc662_dac_nids,
18493 .dig_out_nid = ALC662_DIGOUT_NID,
18494 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18495 .channel_mode = alc662_3ST_6ch_modes,
18496 .input_mux = &alc663_capture_source,
18497 .unsol_event = alc_sku_unsol_event,
18498 .setup = alc663_g50v_setup,
18499 .init_hook = alc_inithook,
18501 [ALC663_ASUS_MODE1] = {
18502 .mixers = { alc663_m51va_mixer },
18503 .cap_mixer = alc662_auto_capture_mixer,
18504 .init_verbs = { alc662_init_verbs,
18505 alc662_eapd_init_verbs,
18506 alc663_21jd_amic_init_verbs },
18507 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18509 .dac_nids = alc662_dac_nids,
18510 .dig_out_nid = ALC662_DIGOUT_NID,
18511 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18512 .channel_mode = alc662_3ST_2ch_modes,
18513 .unsol_event = alc_sku_unsol_event,
18514 .setup = alc663_mode1_setup,
18515 .init_hook = alc_inithook,
18517 [ALC662_ASUS_MODE2] = {
18518 .mixers = { alc662_1bjd_mixer },
18519 .cap_mixer = alc662_auto_capture_mixer,
18520 .init_verbs = { alc662_init_verbs,
18521 alc662_eapd_init_verbs,
18522 alc662_1bjd_amic_init_verbs },
18523 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18524 .dac_nids = alc662_dac_nids,
18525 .dig_out_nid = ALC662_DIGOUT_NID,
18526 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18527 .channel_mode = alc662_3ST_2ch_modes,
18528 .unsol_event = alc_sku_unsol_event,
18529 .setup = alc662_mode2_setup,
18530 .init_hook = alc_inithook,
18532 [ALC663_ASUS_MODE3] = {
18533 .mixers = { alc663_two_hp_m1_mixer },
18534 .cap_mixer = alc662_auto_capture_mixer,
18535 .init_verbs = { alc662_init_verbs,
18536 alc662_eapd_init_verbs,
18537 alc663_two_hp_amic_m1_init_verbs },
18538 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18540 .dac_nids = alc662_dac_nids,
18541 .dig_out_nid = ALC662_DIGOUT_NID,
18542 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18543 .channel_mode = alc662_3ST_2ch_modes,
18544 .unsol_event = alc_sku_unsol_event,
18545 .setup = alc663_mode3_setup,
18546 .init_hook = alc_inithook,
18548 [ALC663_ASUS_MODE4] = {
18549 .mixers = { alc663_asus_21jd_clfe_mixer },
18550 .cap_mixer = alc662_auto_capture_mixer,
18551 .init_verbs = { alc662_init_verbs,
18552 alc662_eapd_init_verbs,
18553 alc663_21jd_amic_init_verbs},
18554 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18556 .dac_nids = alc662_dac_nids,
18557 .dig_out_nid = ALC662_DIGOUT_NID,
18558 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18559 .channel_mode = alc662_3ST_2ch_modes,
18560 .unsol_event = alc_sku_unsol_event,
18561 .setup = alc663_mode4_setup,
18562 .init_hook = alc_inithook,
18564 [ALC663_ASUS_MODE5] = {
18565 .mixers = { alc663_asus_15jd_clfe_mixer },
18566 .cap_mixer = alc662_auto_capture_mixer,
18567 .init_verbs = { alc662_init_verbs,
18568 alc662_eapd_init_verbs,
18569 alc663_15jd_amic_init_verbs },
18570 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18572 .dac_nids = alc662_dac_nids,
18573 .dig_out_nid = ALC662_DIGOUT_NID,
18574 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18575 .channel_mode = alc662_3ST_2ch_modes,
18576 .unsol_event = alc_sku_unsol_event,
18577 .setup = alc663_mode5_setup,
18578 .init_hook = alc_inithook,
18580 [ALC663_ASUS_MODE6] = {
18581 .mixers = { alc663_two_hp_m2_mixer },
18582 .cap_mixer = alc662_auto_capture_mixer,
18583 .init_verbs = { alc662_init_verbs,
18584 alc662_eapd_init_verbs,
18585 alc663_two_hp_amic_m2_init_verbs },
18586 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18588 .dac_nids = alc662_dac_nids,
18589 .dig_out_nid = ALC662_DIGOUT_NID,
18590 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18591 .channel_mode = alc662_3ST_2ch_modes,
18592 .unsol_event = alc_sku_unsol_event,
18593 .setup = alc663_mode6_setup,
18594 .init_hook = alc_inithook,
18596 [ALC663_ASUS_MODE7] = {
18597 .mixers = { alc663_mode7_mixer },
18598 .cap_mixer = alc662_auto_capture_mixer,
18599 .init_verbs = { alc662_init_verbs,
18600 alc662_eapd_init_verbs,
18601 alc663_mode7_init_verbs },
18602 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18604 .dac_nids = alc662_dac_nids,
18605 .dig_out_nid = ALC662_DIGOUT_NID,
18606 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18607 .channel_mode = alc662_3ST_2ch_modes,
18608 .unsol_event = alc_sku_unsol_event,
18609 .setup = alc663_mode7_setup,
18610 .init_hook = alc_inithook,
18612 [ALC663_ASUS_MODE8] = {
18613 .mixers = { alc663_mode8_mixer },
18614 .cap_mixer = alc662_auto_capture_mixer,
18615 .init_verbs = { alc662_init_verbs,
18616 alc662_eapd_init_verbs,
18617 alc663_mode8_init_verbs },
18618 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18620 .dac_nids = alc662_dac_nids,
18621 .dig_out_nid = ALC662_DIGOUT_NID,
18622 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18623 .channel_mode = alc662_3ST_2ch_modes,
18624 .unsol_event = alc_sku_unsol_event,
18625 .setup = alc663_mode8_setup,
18626 .init_hook = alc_inithook,
18629 .mixers = { alc663_m51va_mixer },
18630 .cap_mixer = alc272_auto_capture_mixer,
18631 .init_verbs = { alc662_init_verbs,
18632 alc662_eapd_init_verbs,
18633 alc272_dell_init_verbs },
18634 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18635 .dac_nids = alc272_dac_nids,
18636 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18637 .adc_nids = alc272_adc_nids,
18638 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18639 .capsrc_nids = alc272_capsrc_nids,
18640 .channel_mode = alc662_3ST_2ch_modes,
18641 .unsol_event = alc_sku_unsol_event,
18642 .setup = alc663_m51va_setup,
18643 .init_hook = alc_inithook,
18645 [ALC272_DELL_ZM1] = {
18646 .mixers = { alc663_m51va_mixer },
18647 .cap_mixer = alc662_auto_capture_mixer,
18648 .init_verbs = { alc662_init_verbs,
18649 alc662_eapd_init_verbs,
18650 alc272_dell_zm1_init_verbs },
18651 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18652 .dac_nids = alc272_dac_nids,
18653 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18654 .adc_nids = alc662_adc_nids,
18656 .capsrc_nids = alc662_capsrc_nids,
18657 .channel_mode = alc662_3ST_2ch_modes,
18658 .unsol_event = alc_sku_unsol_event,
18659 .setup = alc663_m51va_setup,
18660 .init_hook = alc_inithook,
18662 [ALC272_SAMSUNG_NC10] = {
18663 .mixers = { alc272_nc10_mixer },
18664 .init_verbs = { alc662_init_verbs,
18665 alc662_eapd_init_verbs,
18666 alc663_21jd_amic_init_verbs },
18667 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18668 .dac_nids = alc272_dac_nids,
18669 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18670 .channel_mode = alc662_3ST_2ch_modes,
18671 /*.input_mux = &alc272_nc10_capture_source,*/
18672 .unsol_event = alc_sku_unsol_event,
18673 .setup = alc663_mode4_setup,
18674 .init_hook = alc_inithook,
18680 * BIOS auto configuration
18683 /* convert from MIX nid to DAC */
18684 static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18689 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18690 for (i = 0; i < num; i++) {
18691 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18697 /* go down to the selector widget before the mixer */
18698 static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18701 int num = snd_hda_get_connections(codec, pin, srcs,
18704 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18709 /* get MIX nid connected to the given pin targeted to DAC */
18710 static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18716 pin = alc_go_down_to_selector(codec, pin);
18717 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18718 for (i = 0; i < num; i++) {
18719 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18725 /* select the connection from pin to DAC if needed */
18726 static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18732 pin = alc_go_down_to_selector(codec, pin);
18733 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18736 for (i = 0; i < num; i++) {
18737 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18738 snd_hda_codec_update_cache(codec, pin, 0,
18739 AC_VERB_SET_CONNECT_SEL, i);
18746 /* look for an empty DAC slot */
18747 static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18749 struct alc_spec *spec = codec->spec;
18753 pin = alc_go_down_to_selector(codec, pin);
18754 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18755 for (i = 0; i < num; i++) {
18756 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18759 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18760 spec->multiout.num_dacs))
18762 if (spec->multiout.hp_nid == nid)
18764 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18765 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18772 static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18774 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18775 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18776 return alc_auto_look_for_dac(codec, pin);
18780 /* fill in the dac_nids table from the parsed pin configuration */
18781 static int alc662_auto_fill_dac_nids(struct hda_codec *codec)
18783 struct alc_spec *spec = codec->spec;
18784 const struct auto_pin_cfg *cfg = &spec->autocfg;
18789 spec->multiout.num_dacs = 0;
18790 spec->multiout.hp_nid = 0;
18791 spec->multiout.extra_out_nid[0] = 0;
18792 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18793 spec->multiout.dac_nids = spec->private_dac_nids;
18795 /* fill hard-wired DACs first */
18797 for (i = 0; i < cfg->line_outs; i++)
18798 spec->private_dac_nids[i] =
18799 get_dac_if_single(codec, cfg->line_out_pins[i]);
18801 spec->multiout.hp_nid =
18802 get_dac_if_single(codec, cfg->hp_pins[0]);
18803 if (cfg->speaker_outs)
18804 spec->multiout.extra_out_nid[0] =
18805 get_dac_if_single(codec, cfg->speaker_pins[0]);
18808 for (i = 0; i < cfg->line_outs; i++) {
18809 hda_nid_t pin = cfg->line_out_pins[i];
18810 if (spec->private_dac_nids[i])
18812 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18813 if (!spec->private_dac_nids[i] && !redone) {
18814 /* if we can't find primary DACs, re-probe without
18815 * checking the hard-wired DACs
18822 for (i = 0; i < cfg->line_outs; i++) {
18823 if (spec->private_dac_nids[i])
18824 spec->multiout.num_dacs++;
18826 memmove(spec->private_dac_nids + i,
18827 spec->private_dac_nids + i + 1,
18828 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
18834 static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18835 hda_nid_t nid, int idx, unsigned int chs)
18837 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
18838 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18841 static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18842 hda_nid_t nid, int idx, unsigned int chs)
18844 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
18845 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18848 #define alc662_add_vol_ctl(spec, pfx, nid, chs) \
18849 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
18850 #define alc662_add_sw_ctl(spec, pfx, nid, chs) \
18851 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
18852 #define alc662_add_stereo_vol(spec, pfx, nid) \
18853 alc662_add_vol_ctl(spec, pfx, nid, 3)
18854 #define alc662_add_stereo_sw(spec, pfx, nid) \
18855 alc662_add_sw_ctl(spec, pfx, nid, 3)
18857 /* add playback controls from the parsed DAC table */
18858 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
18859 const struct auto_pin_cfg *cfg)
18861 struct alc_spec *spec = codec->spec;
18862 hda_nid_t nid, mix, pin;
18863 int i, err, noutputs;
18865 noutputs = cfg->line_outs;
18866 if (spec->multi_ios > 0)
18867 noutputs += spec->multi_ios;
18869 for (i = 0; i < noutputs; i++) {
18872 nid = spec->multiout.dac_nids[i];
18875 if (i >= cfg->line_outs)
18876 pin = spec->multi_io[i - 1].pin;
18878 pin = cfg->line_out_pins[i];
18879 mix = alc_auto_dac_to_mix(codec, pin, nid);
18882 name = alc_get_line_out_pfx(spec, i, true, &index);
18885 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
18888 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
18891 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
18894 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
18898 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
18901 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
18909 /* add playback controls for speaker and HP outputs */
18910 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18911 hda_nid_t dac, const char *pfx)
18913 struct alc_spec *spec = codec->spec;
18920 /* the corresponding DAC is already occupied */
18921 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18922 return 0; /* no way */
18923 /* create a switch only */
18924 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18925 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18928 mix = alc_auto_dac_to_mix(codec, pin, dac);
18931 err = alc662_add_vol_ctl(spec, pfx, dac, 3);
18934 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18940 /* create playback/capture controls for input pins */
18941 #define alc662_auto_create_input_ctls \
18942 alc882_auto_create_input_ctls
18944 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18945 hda_nid_t nid, int pin_type,
18949 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18951 alc_set_pin_output(codec, nid, pin_type);
18952 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18953 for (i = 0; i < num; i++) {
18954 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
18956 /* need the manual connection? */
18958 snd_hda_codec_write(codec, nid, 0,
18959 AC_VERB_SET_CONNECT_SEL, i);
18960 /* unmute mixer widget inputs */
18961 snd_hda_codec_write(codec, srcs[i], 0,
18962 AC_VERB_SET_AMP_GAIN_MUTE,
18964 snd_hda_codec_write(codec, srcs[i], 0,
18965 AC_VERB_SET_AMP_GAIN_MUTE,
18971 static void alc662_auto_init_multi_out(struct hda_codec *codec)
18973 struct alc_spec *spec = codec->spec;
18974 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18977 for (i = 0; i <= HDA_SIDE; i++) {
18978 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18980 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
18981 spec->multiout.dac_nids[i]);
18985 static void alc662_auto_init_hp_out(struct hda_codec *codec)
18987 struct alc_spec *spec = codec->spec;
18990 pin = spec->autocfg.hp_pins[0];
18992 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18993 spec->multiout.hp_nid);
18994 pin = spec->autocfg.speaker_pins[0];
18996 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18997 spec->multiout.extra_out_nid[0]);
19000 #define alc662_auto_init_analog_input alc882_auto_init_analog_input
19001 #define alc662_auto_init_input_src alc882_auto_init_input_src
19006 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19007 unsigned int location)
19009 struct alc_spec *spec = codec->spec;
19010 struct auto_pin_cfg *cfg = &spec->autocfg;
19011 int type, i, num_pins = 0;
19013 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19014 for (i = 0; i < cfg->num_inputs; i++) {
19015 hda_nid_t nid = cfg->inputs[i].pin;
19017 unsigned int defcfg, caps;
19018 if (cfg->inputs[i].type != type)
19020 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19021 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19023 if (location && get_defcfg_location(defcfg) != location)
19025 caps = snd_hda_query_pin_caps(codec, nid);
19026 if (!(caps & AC_PINCAP_OUT))
19028 dac = alc_auto_look_for_dac(codec, nid);
19031 spec->multi_io[num_pins].pin = nid;
19032 spec->multi_io[num_pins].dac = dac;
19034 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19037 spec->multiout.num_dacs = 1;
19043 static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19044 struct snd_ctl_elem_info *uinfo)
19046 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19047 struct alc_spec *spec = codec->spec;
19049 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19051 uinfo->value.enumerated.items = spec->multi_ios + 1;
19052 if (uinfo->value.enumerated.item > spec->multi_ios)
19053 uinfo->value.enumerated.item = spec->multi_ios;
19054 sprintf(uinfo->value.enumerated.name, "%dch",
19055 (uinfo->value.enumerated.item + 1) * 2);
19059 static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19060 struct snd_ctl_elem_value *ucontrol)
19062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19063 struct alc_spec *spec = codec->spec;
19064 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19068 static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19070 struct alc_spec *spec = codec->spec;
19071 hda_nid_t nid = spec->multi_io[idx].pin;
19073 if (!spec->multi_io[idx].ctl_in)
19074 spec->multi_io[idx].ctl_in =
19075 snd_hda_codec_read(codec, nid, 0,
19076 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19078 snd_hda_codec_update_cache(codec, nid, 0,
19079 AC_VERB_SET_PIN_WIDGET_CONTROL,
19081 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19082 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19084 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19086 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19087 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19088 HDA_AMP_MUTE, HDA_AMP_MUTE);
19089 snd_hda_codec_update_cache(codec, nid, 0,
19090 AC_VERB_SET_PIN_WIDGET_CONTROL,
19091 spec->multi_io[idx].ctl_in);
19096 static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19097 struct snd_ctl_elem_value *ucontrol)
19099 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19100 struct alc_spec *spec = codec->spec;
19103 ch = ucontrol->value.enumerated.item[0];
19104 if (ch < 0 || ch > spec->multi_ios)
19106 if (ch == (spec->ext_channel_count - 1) / 2)
19108 spec->ext_channel_count = (ch + 1) * 2;
19109 for (i = 0; i < spec->multi_ios; i++)
19110 alc_set_multi_io(codec, i, i < ch);
19111 spec->multiout.max_channels = spec->ext_channel_count;
19115 static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19117 .name = "Channel Mode",
19118 .info = alc_auto_ch_mode_info,
19119 .get = alc_auto_ch_mode_get,
19120 .put = alc_auto_ch_mode_put,
19123 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
19124 int (*fill_dac)(struct hda_codec *))
19126 struct alc_spec *spec = codec->spec;
19127 struct auto_pin_cfg *cfg = &spec->autocfg;
19128 unsigned int location, defcfg;
19131 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
19132 /* use HP as primary out */
19133 cfg->speaker_outs = cfg->line_outs;
19134 memcpy(cfg->speaker_pins, cfg->line_out_pins,
19135 sizeof(cfg->speaker_pins));
19136 cfg->line_outs = cfg->hp_outs;
19137 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
19139 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
19140 cfg->line_out_type = AUTO_PIN_HP_OUT;
19144 if (cfg->line_outs != 1 ||
19145 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19148 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19149 location = get_defcfg_location(defcfg);
19151 num_pins = alc_auto_fill_multi_ios(codec, location);
19152 if (num_pins > 0) {
19153 struct snd_kcontrol_new *knew;
19155 knew = alc_kcontrol_new(spec);
19158 *knew = alc_auto_channel_mode_enum;
19159 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19163 spec->multi_ios = num_pins;
19164 spec->ext_channel_count = 2;
19165 spec->multiout.num_dacs = num_pins + 1;
19170 static int alc662_parse_auto_config(struct hda_codec *codec)
19172 struct alc_spec *spec = codec->spec;
19174 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19176 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19180 if (!spec->autocfg.line_outs)
19181 return 0; /* can't find valid BIOS pin config */
19183 err = alc662_auto_fill_dac_nids(codec);
19186 err = alc_auto_add_multi_channel_mode(codec, alc662_auto_fill_dac_nids);
19189 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19192 err = alc662_auto_create_extra_out(codec,
19193 spec->autocfg.speaker_pins[0],
19194 spec->multiout.extra_out_nid[0],
19198 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19199 spec->multiout.hp_nid,
19203 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19207 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19209 alc_auto_parse_digital(codec);
19211 if (spec->kctls.list)
19212 add_mixer(spec, spec->kctls.list);
19214 spec->num_mux_defs = 1;
19215 spec->input_mux = &spec->private_imux[0];
19217 err = alc_auto_add_mic_boost(codec);
19221 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19222 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19223 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19225 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19230 /* additional initialization for auto-configuration model */
19231 static void alc662_auto_init(struct hda_codec *codec)
19233 struct alc_spec *spec = codec->spec;
19234 alc662_auto_init_multi_out(codec);
19235 alc662_auto_init_hp_out(codec);
19236 alc662_auto_init_analog_input(codec);
19237 alc662_auto_init_input_src(codec);
19238 alc_auto_init_digital(codec);
19239 if (spec->unsol_event)
19240 alc_inithook(codec);
19243 static void alc272_fixup_mario(struct hda_codec *codec,
19244 const struct alc_fixup *fix, int action)
19246 if (action != ALC_FIXUP_ACT_PROBE)
19248 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19249 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19250 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19251 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19252 (0 << AC_AMPCAP_MUTE_SHIFT)))
19253 printk(KERN_WARNING
19254 "hda_codec: failed to override amp caps for NID 0x2\n");
19258 ALC662_FIXUP_ASPIRE,
19259 ALC662_FIXUP_IDEAPAD,
19260 ALC272_FIXUP_MARIO,
19261 ALC662_FIXUP_CZC_P10T,
19262 ALC662_FIXUP_SKU_IGNORE,
19265 static const struct alc_fixup alc662_fixups[] = {
19266 [ALC662_FIXUP_ASPIRE] = {
19267 .type = ALC_FIXUP_PINS,
19268 .v.pins = (const struct alc_pincfg[]) {
19269 { 0x15, 0x99130112 }, /* subwoofer */
19273 [ALC662_FIXUP_IDEAPAD] = {
19274 .type = ALC_FIXUP_PINS,
19275 .v.pins = (const struct alc_pincfg[]) {
19276 { 0x17, 0x99130112 }, /* subwoofer */
19280 [ALC272_FIXUP_MARIO] = {
19281 .type = ALC_FIXUP_FUNC,
19282 .v.func = alc272_fixup_mario,
19284 [ALC662_FIXUP_CZC_P10T] = {
19285 .type = ALC_FIXUP_VERBS,
19286 .v.verbs = (const struct hda_verb[]) {
19287 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19291 [ALC662_FIXUP_SKU_IGNORE] = {
19292 .type = ALC_FIXUP_SKU,
19293 .v.sku = ALC_FIXUP_SKU_IGNORE,
19297 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19298 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19299 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19300 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19301 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19302 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19303 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19304 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19308 static const struct alc_model_fixup alc662_fixup_models[] = {
19309 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19314 static int patch_alc662(struct hda_codec *codec)
19316 struct alc_spec *spec;
19317 int err, board_config;
19320 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19324 codec->spec = spec;
19326 spec->mixer_nid = 0x0b;
19328 alc_auto_parse_customize_define(codec);
19330 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19332 coef = alc_read_coef_idx(codec, 0);
19333 if (coef == 0x8020 || coef == 0x8011)
19334 alc_codec_rename(codec, "ALC661");
19335 else if (coef & (1 << 14) &&
19336 codec->bus->pci->subsystem_vendor == 0x1025 &&
19337 spec->cdefine.platform_type == 1)
19338 alc_codec_rename(codec, "ALC272X");
19339 else if (coef == 0x4011)
19340 alc_codec_rename(codec, "ALC656");
19342 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19345 if (board_config < 0) {
19346 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19348 board_config = ALC662_AUTO;
19351 if (board_config == ALC662_AUTO) {
19352 alc_pick_fixup(codec, alc662_fixup_models,
19353 alc662_fixup_tbl, alc662_fixups);
19354 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19355 /* automatic parse from the BIOS config */
19356 err = alc662_parse_auto_config(codec);
19362 "hda_codec: Cannot set up configuration "
19363 "from BIOS. Using base mode...\n");
19364 board_config = ALC662_3ST_2ch_DIG;
19368 if (has_cdefine_beep(codec)) {
19369 err = snd_hda_attach_beep_device(codec, 0x1);
19376 if (board_config != ALC662_AUTO)
19377 setup_preset(codec, &alc662_presets[board_config]);
19379 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19380 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19382 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19383 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19385 if (!spec->adc_nids) {
19386 spec->adc_nids = alc662_adc_nids;
19387 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19389 if (!spec->capsrc_nids)
19390 spec->capsrc_nids = alc662_capsrc_nids;
19392 if (!spec->cap_mixer)
19393 set_capture_mixer(codec);
19395 if (has_cdefine_beep(codec)) {
19396 switch (codec->vendor_id) {
19398 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19403 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19406 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19410 spec->vmaster_nid = 0x02;
19412 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19414 codec->patch_ops = alc_patch_ops;
19415 if (board_config == ALC662_AUTO)
19416 spec->init_hook = alc662_auto_init;
19417 spec->shutup = alc_eapd_shutup;
19419 alc_init_jacks(codec);
19421 #ifdef CONFIG_SND_HDA_POWER_SAVE
19422 if (!spec->loopback.amplist)
19423 spec->loopback.amplist = alc662_loopbacks;
19429 static int patch_alc888(struct hda_codec *codec)
19431 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19432 kfree(codec->chip_name);
19433 if (codec->vendor_id == 0x10ec0887)
19434 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19436 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19437 if (!codec->chip_name) {
19441 return patch_alc662(codec);
19443 return patch_alc882(codec);
19446 static int patch_alc899(struct hda_codec *codec)
19448 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19449 kfree(codec->chip_name);
19450 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19452 return patch_alc882(codec);
19458 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19459 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19460 #define alc680_modes alc260_modes
19462 static const hda_nid_t alc680_dac_nids[3] = {
19463 /* Lout1, Lout2, hp */
19467 static const hda_nid_t alc680_adc_nids[3] = {
19469 /* DMIC, MIC, Line-in*/
19474 * Analog capture ADC cgange
19476 static void alc680_rec_autoswitch(struct hda_codec *codec)
19478 struct alc_spec *spec = codec->spec;
19479 struct auto_pin_cfg *cfg = &spec->autocfg;
19481 int type_found = AUTO_PIN_LAST;
19485 for (i = 0; i < cfg->num_inputs; i++) {
19486 nid = cfg->inputs[i].pin;
19487 if (!is_jack_detectable(codec, nid))
19489 if (snd_hda_jack_detect(codec, nid)) {
19490 if (cfg->inputs[i].type < type_found) {
19491 type_found = cfg->inputs[i].type;
19499 snd_hda_get_connections(codec, pin_found, &nid, 1);
19501 if (nid != spec->cur_adc)
19502 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19503 spec->cur_adc = nid;
19504 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19505 spec->cur_adc_format);
19508 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19509 struct hda_codec *codec,
19510 unsigned int stream_tag,
19511 unsigned int format,
19512 struct snd_pcm_substream *substream)
19514 struct alc_spec *spec = codec->spec;
19516 spec->cur_adc = 0x07;
19517 spec->cur_adc_stream_tag = stream_tag;
19518 spec->cur_adc_format = format;
19520 alc680_rec_autoswitch(codec);
19524 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19525 struct hda_codec *codec,
19526 struct snd_pcm_substream *substream)
19528 snd_hda_codec_cleanup_stream(codec, 0x07);
19529 snd_hda_codec_cleanup_stream(codec, 0x08);
19530 snd_hda_codec_cleanup_stream(codec, 0x09);
19534 static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19535 .substreams = 1, /* can be overridden */
19538 /* NID is set in alc_build_pcms */
19540 .prepare = alc680_capture_pcm_prepare,
19541 .cleanup = alc680_capture_pcm_cleanup
19545 static const struct snd_kcontrol_new alc680_base_mixer[] = {
19546 /* output mixer control */
19547 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19548 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19549 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19550 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19551 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19552 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19553 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19557 static const struct hda_bind_ctls alc680_bind_cap_vol = {
19558 .ops = &snd_hda_bind_vol,
19560 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19561 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19562 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19567 static const struct hda_bind_ctls alc680_bind_cap_switch = {
19568 .ops = &snd_hda_bind_sw,
19570 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19571 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19572 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19577 static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19578 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19579 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19584 * generic initialization of ADC, input mixers and output mixers
19586 static const struct hda_verb alc680_init_verbs[] = {
19587 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19588 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19589 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19591 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19592 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19594 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19595 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19596 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19598 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19599 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19600 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19601 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19602 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19604 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19605 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19606 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19611 /* toggle speaker-output according to the hp-jack state */
19612 static void alc680_base_setup(struct hda_codec *codec)
19614 struct alc_spec *spec = codec->spec;
19616 spec->autocfg.hp_pins[0] = 0x16;
19617 spec->autocfg.speaker_pins[0] = 0x14;
19618 spec->autocfg.speaker_pins[1] = 0x15;
19619 spec->autocfg.num_inputs = 2;
19620 spec->autocfg.inputs[0].pin = 0x18;
19621 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19622 spec->autocfg.inputs[1].pin = 0x19;
19623 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19624 spec->automute = 1;
19625 spec->automute_mode = ALC_AUTOMUTE_AMP;
19628 static void alc680_unsol_event(struct hda_codec *codec,
19631 if ((res >> 26) == ALC880_HP_EVENT)
19632 alc_hp_automute(codec);
19633 if ((res >> 26) == ALC880_MIC_EVENT)
19634 alc680_rec_autoswitch(codec);
19637 static void alc680_inithook(struct hda_codec *codec)
19639 alc_hp_automute(codec);
19640 alc680_rec_autoswitch(codec);
19643 /* create input playback/capture controls for the given pin */
19644 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19645 const char *ctlname, int idx)
19663 if (spec->multiout.dac_nids[0] != dac &&
19664 spec->multiout.dac_nids[1] != dac) {
19665 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19666 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19671 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19672 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19676 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19682 /* add playback controls from the parsed DAC table */
19683 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19684 const struct auto_pin_cfg *cfg)
19689 spec->multiout.dac_nids = spec->private_dac_nids;
19691 nid = cfg->line_out_pins[0];
19695 name = alc_get_line_out_pfx(spec, 0, true, &index);
19696 err = alc680_new_analog_output(spec, nid, name, 0);
19701 nid = cfg->speaker_pins[0];
19703 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19707 nid = cfg->hp_pins[0];
19709 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19717 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19718 hda_nid_t nid, int pin_type)
19720 alc_set_pin_output(codec, nid, pin_type);
19723 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19725 struct alc_spec *spec = codec->spec;
19726 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19728 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19729 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19733 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19735 struct alc_spec *spec = codec->spec;
19738 pin = spec->autocfg.hp_pins[0];
19740 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19741 pin = spec->autocfg.speaker_pins[0];
19743 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19746 /* pcm configuration: identical with ALC880 */
19747 #define alc680_pcm_analog_playback alc880_pcm_analog_playback
19748 #define alc680_pcm_analog_capture alc880_pcm_analog_capture
19749 #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19750 #define alc680_pcm_digital_playback alc880_pcm_digital_playback
19751 #define alc680_pcm_digital_capture alc880_pcm_digital_capture
19754 * BIOS auto configuration
19756 static int alc680_parse_auto_config(struct hda_codec *codec)
19758 struct alc_spec *spec = codec->spec;
19760 static const hda_nid_t alc680_ignore[] = { 0 };
19762 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19767 if (!spec->autocfg.line_outs) {
19768 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19769 spec->multiout.max_channels = 2;
19770 spec->no_analog = 1;
19773 return 0; /* can't find valid BIOS pin config */
19775 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19779 spec->multiout.max_channels = 2;
19782 /* digital only support output */
19783 alc_auto_parse_digital(codec);
19784 if (spec->kctls.list)
19785 add_mixer(spec, spec->kctls.list);
19787 err = alc_auto_add_mic_boost(codec);
19794 #define alc680_auto_init_analog_input alc882_auto_init_analog_input
19796 /* init callback for auto-configuration model -- overriding the default init */
19797 static void alc680_auto_init(struct hda_codec *codec)
19799 struct alc_spec *spec = codec->spec;
19800 alc680_auto_init_multi_out(codec);
19801 alc680_auto_init_hp_out(codec);
19802 alc680_auto_init_analog_input(codec);
19803 alc_auto_init_digital(codec);
19804 if (spec->unsol_event)
19805 alc_inithook(codec);
19809 * configuration and preset
19811 static const char * const alc680_models[ALC680_MODEL_LAST] = {
19812 [ALC680_BASE] = "base",
19813 [ALC680_AUTO] = "auto",
19816 static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19817 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19821 static const struct alc_config_preset alc680_presets[] = {
19823 .mixers = { alc680_base_mixer },
19824 .cap_mixer = alc680_master_capture_mixer,
19825 .init_verbs = { alc680_init_verbs },
19826 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19827 .dac_nids = alc680_dac_nids,
19828 .dig_out_nid = ALC680_DIGOUT_NID,
19829 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19830 .channel_mode = alc680_modes,
19831 .unsol_event = alc680_unsol_event,
19832 .setup = alc680_base_setup,
19833 .init_hook = alc680_inithook,
19838 static int patch_alc680(struct hda_codec *codec)
19840 struct alc_spec *spec;
19844 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19848 codec->spec = spec;
19850 /* ALC680 has no aa-loopback mixer */
19852 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19856 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19857 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19859 board_config = ALC680_AUTO;
19862 if (board_config == ALC680_AUTO) {
19863 /* automatic parse from the BIOS config */
19864 err = alc680_parse_auto_config(codec);
19870 "hda_codec: Cannot set up configuration "
19871 "from BIOS. Using base mode...\n");
19872 board_config = ALC680_BASE;
19876 if (board_config != ALC680_AUTO)
19877 setup_preset(codec, &alc680_presets[board_config]);
19879 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19880 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
19881 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19882 spec->stream_digital_capture = &alc680_pcm_digital_capture;
19884 if (!spec->adc_nids) {
19885 spec->adc_nids = alc680_adc_nids;
19886 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19889 if (!spec->cap_mixer)
19890 set_capture_mixer(codec);
19892 spec->vmaster_nid = 0x02;
19894 codec->patch_ops = alc_patch_ops;
19895 if (board_config == ALC680_AUTO)
19896 spec->init_hook = alc680_auto_init;
19904 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
19905 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
19906 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
19907 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
19908 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
19909 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
19910 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
19911 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
19912 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
19913 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
19914 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
19915 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
19916 .patch = patch_alc861 },
19917 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19918 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19919 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
19920 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
19921 .patch = patch_alc882 },
19922 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19923 .patch = patch_alc662 },
19924 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
19925 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
19926 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
19927 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
19928 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
19929 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
19930 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
19931 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
19932 .patch = patch_alc882 },
19933 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
19934 .patch = patch_alc882 },
19935 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
19936 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
19937 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
19938 .patch = patch_alc882 },
19939 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
19940 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
19941 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
19942 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
19943 {} /* terminator */
19946 MODULE_ALIAS("snd-hda-codec-id:10ec*");
19948 MODULE_LICENSE("GPL");
19949 MODULE_DESCRIPTION("Realtek HD-audio codec");
19951 static struct hda_codec_preset_list realtek_list = {
19952 .preset = snd_hda_preset_realtek,
19953 .owner = THIS_MODULE,
19956 static int __init patch_realtek_init(void)
19958 return snd_hda_add_codec_preset(&realtek_list);
19961 static void __exit patch_realtek_exit(void)
19963 snd_hda_delete_codec_preset(&realtek_list);
19966 module_init(patch_realtek_init)
19967 module_exit(patch_realtek_exit)