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 "hda_codec.h"
32 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
82 #ifdef CONFIG_SND_DEBUG
86 ALC260_MODEL_LAST /* last tag */
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
110 ALC262_MODEL_LAST /* last tag */
120 ALC268_ACER_ASPIRE_ONE,
123 #ifdef CONFIG_SND_DEBUG
127 ALC268_MODEL_LAST /* last tag */
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
139 ALC269_MODEL_LAST /* last tag */
156 /* ALC861-VD models */
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
222 ALC883_TARGA_2ch_DIG,
225 ALC888_ACER_ASPIRE_4930G,
229 ALC883_LENOVO_101E_2ch,
230 ALC883_LENOVO_NB0763,
231 ALC888_LENOVO_MS7195_DIG,
238 ALC883_FUJITSU_PI2515,
239 ALC888_FUJITSU_XA3530,
240 ALC883_3ST_6ch_INTEL,
249 /* styles of capture selection */
251 CAPT_MUX = 0, /* only mux based */
252 CAPT_MIX, /* only mixer based */
253 CAPT_1MUX_MIX, /* first mux and other mixers */
257 #define GPIO_MASK 0x03
259 /* extra amp-initialization sequence types */
269 /* codec parameterization */
270 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
271 unsigned int num_mixers;
272 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
273 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
275 const struct hda_verb *init_verbs[5]; /* initialization verbs
279 unsigned int num_init_verbs;
281 char stream_name_analog[16]; /* analog PCM stream */
282 struct hda_pcm_stream *stream_analog_playback;
283 struct hda_pcm_stream *stream_analog_capture;
284 struct hda_pcm_stream *stream_analog_alt_playback;
285 struct hda_pcm_stream *stream_analog_alt_capture;
287 char stream_name_digital[16]; /* digital PCM stream */
288 struct hda_pcm_stream *stream_digital_playback;
289 struct hda_pcm_stream *stream_digital_capture;
292 struct hda_multi_out multiout; /* playback set-up
293 * max_channels, dacs must be set
294 * dig_out_nid and hp_nid are optional
296 hda_nid_t alt_dac_nid;
297 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
301 unsigned int num_adc_nids;
303 hda_nid_t *capsrc_nids;
304 hda_nid_t dig_in_nid; /* digital-in NID; optional */
305 int capture_style; /* capture style (CAPT_*) */
308 unsigned int num_mux_defs;
309 const struct hda_input_mux *input_mux;
310 unsigned int cur_mux[3];
313 const struct hda_channel_mode *channel_mode;
314 int num_channel_mode;
317 /* PCM information */
318 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
320 /* dynamic controls, init_verbs and input_mux */
321 struct auto_pin_cfg autocfg;
322 struct snd_array kctls;
323 struct hda_input_mux private_imux[3];
324 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
327 void (*init_hook)(struct hda_codec *codec);
328 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
330 /* for pin sensing */
331 unsigned int sense_updated: 1;
332 unsigned int jack_present: 1;
333 unsigned int master_sw: 1;
336 unsigned int no_analog :1; /* digital I/O only */
339 /* for virtual master */
340 hda_nid_t vmaster_nid;
341 #ifdef CONFIG_SND_HDA_POWER_SAVE
342 struct hda_loopback_check loopback;
347 unsigned int pll_coef_idx, pll_coef_bit;
351 * configuration template - to be copied to the spec instance
353 struct alc_config_preset {
354 struct snd_kcontrol_new *mixers[5]; /* should be identical size
357 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
358 const struct hda_verb *init_verbs[5];
359 unsigned int num_dacs;
361 hda_nid_t dig_out_nid; /* optional */
362 hda_nid_t hp_nid; /* optional */
363 hda_nid_t *slave_dig_outs;
364 unsigned int num_adc_nids;
366 hda_nid_t *capsrc_nids;
367 hda_nid_t dig_in_nid;
368 unsigned int num_channel_mode;
369 const struct hda_channel_mode *channel_mode;
371 unsigned int num_mux_defs;
372 const struct hda_input_mux *input_mux;
373 void (*unsol_event)(struct hda_codec *, unsigned int);
374 void (*init_hook)(struct hda_codec *);
375 #ifdef CONFIG_SND_HDA_POWER_SAVE
376 struct hda_amp_list *loopbacks;
384 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
385 struct snd_ctl_elem_info *uinfo)
387 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
388 struct alc_spec *spec = codec->spec;
389 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
390 if (mux_idx >= spec->num_mux_defs)
392 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
395 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_value *ucontrol)
398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
399 struct alc_spec *spec = codec->spec;
400 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
402 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
406 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
407 struct snd_ctl_elem_value *ucontrol)
409 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
410 struct alc_spec *spec = codec->spec;
411 const struct hda_input_mux *imux;
412 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
413 unsigned int mux_idx;
414 hda_nid_t nid = spec->capsrc_nids ?
415 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
417 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
418 imux = &spec->input_mux[mux_idx];
420 if (spec->capture_style &&
421 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
422 /* Matrix-mixer style (e.g. ALC882) */
423 unsigned int *cur_val = &spec->cur_mux[adc_idx];
426 idx = ucontrol->value.enumerated.item[0];
427 if (idx >= imux->num_items)
428 idx = imux->num_items - 1;
431 for (i = 0; i < imux->num_items; i++) {
432 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
433 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
434 imux->items[i].index,
440 /* MUX style (e.g. ALC880) */
441 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
442 &spec->cur_mux[adc_idx]);
447 * channel mode setting
449 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
450 struct snd_ctl_elem_info *uinfo)
452 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
453 struct alc_spec *spec = codec->spec;
454 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
455 spec->num_channel_mode);
458 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
463 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
464 spec->num_channel_mode,
465 spec->multiout.max_channels);
468 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_value *ucontrol)
471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
472 struct alc_spec *spec = codec->spec;
473 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
474 spec->num_channel_mode,
475 &spec->multiout.max_channels);
476 if (err >= 0 && spec->need_dac_fix)
477 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
482 * Control the mode of pin widget settings via the mixer. "pc" is used
483 * instead of "%" to avoid consequences of accidently treating the % as
484 * being part of a format specifier. Maximum allowed length of a value is
485 * 63 characters plus NULL terminator.
487 * Note: some retasking pin complexes seem to ignore requests for input
488 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
489 * are requested. Therefore order this list so that this behaviour will not
490 * cause problems when mixer clients move through the enum sequentially.
491 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
494 static char *alc_pin_mode_names[] = {
495 "Mic 50pc bias", "Mic 80pc bias",
496 "Line in", "Line out", "Headphone out",
498 static unsigned char alc_pin_mode_values[] = {
499 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
501 /* The control can present all 5 options, or it can limit the options based
502 * in the pin being assumed to be exclusively an input or an output pin. In
503 * addition, "input" pins may or may not process the mic bias option
504 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
505 * accept requests for bias as of chip versions up to March 2006) and/or
506 * wiring in the computer.
508 #define ALC_PIN_DIR_IN 0x00
509 #define ALC_PIN_DIR_OUT 0x01
510 #define ALC_PIN_DIR_INOUT 0x02
511 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
512 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
514 /* Info about the pin modes supported by the different pin direction modes.
515 * For each direction the minimum and maximum values are given.
517 static signed char alc_pin_mode_dir_info[5][2] = {
518 { 0, 2 }, /* ALC_PIN_DIR_IN */
519 { 3, 4 }, /* ALC_PIN_DIR_OUT */
520 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
521 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
522 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
524 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
525 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
526 #define alc_pin_mode_n_items(_dir) \
527 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
529 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
530 struct snd_ctl_elem_info *uinfo)
532 unsigned int item_num = uinfo->value.enumerated.item;
533 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
535 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
537 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
539 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
540 item_num = alc_pin_mode_min(dir);
541 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
545 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
546 struct snd_ctl_elem_value *ucontrol)
549 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
550 hda_nid_t nid = kcontrol->private_value & 0xffff;
551 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
552 long *valp = ucontrol->value.integer.value;
553 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
554 AC_VERB_GET_PIN_WIDGET_CONTROL,
557 /* Find enumerated value for current pinctl setting */
558 i = alc_pin_mode_min(dir);
559 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
561 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
565 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
566 struct snd_ctl_elem_value *ucontrol)
569 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
570 hda_nid_t nid = kcontrol->private_value & 0xffff;
571 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
572 long val = *ucontrol->value.integer.value;
573 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
574 AC_VERB_GET_PIN_WIDGET_CONTROL,
577 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
578 val = alc_pin_mode_min(dir);
580 change = pinctl != alc_pin_mode_values[val];
582 /* Set pin mode to that requested */
583 snd_hda_codec_write_cache(codec, nid, 0,
584 AC_VERB_SET_PIN_WIDGET_CONTROL,
585 alc_pin_mode_values[val]);
587 /* Also enable the retasking pin's input/output as required
588 * for the requested pin mode. Enum values of 2 or less are
591 * Dynamically switching the input/output buffers probably
592 * reduces noise slightly (particularly on input) so we'll
593 * do it. However, having both input and output buffers
594 * enabled simultaneously doesn't seem to be problematic if
595 * this turns out to be necessary in the future.
598 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
599 HDA_AMP_MUTE, HDA_AMP_MUTE);
600 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
603 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
604 HDA_AMP_MUTE, HDA_AMP_MUTE);
605 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
612 #define ALC_PIN_MODE(xname, nid, dir) \
613 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
614 .info = alc_pin_mode_info, \
615 .get = alc_pin_mode_get, \
616 .put = alc_pin_mode_put, \
617 .private_value = nid | (dir<<16) }
619 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
620 * together using a mask with more than one bit set. This control is
621 * currently used only by the ALC260 test model. At this stage they are not
622 * needed for any "production" models.
624 #ifdef CONFIG_SND_DEBUG
625 #define alc_gpio_data_info snd_ctl_boolean_mono_info
627 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_value *ucontrol)
630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
631 hda_nid_t nid = kcontrol->private_value & 0xffff;
632 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
633 long *valp = ucontrol->value.integer.value;
634 unsigned int val = snd_hda_codec_read(codec, nid, 0,
635 AC_VERB_GET_GPIO_DATA, 0x00);
637 *valp = (val & mask) != 0;
640 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
641 struct snd_ctl_elem_value *ucontrol)
644 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
645 hda_nid_t nid = kcontrol->private_value & 0xffff;
646 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
647 long val = *ucontrol->value.integer.value;
648 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
649 AC_VERB_GET_GPIO_DATA,
652 /* Set/unset the masked GPIO bit(s) as needed */
653 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
658 snd_hda_codec_write_cache(codec, nid, 0,
659 AC_VERB_SET_GPIO_DATA, gpio_data);
663 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
664 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
665 .info = alc_gpio_data_info, \
666 .get = alc_gpio_data_get, \
667 .put = alc_gpio_data_put, \
668 .private_value = nid | (mask<<16) }
669 #endif /* CONFIG_SND_DEBUG */
671 /* A switch control to allow the enabling of the digital IO pins on the
672 * ALC260. This is incredibly simplistic; the intention of this control is
673 * to provide something in the test model allowing digital outputs to be
674 * identified if present. If models are found which can utilise these
675 * outputs a more complete mixer control can be devised for those models if
678 #ifdef CONFIG_SND_DEBUG
679 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
681 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
682 struct snd_ctl_elem_value *ucontrol)
684 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
685 hda_nid_t nid = kcontrol->private_value & 0xffff;
686 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
687 long *valp = ucontrol->value.integer.value;
688 unsigned int val = snd_hda_codec_read(codec, nid, 0,
689 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
691 *valp = (val & mask) != 0;
694 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
695 struct snd_ctl_elem_value *ucontrol)
698 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
699 hda_nid_t nid = kcontrol->private_value & 0xffff;
700 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
701 long val = *ucontrol->value.integer.value;
702 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
703 AC_VERB_GET_DIGI_CONVERT_1,
706 /* Set/unset the masked control bit(s) as needed */
707 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
712 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
717 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
718 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
719 .info = alc_spdif_ctrl_info, \
720 .get = alc_spdif_ctrl_get, \
721 .put = alc_spdif_ctrl_put, \
722 .private_value = nid | (mask<<16) }
723 #endif /* CONFIG_SND_DEBUG */
725 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
726 * Again, this is only used in the ALC26x test models to help identify when
727 * the EAPD line must be asserted for features to work.
729 #ifdef CONFIG_SND_DEBUG
730 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
732 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
733 struct snd_ctl_elem_value *ucontrol)
735 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
736 hda_nid_t nid = kcontrol->private_value & 0xffff;
737 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
738 long *valp = ucontrol->value.integer.value;
739 unsigned int val = snd_hda_codec_read(codec, nid, 0,
740 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
742 *valp = (val & mask) != 0;
746 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
747 struct snd_ctl_elem_value *ucontrol)
750 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
751 hda_nid_t nid = kcontrol->private_value & 0xffff;
752 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
753 long val = *ucontrol->value.integer.value;
754 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
755 AC_VERB_GET_EAPD_BTLENABLE,
758 /* Set/unset the masked control bit(s) as needed */
759 change = (!val ? 0 : mask) != (ctrl_data & mask);
764 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
770 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
771 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
772 .info = alc_eapd_ctrl_info, \
773 .get = alc_eapd_ctrl_get, \
774 .put = alc_eapd_ctrl_put, \
775 .private_value = nid | (mask<<16) }
776 #endif /* CONFIG_SND_DEBUG */
779 * set up the input pin config (depending on the given auto-pin type)
781 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
784 unsigned int val = PIN_IN;
786 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
788 pincap = snd_hda_query_pin_caps(codec, nid);
789 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
790 if (pincap & AC_PINCAP_VREF_80)
793 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
798 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
800 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
802 spec->mixers[spec->num_mixers++] = mix;
805 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
807 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
809 spec->init_verbs[spec->num_init_verbs++] = verb;
812 #ifdef CONFIG_PROC_FS
816 static void print_realtek_coef(struct snd_info_buffer *buffer,
817 struct hda_codec *codec, hda_nid_t nid)
823 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
824 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
825 coeff = snd_hda_codec_read(codec, nid, 0,
826 AC_VERB_GET_COEF_INDEX, 0);
827 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
830 #define print_realtek_coef NULL
834 * set up from the preset table
836 static void setup_preset(struct alc_spec *spec,
837 const struct alc_config_preset *preset)
841 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
842 add_mixer(spec, preset->mixers[i]);
843 spec->cap_mixer = preset->cap_mixer;
844 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
846 add_verb(spec, preset->init_verbs[i]);
848 spec->channel_mode = preset->channel_mode;
849 spec->num_channel_mode = preset->num_channel_mode;
850 spec->need_dac_fix = preset->need_dac_fix;
852 spec->multiout.max_channels = spec->channel_mode[0].channels;
854 spec->multiout.num_dacs = preset->num_dacs;
855 spec->multiout.dac_nids = preset->dac_nids;
856 spec->multiout.dig_out_nid = preset->dig_out_nid;
857 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
858 spec->multiout.hp_nid = preset->hp_nid;
860 spec->num_mux_defs = preset->num_mux_defs;
861 if (!spec->num_mux_defs)
862 spec->num_mux_defs = 1;
863 spec->input_mux = preset->input_mux;
865 spec->num_adc_nids = preset->num_adc_nids;
866 spec->adc_nids = preset->adc_nids;
867 spec->capsrc_nids = preset->capsrc_nids;
868 spec->dig_in_nid = preset->dig_in_nid;
870 spec->unsol_event = preset->unsol_event;
871 spec->init_hook = preset->init_hook;
872 #ifdef CONFIG_SND_HDA_POWER_SAVE
873 spec->loopback.amplist = preset->loopbacks;
877 /* Enable GPIO mask and set output */
878 static struct hda_verb alc_gpio1_init_verbs[] = {
879 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
880 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
881 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
885 static struct hda_verb alc_gpio2_init_verbs[] = {
886 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
887 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
888 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
892 static struct hda_verb alc_gpio3_init_verbs[] = {
893 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
894 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
895 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
900 * Fix hardware PLL issue
901 * On some codecs, the analog PLL gating control must be off while
902 * the default value is 1.
904 static void alc_fix_pll(struct hda_codec *codec)
906 struct alc_spec *spec = codec->spec;
911 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
913 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
914 AC_VERB_GET_PROC_COEF, 0);
915 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
917 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
918 val & ~(1 << spec->pll_coef_bit));
921 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
922 unsigned int coef_idx, unsigned int coef_bit)
924 struct alc_spec *spec = codec->spec;
926 spec->pll_coef_idx = coef_idx;
927 spec->pll_coef_bit = coef_bit;
931 static void alc_automute_pin(struct hda_codec *codec)
933 struct alc_spec *spec = codec->spec;
934 unsigned int present;
935 unsigned int nid = spec->autocfg.hp_pins[0];
938 /* need to execute and sync at first */
939 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
940 present = snd_hda_codec_read(codec, nid, 0,
941 AC_VERB_GET_PIN_SENSE, 0);
942 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
943 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
944 nid = spec->autocfg.speaker_pins[i];
947 snd_hda_codec_write(codec, nid, 0,
948 AC_VERB_SET_PIN_WIDGET_CONTROL,
949 spec->jack_present ? 0 : PIN_OUT);
953 #if 0 /* it's broken in some acses -- temporarily disabled */
954 static void alc_mic_automute(struct hda_codec *codec)
956 struct alc_spec *spec = codec->spec;
957 unsigned int present;
958 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
959 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
960 unsigned int mix_nid = spec->capsrc_nids[0];
961 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
963 capsrc_idx_mic = mic_nid - 0x18;
964 capsrc_idx_fmic = fmic_nid - 0x18;
965 present = snd_hda_codec_read(codec, mic_nid, 0,
966 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
967 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
968 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
969 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
970 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
971 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
972 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
975 #define alc_mic_automute(codec) do {} while(0) /* NOP */
976 #endif /* disabled */
978 /* unsolicited event for HP jack sensing */
979 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
981 if (codec->vendor_id == 0x10ec0880)
986 case ALC880_HP_EVENT:
987 alc_automute_pin(codec);
989 case ALC880_MIC_EVENT:
990 alc_mic_automute(codec);
995 static void alc_inithook(struct hda_codec *codec)
997 alc_automute_pin(codec);
998 alc_mic_automute(codec);
1001 /* additional initialization for ALC888 variants */
1002 static void alc888_coef_init(struct hda_codec *codec)
1006 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1007 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1008 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1009 if ((tmp & 0xf0) == 0x20)
1011 snd_hda_codec_read(codec, 0x20, 0,
1012 AC_VERB_SET_PROC_COEF, 0x830);
1015 snd_hda_codec_read(codec, 0x20, 0,
1016 AC_VERB_SET_PROC_COEF, 0x3030);
1019 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1024 case ALC_INIT_GPIO1:
1025 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1027 case ALC_INIT_GPIO2:
1028 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1030 case ALC_INIT_GPIO3:
1031 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1033 case ALC_INIT_DEFAULT:
1034 switch (codec->vendor_id) {
1036 snd_hda_codec_write(codec, 0x0f, 0,
1037 AC_VERB_SET_EAPD_BTLENABLE, 2);
1038 snd_hda_codec_write(codec, 0x10, 0,
1039 AC_VERB_SET_EAPD_BTLENABLE, 2);
1051 snd_hda_codec_write(codec, 0x14, 0,
1052 AC_VERB_SET_EAPD_BTLENABLE, 2);
1053 snd_hda_codec_write(codec, 0x15, 0,
1054 AC_VERB_SET_EAPD_BTLENABLE, 2);
1057 switch (codec->vendor_id) {
1059 snd_hda_codec_write(codec, 0x1a, 0,
1060 AC_VERB_SET_COEF_INDEX, 7);
1061 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1062 AC_VERB_GET_PROC_COEF, 0);
1063 snd_hda_codec_write(codec, 0x1a, 0,
1064 AC_VERB_SET_COEF_INDEX, 7);
1065 snd_hda_codec_write(codec, 0x1a, 0,
1066 AC_VERB_SET_PROC_COEF,
1076 snd_hda_codec_write(codec, 0x20, 0,
1077 AC_VERB_SET_COEF_INDEX, 7);
1078 tmp = snd_hda_codec_read(codec, 0x20, 0,
1079 AC_VERB_GET_PROC_COEF, 0);
1080 snd_hda_codec_write(codec, 0x20, 0,
1081 AC_VERB_SET_COEF_INDEX, 7);
1082 snd_hda_codec_write(codec, 0x20, 0,
1083 AC_VERB_SET_PROC_COEF,
1087 alc888_coef_init(codec);
1091 snd_hda_codec_write(codec, 0x20, 0,
1092 AC_VERB_SET_COEF_INDEX, 7);
1093 tmp = snd_hda_codec_read(codec, 0x20, 0,
1094 AC_VERB_GET_PROC_COEF, 0);
1095 snd_hda_codec_write(codec, 0x20, 0,
1096 AC_VERB_SET_COEF_INDEX, 7);
1097 snd_hda_codec_write(codec, 0x20, 0,
1098 AC_VERB_SET_PROC_COEF,
1106 static void alc_init_auto_hp(struct hda_codec *codec)
1108 struct alc_spec *spec = codec->spec;
1110 if (!spec->autocfg.hp_pins[0])
1113 if (!spec->autocfg.speaker_pins[0]) {
1114 if (spec->autocfg.line_out_pins[0] &&
1115 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1116 spec->autocfg.speaker_pins[0] =
1117 spec->autocfg.line_out_pins[0];
1122 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1123 spec->autocfg.hp_pins[0]);
1124 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1125 AC_VERB_SET_UNSOLICITED_ENABLE,
1126 AC_USRSP_EN | ALC880_HP_EVENT);
1127 spec->unsol_event = alc_sku_unsol_event;
1130 /* check subsystem ID and set up device-specific initialization;
1131 * return 1 if initialized, 0 if invalid SSID
1133 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1134 * 31 ~ 16 : Manufacture ID
1136 * 7 ~ 0 : Assembly ID
1137 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1139 static int alc_subsystem_id(struct hda_codec *codec,
1140 hda_nid_t porta, hda_nid_t porte,
1143 unsigned int ass, tmp, i;
1145 struct alc_spec *spec = codec->spec;
1147 ass = codec->subsystem_id & 0xffff;
1148 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1151 /* invalid SSID, check the special NID pin defcfg instead */
1153 * 31~30 : port conetcivity
1156 * 19~16 : Check sum (15:1)
1161 if (codec->vendor_id == 0x10ec0260)
1163 ass = snd_hda_codec_get_pincfg(codec, nid);
1164 snd_printd("realtek: No valid SSID, "
1165 "checking pincfg 0x%08x for NID 0x%x\n",
1167 if (!(ass & 1) && !(ass & 0x100000))
1169 if ((ass >> 30) != 1) /* no physical connection */
1174 for (i = 1; i < 16; i++) {
1178 if (((ass >> 16) & 0xf) != tmp)
1181 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1182 ass & 0xffff, codec->vendor_id);
1186 * 2 : 0 --> Desktop, 1 --> Laptop
1187 * 3~5 : External Amplifier control
1190 tmp = (ass & 0x38) >> 3; /* external Amp control */
1193 spec->init_amp = ALC_INIT_GPIO1;
1196 spec->init_amp = ALC_INIT_GPIO2;
1199 spec->init_amp = ALC_INIT_GPIO3;
1202 spec->init_amp = ALC_INIT_DEFAULT;
1206 /* is laptop or Desktop and enable the function "Mute internal speaker
1207 * when the external headphone out jack is plugged"
1209 if (!(ass & 0x8000))
1212 * 10~8 : Jack location
1213 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1215 * 15 : 1 --> enable the function "Mute internal speaker
1216 * when the external headphone out jack is plugged"
1218 if (!spec->autocfg.hp_pins[0]) {
1219 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1221 spec->autocfg.hp_pins[0] = porta;
1223 spec->autocfg.hp_pins[0] = porte;
1225 spec->autocfg.hp_pins[0] = portd;
1230 alc_init_auto_hp(codec);
1234 static void alc_ssid_check(struct hda_codec *codec,
1235 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1237 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1238 struct alc_spec *spec = codec->spec;
1239 snd_printd("realtek: "
1240 "Enable default setup for auto mode as fallback\n");
1241 spec->init_amp = ALC_INIT_DEFAULT;
1242 alc_init_auto_hp(codec);
1247 * Fix-up pin default configurations
1255 static void alc_fix_pincfg(struct hda_codec *codec,
1256 const struct snd_pci_quirk *quirk,
1257 const struct alc_pincfg **pinfix)
1259 const struct alc_pincfg *cfg;
1261 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1265 cfg = pinfix[quirk->value];
1266 for (; cfg->nid; cfg++)
1267 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1277 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1278 /* Mic-in jack as mic in */
1279 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1280 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1281 /* Line-in jack as Line in */
1282 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1283 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1284 /* Line-Out as Front */
1285 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1292 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1293 /* Mic-in jack as mic in */
1294 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1295 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1296 /* Line-in jack as Surround */
1297 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1298 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1299 /* Line-Out as Front */
1300 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1307 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1308 /* Mic-in jack as CLFE */
1309 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1310 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1311 /* Line-in jack as Surround */
1312 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1313 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1314 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1315 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1322 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1323 /* Mic-in jack as CLFE */
1324 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1325 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1326 /* Line-in jack as Surround */
1327 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1328 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1329 /* Line-Out as Side */
1330 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1334 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1335 { 2, alc888_4ST_ch2_intel_init },
1336 { 4, alc888_4ST_ch4_intel_init },
1337 { 6, alc888_4ST_ch6_intel_init },
1338 { 8, alc888_4ST_ch8_intel_init },
1342 * ALC888 Fujitsu Siemens Amillo xa3530
1345 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1346 /* Front Mic: set to PIN_IN (empty by default) */
1347 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1348 /* Connect Internal HP to Front */
1349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1350 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1351 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1352 /* Connect Bass HP to Front */
1353 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1354 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1355 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1356 /* Connect Line-Out side jack (SPDIF) to Side */
1357 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1358 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1359 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1360 /* Connect Mic jack to CLFE */
1361 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1362 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1363 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1364 /* Connect Line-in jack to Surround */
1365 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1366 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1367 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1368 /* Connect HP out jack to Front */
1369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1370 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1371 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1372 /* Enable unsolicited event for HP jack and Line-out jack */
1373 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1374 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1378 static void alc_automute_amp(struct hda_codec *codec)
1380 struct alc_spec *spec = codec->spec;
1381 unsigned int val, mute;
1385 spec->jack_present = 0;
1386 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1387 nid = spec->autocfg.hp_pins[i];
1390 val = snd_hda_codec_read(codec, nid, 0,
1391 AC_VERB_GET_PIN_SENSE, 0);
1392 if (val & AC_PINSENSE_PRESENCE) {
1393 spec->jack_present = 1;
1398 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1399 /* Toggle internal speakers muting */
1400 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1401 nid = spec->autocfg.speaker_pins[i];
1404 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1405 HDA_AMP_MUTE, mute);
1409 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1412 if (codec->vendor_id == 0x10ec0880)
1416 if (res == ALC880_HP_EVENT)
1417 alc_automute_amp(codec);
1420 static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1422 struct alc_spec *spec = codec->spec;
1424 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1425 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1426 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1427 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1428 alc_automute_amp(codec);
1432 * ALC888 Acer Aspire 4930G model
1435 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1436 /* Front Mic: set to PIN_IN (empty by default) */
1437 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1438 /* Unselect Front Mic by default in input mixer 3 */
1439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1440 /* Enable unsolicited event for HP jack */
1441 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1442 /* Connect Internal HP to front */
1443 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1444 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1445 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1446 /* Connect HP out to front */
1447 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1448 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1453 static struct hda_input_mux alc888_2_capture_sources[2] = {
1454 /* Front mic only available on one ADC */
1461 { "Front Mic", 0xb },
1474 static struct snd_kcontrol_new alc888_base_mixer[] = {
1475 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1476 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1477 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1478 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1479 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1481 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1482 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1483 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1484 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1485 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1486 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1487 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1491 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1496 static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1498 struct alc_spec *spec = codec->spec;
1500 spec->autocfg.hp_pins[0] = 0x15;
1501 spec->autocfg.speaker_pins[0] = 0x14;
1502 alc_automute_amp(codec);
1506 * ALC880 3-stack model
1508 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1509 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1510 * F-Mic = 0x1b, HP = 0x19
1513 static hda_nid_t alc880_dac_nids[4] = {
1514 /* front, rear, clfe, rear_surr */
1515 0x02, 0x05, 0x04, 0x03
1518 static hda_nid_t alc880_adc_nids[3] = {
1523 /* The datasheet says the node 0x07 is connected from inputs,
1524 * but it shows zero connection in the real implementation on some devices.
1525 * Note: this is a 915GAV bug, fixed on 915GLV
1527 static hda_nid_t alc880_adc_nids_alt[2] = {
1532 #define ALC880_DIGOUT_NID 0x06
1533 #define ALC880_DIGIN_NID 0x0a
1535 static struct hda_input_mux alc880_capture_source = {
1539 { "Front Mic", 0x3 },
1545 /* channel source setting (2/6 channel selection for 3-stack) */
1547 static struct hda_verb alc880_threestack_ch2_init[] = {
1548 /* set line-in to input, mute it */
1549 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1550 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1551 /* set mic-in to input vref 80%, mute it */
1552 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1553 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1558 static struct hda_verb alc880_threestack_ch6_init[] = {
1559 /* set line-in to output, unmute it */
1560 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1561 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1562 /* set mic-in to output, unmute it */
1563 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1564 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1568 static struct hda_channel_mode alc880_threestack_modes[2] = {
1569 { 2, alc880_threestack_ch2_init },
1570 { 6, alc880_threestack_ch6_init },
1573 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1574 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1575 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1576 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1577 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1578 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1579 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1580 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1581 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1582 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1583 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1584 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1585 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1588 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1589 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1593 .name = "Channel Mode",
1594 .info = alc_ch_mode_info,
1595 .get = alc_ch_mode_get,
1596 .put = alc_ch_mode_put,
1601 /* capture mixer elements */
1602 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1603 struct snd_ctl_elem_info *uinfo)
1605 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1606 struct alc_spec *spec = codec->spec;
1609 mutex_lock(&codec->control_mutex);
1610 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1612 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1613 mutex_unlock(&codec->control_mutex);
1617 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1618 unsigned int size, unsigned int __user *tlv)
1620 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1621 struct alc_spec *spec = codec->spec;
1624 mutex_lock(&codec->control_mutex);
1625 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1627 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1628 mutex_unlock(&codec->control_mutex);
1632 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1633 struct snd_ctl_elem_value *ucontrol);
1635 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1636 struct snd_ctl_elem_value *ucontrol,
1639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1640 struct alc_spec *spec = codec->spec;
1641 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1644 mutex_lock(&codec->control_mutex);
1645 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1647 err = func(kcontrol, ucontrol);
1648 mutex_unlock(&codec->control_mutex);
1652 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1653 struct snd_ctl_elem_value *ucontrol)
1655 return alc_cap_getput_caller(kcontrol, ucontrol,
1656 snd_hda_mixer_amp_volume_get);
1659 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1660 struct snd_ctl_elem_value *ucontrol)
1662 return alc_cap_getput_caller(kcontrol, ucontrol,
1663 snd_hda_mixer_amp_volume_put);
1666 /* capture mixer elements */
1667 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1669 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1670 struct snd_ctl_elem_value *ucontrol)
1672 return alc_cap_getput_caller(kcontrol, ucontrol,
1673 snd_hda_mixer_amp_switch_get);
1676 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1677 struct snd_ctl_elem_value *ucontrol)
1679 return alc_cap_getput_caller(kcontrol, ucontrol,
1680 snd_hda_mixer_amp_switch_put);
1683 #define _DEFINE_CAPMIX(num) \
1685 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1686 .name = "Capture Switch", \
1687 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1689 .info = alc_cap_sw_info, \
1690 .get = alc_cap_sw_get, \
1691 .put = alc_cap_sw_put, \
1694 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1695 .name = "Capture Volume", \
1696 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1697 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1698 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1700 .info = alc_cap_vol_info, \
1701 .get = alc_cap_vol_get, \
1702 .put = alc_cap_vol_put, \
1703 .tlv = { .c = alc_cap_vol_tlv }, \
1706 #define _DEFINE_CAPSRC(num) \
1708 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1709 /* .name = "Capture Source", */ \
1710 .name = "Input Source", \
1712 .info = alc_mux_enum_info, \
1713 .get = alc_mux_enum_get, \
1714 .put = alc_mux_enum_put, \
1717 #define DEFINE_CAPMIX(num) \
1718 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1719 _DEFINE_CAPMIX(num), \
1720 _DEFINE_CAPSRC(num), \
1724 #define DEFINE_CAPMIX_NOSRC(num) \
1725 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1726 _DEFINE_CAPMIX(num), \
1730 /* up to three ADCs */
1734 DEFINE_CAPMIX_NOSRC(1);
1735 DEFINE_CAPMIX_NOSRC(2);
1736 DEFINE_CAPMIX_NOSRC(3);
1739 * ALC880 5-stack model
1741 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1743 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1744 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1747 /* additional mixers to alc880_three_stack_mixer */
1748 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1749 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1750 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1754 /* channel source setting (6/8 channel selection for 5-stack) */
1756 static struct hda_verb alc880_fivestack_ch6_init[] = {
1757 /* set line-in to input, mute it */
1758 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1759 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1764 static struct hda_verb alc880_fivestack_ch8_init[] = {
1765 /* set line-in to output, unmute it */
1766 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1767 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1771 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1772 { 6, alc880_fivestack_ch6_init },
1773 { 8, alc880_fivestack_ch8_init },
1778 * ALC880 6-stack model
1780 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1781 * Side = 0x05 (0x0f)
1782 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1783 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1786 static hda_nid_t alc880_6st_dac_nids[4] = {
1787 /* front, rear, clfe, rear_surr */
1788 0x02, 0x03, 0x04, 0x05
1791 static struct hda_input_mux alc880_6stack_capture_source = {
1795 { "Front Mic", 0x1 },
1801 /* fixed 8-channels */
1802 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1806 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1807 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1808 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1809 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1810 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1811 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1812 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1813 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1814 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1815 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1816 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1817 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1818 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1819 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1820 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1822 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1823 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1824 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1827 .name = "Channel Mode",
1828 .info = alc_ch_mode_info,
1829 .get = alc_ch_mode_get,
1830 .put = alc_ch_mode_put,
1839 * W810 has rear IO for:
1842 * Center/LFE (DAC 04)
1845 * The system also has a pair of internal speakers, and a headphone jack.
1846 * These are both connected to Line2 on the codec, hence to DAC 02.
1848 * There is a variable resistor to control the speaker or headphone
1849 * volume. This is a hardware-only device without a software API.
1851 * Plugging headphones in will disable the internal speakers. This is
1852 * implemented in hardware, not via the driver using jack sense. In
1853 * a similar fashion, plugging into the rear socket marked "front" will
1854 * disable both the speakers and headphones.
1856 * For input, there's a microphone jack, and an "audio in" jack.
1857 * These may not do anything useful with this driver yet, because I
1858 * haven't setup any initialization verbs for these yet...
1861 static hda_nid_t alc880_w810_dac_nids[3] = {
1862 /* front, rear/surround, clfe */
1866 /* fixed 6 channels */
1867 static struct hda_channel_mode alc880_w810_modes[1] = {
1871 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1872 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1873 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1874 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1875 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1876 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1877 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1878 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1879 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1880 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1881 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1889 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1890 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1894 static hda_nid_t alc880_z71v_dac_nids[1] = {
1897 #define ALC880_Z71V_HP_DAC 0x03
1899 /* fixed 2 channels */
1900 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1904 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1905 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1906 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1907 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1908 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1909 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1910 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1918 * ALC880 F1734 model
1920 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1921 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1924 static hda_nid_t alc880_f1734_dac_nids[1] = {
1927 #define ALC880_F1734_HP_DAC 0x02
1929 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1930 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1931 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1932 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1933 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1934 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1935 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1936 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1937 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1941 static struct hda_input_mux alc880_f1734_capture_source = {
1953 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1954 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1955 * Mic = 0x18, Line = 0x1a
1958 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1959 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1961 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1962 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1963 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1964 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1965 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1966 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1967 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1968 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1969 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1970 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1971 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1972 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1973 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1977 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1978 .name = "Channel Mode",
1979 .info = alc_ch_mode_info,
1980 .get = alc_ch_mode_get,
1981 .put = alc_ch_mode_put,
1987 * ALC880 ASUS W1V model
1989 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1990 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1991 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1994 /* additional mixers to alc880_asus_mixer */
1995 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1996 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1997 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2002 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2003 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2004 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2005 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2007 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2010 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2011 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2016 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2017 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2018 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2019 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2020 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2021 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2022 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2023 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2024 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2025 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2026 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2027 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2028 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2031 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2032 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2034 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2035 .name = "Channel Mode",
2036 .info = alc_ch_mode_info,
2037 .get = alc_ch_mode_get,
2038 .put = alc_ch_mode_put,
2043 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2044 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2045 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2046 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2047 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2050 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2051 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2052 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2053 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2057 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2058 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2059 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2060 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2061 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2063 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2068 * virtual master controls
2072 * slave controls for virtual master
2074 static const char *alc_slave_vols[] = {
2075 "Front Playback Volume",
2076 "Surround Playback Volume",
2077 "Center Playback Volume",
2078 "LFE Playback Volume",
2079 "Side Playback Volume",
2080 "Headphone Playback Volume",
2081 "Speaker Playback Volume",
2082 "Mono Playback Volume",
2083 "Line-Out Playback Volume",
2084 "PCM Playback Volume",
2088 static const char *alc_slave_sws[] = {
2089 "Front Playback Switch",
2090 "Surround Playback Switch",
2091 "Center Playback Switch",
2092 "LFE Playback Switch",
2093 "Side Playback Switch",
2094 "Headphone Playback Switch",
2095 "Speaker Playback Switch",
2096 "Mono Playback Switch",
2097 "IEC958 Playback Switch",
2102 * build control elements
2105 static void alc_free_kctls(struct hda_codec *codec);
2107 /* additional beep mixers; the actual parameters are overwritten at build */
2108 static struct snd_kcontrol_new alc_beep_mixer[] = {
2109 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2110 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2114 static int alc_build_controls(struct hda_codec *codec)
2116 struct alc_spec *spec = codec->spec;
2120 for (i = 0; i < spec->num_mixers; i++) {
2121 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2125 if (spec->cap_mixer) {
2126 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2130 if (spec->multiout.dig_out_nid) {
2131 err = snd_hda_create_spdif_out_ctls(codec,
2132 spec->multiout.dig_out_nid);
2135 if (!spec->no_analog) {
2136 err = snd_hda_create_spdif_share_sw(codec,
2140 spec->multiout.share_spdif = 1;
2143 if (spec->dig_in_nid) {
2144 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2149 /* create beep controls if needed */
2150 if (spec->beep_amp) {
2151 struct snd_kcontrol_new *knew;
2152 for (knew = alc_beep_mixer; knew->name; knew++) {
2153 struct snd_kcontrol *kctl;
2154 kctl = snd_ctl_new1(knew, codec);
2157 kctl->private_value = spec->beep_amp;
2158 err = snd_hda_ctl_add(codec, kctl);
2164 /* if we have no master control, let's create it */
2165 if (!spec->no_analog &&
2166 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2167 unsigned int vmaster_tlv[4];
2168 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2169 HDA_OUTPUT, vmaster_tlv);
2170 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2171 vmaster_tlv, alc_slave_vols);
2175 if (!spec->no_analog &&
2176 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2177 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2178 NULL, alc_slave_sws);
2183 alc_free_kctls(codec); /* no longer needed */
2189 * initialize the codec volumes, etc
2193 * generic initialization of ADC, input mixers and output mixers
2195 static struct hda_verb alc880_volume_init_verbs[] = {
2197 * Unmute ADC0-2 and set the default input to mic-in
2199 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2201 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2202 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2203 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2204 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2206 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2208 * Note: PASD motherboards uses the Line In 2 as the input for front
2211 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2215 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2216 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2217 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2218 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2221 * Set up output mixers (0x0c - 0x0f)
2223 /* set vol=0 to output mixers */
2224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2225 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2226 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2227 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2228 /* set up input amps for analog loopback */
2229 /* Amp Indices: DAC = 0, mixer = 1 */
2230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2231 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2232 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2233 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2234 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2235 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2236 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2237 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2243 * 3-stack pin configuration:
2244 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2246 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2248 * preset connection lists of input pins
2249 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2251 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2252 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2253 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2256 * Set pin mode and muting
2258 /* set front pin widgets 0x14 for output */
2259 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2260 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2261 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2262 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2263 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2264 /* Mic2 (as headphone out) for HP output */
2265 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2266 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2267 /* Line In pin widget for input */
2268 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2269 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2270 /* Line2 (as front mic) pin widget for input and vref at 80% */
2271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2272 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2273 /* CD pin widget for input */
2274 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2280 * 5-stack pin configuration:
2281 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2282 * line-in/side = 0x1a, f-mic = 0x1b
2284 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2286 * preset connection lists of input pins
2287 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2289 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2290 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2293 * Set pin mode and muting
2295 /* set pin widgets 0x14-0x17 for output */
2296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2297 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2298 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2299 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2300 /* unmute pins for output (no gain on this amp) */
2301 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2304 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2306 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2307 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2308 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2309 /* Mic2 (as headphone out) for HP output */
2310 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2311 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2312 /* Line In pin widget for input */
2313 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2314 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2315 /* Line2 (as front mic) pin widget for input and vref at 80% */
2316 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2317 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2318 /* CD pin widget for input */
2319 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2325 * W810 pin configuration:
2326 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2328 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2329 /* hphone/speaker input selector: front DAC */
2330 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2332 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2333 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2334 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2335 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2336 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2337 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2339 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2340 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2346 * Z71V pin configuration:
2347 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2349 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2350 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2351 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2353 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2355 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2356 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2357 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2358 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2364 * 6-stack pin configuration:
2365 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2366 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2368 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2369 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2371 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2372 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2374 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2375 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2376 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2377 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2378 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2380 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2381 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2382 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2383 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2384 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2385 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2386 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2387 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2388 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2394 * Uniwill pin configuration:
2395 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2398 static struct hda_verb alc880_uniwill_init_verbs[] = {
2399 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2401 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2402 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2403 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2404 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2405 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2406 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2407 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2408 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2414 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2416 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2417 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2418 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2419 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2420 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2421 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2422 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2423 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2424 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2426 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2427 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2434 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2436 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2437 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2439 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2440 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2441 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2442 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2443 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2444 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2445 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2446 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2447 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2448 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2449 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2450 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2452 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2454 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2459 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2460 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2465 static struct hda_verb alc880_beep_init_verbs[] = {
2466 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2470 /* auto-toggle front mic */
2471 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2473 unsigned int present;
2476 present = snd_hda_codec_read(codec, 0x18, 0,
2477 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2478 bits = present ? HDA_AMP_MUTE : 0;
2479 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2482 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2484 struct alc_spec *spec = codec->spec;
2486 spec->autocfg.hp_pins[0] = 0x14;
2487 spec->autocfg.speaker_pins[0] = 0x15;
2488 spec->autocfg.speaker_pins[0] = 0x16;
2489 alc_automute_amp(codec);
2490 alc880_uniwill_mic_automute(codec);
2493 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2496 /* Looks like the unsol event is incompatible with the standard
2497 * definition. 4bit tag is placed at 28 bit!
2499 switch (res >> 28) {
2500 case ALC880_MIC_EVENT:
2501 alc880_uniwill_mic_automute(codec);
2504 alc_automute_amp_unsol_event(codec, res);
2509 static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2511 struct alc_spec *spec = codec->spec;
2513 spec->autocfg.hp_pins[0] = 0x14;
2514 spec->autocfg.speaker_pins[0] = 0x15;
2515 alc_automute_amp(codec);
2518 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2520 unsigned int present;
2522 present = snd_hda_codec_read(codec, 0x21, 0,
2523 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2524 present &= HDA_AMP_VOLMASK;
2525 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2526 HDA_AMP_VOLMASK, present);
2527 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2528 HDA_AMP_VOLMASK, present);
2531 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2534 /* Looks like the unsol event is incompatible with the standard
2535 * definition. 4bit tag is placed at 28 bit!
2537 if ((res >> 28) == ALC880_DCVOL_EVENT)
2538 alc880_uniwill_p53_dcvol_automute(codec);
2540 alc_automute_amp_unsol_event(codec, res);
2544 * F1734 pin configuration:
2545 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2547 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2548 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2549 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2550 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2551 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2552 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2554 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2555 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2556 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2557 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2561 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2562 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2563 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2564 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2565 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2566 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2567 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2569 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2570 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2576 * ASUS pin configuration:
2577 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2579 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2580 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2581 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2582 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2583 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2587 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2589 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2591 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2592 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2595 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2596 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2597 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2598 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2599 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2600 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2601 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2602 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2607 /* Enable GPIO mask and set output */
2608 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2609 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2611 /* Clevo m520g init */
2612 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2613 /* headphone output */
2614 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2617 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2619 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2620 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2622 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2623 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2624 /* Mic1 (rear panel) */
2625 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2626 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2627 /* Mic2 (front panel) */
2628 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2629 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2631 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2632 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2633 /* change to EAPD mode */
2634 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2635 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2640 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2641 /* change to EAPD mode */
2642 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2643 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2645 /* Headphone output */
2646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2648 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2649 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2651 /* Line In pin widget for input */
2652 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2653 /* CD pin widget for input */
2654 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2655 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2656 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2658 /* change to EAPD mode */
2659 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2660 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2666 * LG m1 express dual
2669 * Rear Line-In/Out (blue): 0x14
2670 * Build-in Mic-In: 0x15
2672 * HP-Out (green): 0x1b
2673 * Mic-In/Out (red): 0x19
2677 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2678 static hda_nid_t alc880_lg_dac_nids[3] = {
2682 /* seems analog CD is not working */
2683 static struct hda_input_mux alc880_lg_capture_source = {
2688 { "Internal Mic", 0x6 },
2692 /* 2,4,6 channel modes */
2693 static struct hda_verb alc880_lg_ch2_init[] = {
2694 /* set line-in and mic-in to input */
2695 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2696 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2700 static struct hda_verb alc880_lg_ch4_init[] = {
2701 /* set line-in to out and mic-in to input */
2702 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2703 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2707 static struct hda_verb alc880_lg_ch6_init[] = {
2708 /* set line-in and mic-in to output */
2709 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2710 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2714 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2715 { 2, alc880_lg_ch2_init },
2716 { 4, alc880_lg_ch4_init },
2717 { 6, alc880_lg_ch6_init },
2720 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2721 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2722 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2723 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2724 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2725 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2726 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2727 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2728 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2731 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2732 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2733 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2734 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2736 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2737 .name = "Channel Mode",
2738 .info = alc_ch_mode_info,
2739 .get = alc_ch_mode_get,
2740 .put = alc_ch_mode_put,
2745 static struct hda_verb alc880_lg_init_verbs[] = {
2746 /* set capture source to mic-in */
2747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2748 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2749 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2750 /* mute all amp mixer inputs */
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2753 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2754 /* line-in to input */
2755 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2758 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2759 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2761 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2762 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2763 /* mic-in to input */
2764 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2765 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2766 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2768 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2769 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2770 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2772 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2776 /* toggle speaker-output according to the hp-jack state */
2777 static void alc880_lg_init_hook(struct hda_codec *codec)
2779 struct alc_spec *spec = codec->spec;
2781 spec->autocfg.hp_pins[0] = 0x1b;
2782 spec->autocfg.speaker_pins[0] = 0x17;
2783 alc_automute_amp(codec);
2792 * Built-in Mic-In: 0x19
2798 static struct hda_input_mux alc880_lg_lw_capture_source = {
2802 { "Internal Mic", 0x1 },
2807 #define alc880_lg_lw_modes alc880_threestack_modes
2809 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2810 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2811 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2812 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2813 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2814 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2815 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2816 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2817 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2818 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2819 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2820 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2822 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2823 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2826 .name = "Channel Mode",
2827 .info = alc_ch_mode_info,
2828 .get = alc_ch_mode_get,
2829 .put = alc_ch_mode_put,
2834 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2835 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2836 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2837 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2839 /* set capture source to mic-in */
2840 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2841 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2842 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2843 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2848 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2849 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2850 /* mic-in to input */
2851 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2852 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2854 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2855 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2857 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2861 /* toggle speaker-output according to the hp-jack state */
2862 static void alc880_lg_lw_init_hook(struct hda_codec *codec)
2864 struct alc_spec *spec = codec->spec;
2866 spec->autocfg.hp_pins[0] = 0x1b;
2867 spec->autocfg.speaker_pins[0] = 0x14;
2868 alc_automute_amp(codec);
2871 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2872 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2873 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2876 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2877 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2881 static struct hda_input_mux alc880_medion_rim_capture_source = {
2885 { "Internal Mic", 0x1 },
2889 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2890 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2893 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2895 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2897 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2898 /* Mic2 (as headphone out) for HP output */
2899 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2900 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2901 /* Internal Speaker */
2902 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2903 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2905 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2906 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2908 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2912 /* toggle speaker-output according to the hp-jack state */
2913 static void alc880_medion_rim_automute(struct hda_codec *codec)
2915 struct alc_spec *spec = codec->spec;
2916 alc_automute_amp(codec);
2918 if (spec->jack_present)
2919 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2921 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2924 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2927 /* Looks like the unsol event is incompatible with the standard
2928 * definition. 4bit tag is placed at 28 bit!
2930 if ((res >> 28) == ALC880_HP_EVENT)
2931 alc880_medion_rim_automute(codec);
2934 static void alc880_medion_rim_init_hook(struct hda_codec *codec)
2936 struct alc_spec *spec = codec->spec;
2938 spec->autocfg.hp_pins[0] = 0x14;
2939 spec->autocfg.speaker_pins[0] = 0x1b;
2940 alc880_medion_rim_automute(codec);
2943 #ifdef CONFIG_SND_HDA_POWER_SAVE
2944 static struct hda_amp_list alc880_loopbacks[] = {
2945 { 0x0b, HDA_INPUT, 0 },
2946 { 0x0b, HDA_INPUT, 1 },
2947 { 0x0b, HDA_INPUT, 2 },
2948 { 0x0b, HDA_INPUT, 3 },
2949 { 0x0b, HDA_INPUT, 4 },
2953 static struct hda_amp_list alc880_lg_loopbacks[] = {
2954 { 0x0b, HDA_INPUT, 1 },
2955 { 0x0b, HDA_INPUT, 6 },
2956 { 0x0b, HDA_INPUT, 7 },
2965 static int alc_init(struct hda_codec *codec)
2967 struct alc_spec *spec = codec->spec;
2971 alc_auto_init_amp(codec, spec->init_amp);
2973 for (i = 0; i < spec->num_init_verbs; i++)
2974 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2976 if (spec->init_hook)
2977 spec->init_hook(codec);
2982 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2984 struct alc_spec *spec = codec->spec;
2986 if (spec->unsol_event)
2987 spec->unsol_event(codec, res);
2990 #ifdef CONFIG_SND_HDA_POWER_SAVE
2991 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2993 struct alc_spec *spec = codec->spec;
2994 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2999 * Analog playback callbacks
3001 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3002 struct hda_codec *codec,
3003 struct snd_pcm_substream *substream)
3005 struct alc_spec *spec = codec->spec;
3006 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3010 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3011 struct hda_codec *codec,
3012 unsigned int stream_tag,
3013 unsigned int format,
3014 struct snd_pcm_substream *substream)
3016 struct alc_spec *spec = codec->spec;
3017 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3018 stream_tag, format, substream);
3021 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3022 struct hda_codec *codec,
3023 struct snd_pcm_substream *substream)
3025 struct alc_spec *spec = codec->spec;
3026 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3032 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3033 struct hda_codec *codec,
3034 struct snd_pcm_substream *substream)
3036 struct alc_spec *spec = codec->spec;
3037 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3040 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3041 struct hda_codec *codec,
3042 unsigned int stream_tag,
3043 unsigned int format,
3044 struct snd_pcm_substream *substream)
3046 struct alc_spec *spec = codec->spec;
3047 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3048 stream_tag, format, substream);
3051 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3052 struct hda_codec *codec,
3053 struct snd_pcm_substream *substream)
3055 struct alc_spec *spec = codec->spec;
3056 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3059 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3060 struct hda_codec *codec,
3061 struct snd_pcm_substream *substream)
3063 struct alc_spec *spec = codec->spec;
3064 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3070 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3071 struct hda_codec *codec,
3072 unsigned int stream_tag,
3073 unsigned int format,
3074 struct snd_pcm_substream *substream)
3076 struct alc_spec *spec = codec->spec;
3078 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3079 stream_tag, 0, format);
3083 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3084 struct hda_codec *codec,
3085 struct snd_pcm_substream *substream)
3087 struct alc_spec *spec = codec->spec;
3089 snd_hda_codec_cleanup_stream(codec,
3090 spec->adc_nids[substream->number + 1]);
3097 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3101 /* NID is set in alc_build_pcms */
3103 .open = alc880_playback_pcm_open,
3104 .prepare = alc880_playback_pcm_prepare,
3105 .cleanup = alc880_playback_pcm_cleanup
3109 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3113 /* NID is set in alc_build_pcms */
3116 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3120 /* NID is set in alc_build_pcms */
3123 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3124 .substreams = 2, /* can be overridden */
3127 /* NID is set in alc_build_pcms */
3129 .prepare = alc880_alt_capture_pcm_prepare,
3130 .cleanup = alc880_alt_capture_pcm_cleanup
3134 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3138 /* NID is set in alc_build_pcms */
3140 .open = alc880_dig_playback_pcm_open,
3141 .close = alc880_dig_playback_pcm_close,
3142 .prepare = alc880_dig_playback_pcm_prepare,
3143 .cleanup = alc880_dig_playback_pcm_cleanup
3147 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3151 /* NID is set in alc_build_pcms */
3154 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3155 static struct hda_pcm_stream alc_pcm_null_stream = {
3161 static int alc_build_pcms(struct hda_codec *codec)
3163 struct alc_spec *spec = codec->spec;
3164 struct hda_pcm *info = spec->pcm_rec;
3167 codec->num_pcms = 1;
3168 codec->pcm_info = info;
3170 if (spec->no_analog)
3173 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3174 "%s Analog", codec->chip_name);
3175 info->name = spec->stream_name_analog;
3177 if (spec->stream_analog_playback) {
3178 if (snd_BUG_ON(!spec->multiout.dac_nids))
3180 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3181 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3183 if (spec->stream_analog_capture) {
3184 if (snd_BUG_ON(!spec->adc_nids))
3186 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3187 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3190 if (spec->channel_mode) {
3191 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3192 for (i = 0; i < spec->num_channel_mode; i++) {
3193 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3194 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3200 /* SPDIF for stream index #1 */
3201 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3202 snprintf(spec->stream_name_digital,
3203 sizeof(spec->stream_name_digital),
3204 "%s Digital", codec->chip_name);
3205 codec->num_pcms = 2;
3206 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3207 info = spec->pcm_rec + 1;
3208 info->name = spec->stream_name_digital;
3209 if (spec->dig_out_type)
3210 info->pcm_type = spec->dig_out_type;
3212 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3213 if (spec->multiout.dig_out_nid &&
3214 spec->stream_digital_playback) {
3215 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3216 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3218 if (spec->dig_in_nid &&
3219 spec->stream_digital_capture) {
3220 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3221 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3223 /* FIXME: do we need this for all Realtek codec models? */
3224 codec->spdif_status_reset = 1;
3227 if (spec->no_analog)
3230 /* If the use of more than one ADC is requested for the current
3231 * model, configure a second analog capture-only PCM.
3233 /* Additional Analaog capture for index #2 */
3234 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3235 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3236 codec->num_pcms = 3;
3237 info = spec->pcm_rec + 2;
3238 info->name = spec->stream_name_analog;
3239 if (spec->alt_dac_nid) {
3240 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3241 *spec->stream_analog_alt_playback;
3242 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3245 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3246 alc_pcm_null_stream;
3247 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3249 if (spec->num_adc_nids > 1) {
3250 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3251 *spec->stream_analog_alt_capture;
3252 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3254 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3255 spec->num_adc_nids - 1;
3257 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3258 alc_pcm_null_stream;
3259 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3266 static void alc_free_kctls(struct hda_codec *codec)
3268 struct alc_spec *spec = codec->spec;
3270 if (spec->kctls.list) {
3271 struct snd_kcontrol_new *kctl = spec->kctls.list;
3273 for (i = 0; i < spec->kctls.used; i++)
3274 kfree(kctl[i].name);
3276 snd_array_free(&spec->kctls);
3279 static void alc_free(struct hda_codec *codec)
3281 struct alc_spec *spec = codec->spec;
3286 alc_free_kctls(codec);
3288 snd_hda_detach_beep_device(codec);
3291 #ifdef SND_HDA_NEEDS_RESUME
3292 static int alc_resume(struct hda_codec *codec)
3294 codec->patch_ops.init(codec);
3295 snd_hda_codec_resume_amp(codec);
3296 snd_hda_codec_resume_cache(codec);
3303 static struct hda_codec_ops alc_patch_ops = {
3304 .build_controls = alc_build_controls,
3305 .build_pcms = alc_build_pcms,
3308 .unsol_event = alc_unsol_event,
3309 #ifdef SND_HDA_NEEDS_RESUME
3310 .resume = alc_resume,
3312 #ifdef CONFIG_SND_HDA_POWER_SAVE
3313 .check_power_status = alc_check_power_status,
3319 * Test configuration for debugging
3321 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3324 #ifdef CONFIG_SND_DEBUG
3325 static hda_nid_t alc880_test_dac_nids[4] = {
3326 0x02, 0x03, 0x04, 0x05
3329 static struct hda_input_mux alc880_test_capture_source = {
3338 { "Surround", 0x6 },
3342 static struct hda_channel_mode alc880_test_modes[4] = {
3349 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3350 struct snd_ctl_elem_info *uinfo)
3352 static char *texts[] = {
3353 "N/A", "Line Out", "HP Out",
3354 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3356 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3358 uinfo->value.enumerated.items = 8;
3359 if (uinfo->value.enumerated.item >= 8)
3360 uinfo->value.enumerated.item = 7;
3361 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3365 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3366 struct snd_ctl_elem_value *ucontrol)
3368 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3369 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3370 unsigned int pin_ctl, item = 0;
3372 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3373 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3374 if (pin_ctl & AC_PINCTL_OUT_EN) {
3375 if (pin_ctl & AC_PINCTL_HP_EN)
3379 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3380 switch (pin_ctl & AC_PINCTL_VREFEN) {
3381 case AC_PINCTL_VREF_HIZ: item = 3; break;
3382 case AC_PINCTL_VREF_50: item = 4; break;
3383 case AC_PINCTL_VREF_GRD: item = 5; break;
3384 case AC_PINCTL_VREF_80: item = 6; break;
3385 case AC_PINCTL_VREF_100: item = 7; break;
3388 ucontrol->value.enumerated.item[0] = item;
3392 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3393 struct snd_ctl_elem_value *ucontrol)
3395 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3396 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3397 static unsigned int ctls[] = {
3398 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3399 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3400 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3401 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3402 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3403 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3405 unsigned int old_ctl, new_ctl;
3407 old_ctl = snd_hda_codec_read(codec, nid, 0,
3408 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3409 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3410 if (old_ctl != new_ctl) {
3412 snd_hda_codec_write_cache(codec, nid, 0,
3413 AC_VERB_SET_PIN_WIDGET_CONTROL,
3415 val = ucontrol->value.enumerated.item[0] >= 3 ?
3417 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3424 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3425 struct snd_ctl_elem_info *uinfo)
3427 static char *texts[] = {
3428 "Front", "Surround", "CLFE", "Side"
3430 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3432 uinfo->value.enumerated.items = 4;
3433 if (uinfo->value.enumerated.item >= 4)
3434 uinfo->value.enumerated.item = 3;
3435 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3439 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3440 struct snd_ctl_elem_value *ucontrol)
3442 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3443 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3446 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3447 ucontrol->value.enumerated.item[0] = sel & 3;
3451 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3452 struct snd_ctl_elem_value *ucontrol)
3454 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3455 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3458 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3459 if (ucontrol->value.enumerated.item[0] != sel) {
3460 sel = ucontrol->value.enumerated.item[0] & 3;
3461 snd_hda_codec_write_cache(codec, nid, 0,
3462 AC_VERB_SET_CONNECT_SEL, sel);
3468 #define PIN_CTL_TEST(xname,nid) { \
3469 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3471 .info = alc_test_pin_ctl_info, \
3472 .get = alc_test_pin_ctl_get, \
3473 .put = alc_test_pin_ctl_put, \
3474 .private_value = nid \
3477 #define PIN_SRC_TEST(xname,nid) { \
3478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3480 .info = alc_test_pin_src_info, \
3481 .get = alc_test_pin_src_get, \
3482 .put = alc_test_pin_src_put, \
3483 .private_value = nid \
3486 static struct snd_kcontrol_new alc880_test_mixer[] = {
3487 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3488 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3489 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3490 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3491 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3492 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3493 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3494 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3495 PIN_CTL_TEST("Front Pin Mode", 0x14),
3496 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3497 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3498 PIN_CTL_TEST("Side Pin Mode", 0x17),
3499 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3500 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3501 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3502 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3503 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3504 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3505 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3506 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3507 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3508 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3509 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3510 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3511 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3512 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3513 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3514 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3515 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3516 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3519 .name = "Channel Mode",
3520 .info = alc_ch_mode_info,
3521 .get = alc_ch_mode_get,
3522 .put = alc_ch_mode_put,
3527 static struct hda_verb alc880_test_init_verbs[] = {
3528 /* Unmute inputs of 0x0c - 0x0f */
3529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3530 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3531 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3533 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3534 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3535 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3536 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3537 /* Vol output for 0x0c-0x0f */
3538 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3539 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3540 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3541 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3542 /* Set output pins 0x14-0x17 */
3543 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3545 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3546 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3547 /* Unmute output pins 0x14-0x17 */
3548 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3549 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3550 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3551 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3552 /* Set input pins 0x18-0x1c */
3553 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3554 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3555 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3556 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3557 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3558 /* Mute input pins 0x18-0x1b */
3559 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3560 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3561 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3562 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3564 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3565 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3566 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3567 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3568 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3569 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3570 /* Analog input/passthru */
3571 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3572 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3573 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3583 static const char *alc880_models[ALC880_MODEL_LAST] = {
3584 [ALC880_3ST] = "3stack",
3585 [ALC880_TCL_S700] = "tcl",
3586 [ALC880_3ST_DIG] = "3stack-digout",
3587 [ALC880_CLEVO] = "clevo",
3588 [ALC880_5ST] = "5stack",
3589 [ALC880_5ST_DIG] = "5stack-digout",
3590 [ALC880_W810] = "w810",
3591 [ALC880_Z71V] = "z71v",
3592 [ALC880_6ST] = "6stack",
3593 [ALC880_6ST_DIG] = "6stack-digout",
3594 [ALC880_ASUS] = "asus",
3595 [ALC880_ASUS_W1V] = "asus-w1v",
3596 [ALC880_ASUS_DIG] = "asus-dig",
3597 [ALC880_ASUS_DIG2] = "asus-dig2",
3598 [ALC880_UNIWILL_DIG] = "uniwill",
3599 [ALC880_UNIWILL_P53] = "uniwill-p53",
3600 [ALC880_FUJITSU] = "fujitsu",
3601 [ALC880_F1734] = "F1734",
3603 [ALC880_LG_LW] = "lg-lw",
3604 [ALC880_MEDION_RIM] = "medion",
3605 #ifdef CONFIG_SND_DEBUG
3606 [ALC880_TEST] = "test",
3608 [ALC880_AUTO] = "auto",
3611 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3612 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3613 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3614 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3615 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3616 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3617 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3618 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3619 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3620 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3621 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3622 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3623 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3624 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3625 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3626 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3627 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3628 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3629 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3630 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3631 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3632 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3633 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3634 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3635 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3636 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3637 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3638 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3639 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3640 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3641 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3642 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3643 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3644 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3645 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3646 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3647 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3648 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3649 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3650 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3651 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3652 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3653 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3654 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3655 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3656 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3657 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3658 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3659 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3660 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3661 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3662 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3663 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3664 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3665 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3666 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3667 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3668 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3669 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3670 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3671 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3672 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3673 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3674 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3675 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3676 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3677 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3678 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3679 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3681 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3682 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3683 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3688 * ALC880 codec presets
3690 static struct alc_config_preset alc880_presets[] = {
3692 .mixers = { alc880_three_stack_mixer },
3693 .init_verbs = { alc880_volume_init_verbs,
3694 alc880_pin_3stack_init_verbs },
3695 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3696 .dac_nids = alc880_dac_nids,
3697 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3698 .channel_mode = alc880_threestack_modes,
3700 .input_mux = &alc880_capture_source,
3702 [ALC880_3ST_DIG] = {
3703 .mixers = { alc880_three_stack_mixer },
3704 .init_verbs = { alc880_volume_init_verbs,
3705 alc880_pin_3stack_init_verbs },
3706 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3707 .dac_nids = alc880_dac_nids,
3708 .dig_out_nid = ALC880_DIGOUT_NID,
3709 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3710 .channel_mode = alc880_threestack_modes,
3712 .input_mux = &alc880_capture_source,
3714 [ALC880_TCL_S700] = {
3715 .mixers = { alc880_tcl_s700_mixer },
3716 .init_verbs = { alc880_volume_init_verbs,
3717 alc880_pin_tcl_S700_init_verbs,
3718 alc880_gpio2_init_verbs },
3719 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3720 .dac_nids = alc880_dac_nids,
3721 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3722 .num_adc_nids = 1, /* single ADC */
3724 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3725 .channel_mode = alc880_2_jack_modes,
3726 .input_mux = &alc880_capture_source,
3729 .mixers = { alc880_three_stack_mixer,
3730 alc880_five_stack_mixer},
3731 .init_verbs = { alc880_volume_init_verbs,
3732 alc880_pin_5stack_init_verbs },
3733 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3734 .dac_nids = alc880_dac_nids,
3735 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3736 .channel_mode = alc880_fivestack_modes,
3737 .input_mux = &alc880_capture_source,
3739 [ALC880_5ST_DIG] = {
3740 .mixers = { alc880_three_stack_mixer,
3741 alc880_five_stack_mixer },
3742 .init_verbs = { alc880_volume_init_verbs,
3743 alc880_pin_5stack_init_verbs },
3744 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3745 .dac_nids = alc880_dac_nids,
3746 .dig_out_nid = ALC880_DIGOUT_NID,
3747 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3748 .channel_mode = alc880_fivestack_modes,
3749 .input_mux = &alc880_capture_source,
3752 .mixers = { alc880_six_stack_mixer },
3753 .init_verbs = { alc880_volume_init_verbs,
3754 alc880_pin_6stack_init_verbs },
3755 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3756 .dac_nids = alc880_6st_dac_nids,
3757 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3758 .channel_mode = alc880_sixstack_modes,
3759 .input_mux = &alc880_6stack_capture_source,
3761 [ALC880_6ST_DIG] = {
3762 .mixers = { alc880_six_stack_mixer },
3763 .init_verbs = { alc880_volume_init_verbs,
3764 alc880_pin_6stack_init_verbs },
3765 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3766 .dac_nids = alc880_6st_dac_nids,
3767 .dig_out_nid = ALC880_DIGOUT_NID,
3768 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3769 .channel_mode = alc880_sixstack_modes,
3770 .input_mux = &alc880_6stack_capture_source,
3773 .mixers = { alc880_w810_base_mixer },
3774 .init_verbs = { alc880_volume_init_verbs,
3775 alc880_pin_w810_init_verbs,
3776 alc880_gpio2_init_verbs },
3777 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3778 .dac_nids = alc880_w810_dac_nids,
3779 .dig_out_nid = ALC880_DIGOUT_NID,
3780 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3781 .channel_mode = alc880_w810_modes,
3782 .input_mux = &alc880_capture_source,
3785 .mixers = { alc880_z71v_mixer },
3786 .init_verbs = { alc880_volume_init_verbs,
3787 alc880_pin_z71v_init_verbs },
3788 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3789 .dac_nids = alc880_z71v_dac_nids,
3790 .dig_out_nid = ALC880_DIGOUT_NID,
3792 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3793 .channel_mode = alc880_2_jack_modes,
3794 .input_mux = &alc880_capture_source,
3797 .mixers = { alc880_f1734_mixer },
3798 .init_verbs = { alc880_volume_init_verbs,
3799 alc880_pin_f1734_init_verbs },
3800 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3801 .dac_nids = alc880_f1734_dac_nids,
3803 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3804 .channel_mode = alc880_2_jack_modes,
3805 .input_mux = &alc880_f1734_capture_source,
3806 .unsol_event = alc880_uniwill_p53_unsol_event,
3807 .init_hook = alc880_uniwill_p53_init_hook,
3810 .mixers = { alc880_asus_mixer },
3811 .init_verbs = { alc880_volume_init_verbs,
3812 alc880_pin_asus_init_verbs,
3813 alc880_gpio1_init_verbs },
3814 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3815 .dac_nids = alc880_asus_dac_nids,
3816 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3817 .channel_mode = alc880_asus_modes,
3819 .input_mux = &alc880_capture_source,
3821 [ALC880_ASUS_DIG] = {
3822 .mixers = { alc880_asus_mixer },
3823 .init_verbs = { alc880_volume_init_verbs,
3824 alc880_pin_asus_init_verbs,
3825 alc880_gpio1_init_verbs },
3826 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3827 .dac_nids = alc880_asus_dac_nids,
3828 .dig_out_nid = ALC880_DIGOUT_NID,
3829 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3830 .channel_mode = alc880_asus_modes,
3832 .input_mux = &alc880_capture_source,
3834 [ALC880_ASUS_DIG2] = {
3835 .mixers = { alc880_asus_mixer },
3836 .init_verbs = { alc880_volume_init_verbs,
3837 alc880_pin_asus_init_verbs,
3838 alc880_gpio2_init_verbs }, /* use GPIO2 */
3839 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3840 .dac_nids = alc880_asus_dac_nids,
3841 .dig_out_nid = ALC880_DIGOUT_NID,
3842 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3843 .channel_mode = alc880_asus_modes,
3845 .input_mux = &alc880_capture_source,
3847 [ALC880_ASUS_W1V] = {
3848 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3849 .init_verbs = { alc880_volume_init_verbs,
3850 alc880_pin_asus_init_verbs,
3851 alc880_gpio1_init_verbs },
3852 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3853 .dac_nids = alc880_asus_dac_nids,
3854 .dig_out_nid = ALC880_DIGOUT_NID,
3855 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3856 .channel_mode = alc880_asus_modes,
3858 .input_mux = &alc880_capture_source,
3860 [ALC880_UNIWILL_DIG] = {
3861 .mixers = { alc880_asus_mixer },
3862 .init_verbs = { alc880_volume_init_verbs,
3863 alc880_pin_asus_init_verbs },
3864 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3865 .dac_nids = alc880_asus_dac_nids,
3866 .dig_out_nid = ALC880_DIGOUT_NID,
3867 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3868 .channel_mode = alc880_asus_modes,
3870 .input_mux = &alc880_capture_source,
3872 [ALC880_UNIWILL] = {
3873 .mixers = { alc880_uniwill_mixer },
3874 .init_verbs = { alc880_volume_init_verbs,
3875 alc880_uniwill_init_verbs },
3876 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3877 .dac_nids = alc880_asus_dac_nids,
3878 .dig_out_nid = ALC880_DIGOUT_NID,
3879 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3880 .channel_mode = alc880_threestack_modes,
3882 .input_mux = &alc880_capture_source,
3883 .unsol_event = alc880_uniwill_unsol_event,
3884 .init_hook = alc880_uniwill_init_hook,
3886 [ALC880_UNIWILL_P53] = {
3887 .mixers = { alc880_uniwill_p53_mixer },
3888 .init_verbs = { alc880_volume_init_verbs,
3889 alc880_uniwill_p53_init_verbs },
3890 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3891 .dac_nids = alc880_asus_dac_nids,
3892 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3893 .channel_mode = alc880_threestack_modes,
3894 .input_mux = &alc880_capture_source,
3895 .unsol_event = alc880_uniwill_p53_unsol_event,
3896 .init_hook = alc880_uniwill_p53_init_hook,
3898 [ALC880_FUJITSU] = {
3899 .mixers = { alc880_fujitsu_mixer },
3900 .init_verbs = { alc880_volume_init_verbs,
3901 alc880_uniwill_p53_init_verbs,
3902 alc880_beep_init_verbs },
3903 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3904 .dac_nids = alc880_dac_nids,
3905 .dig_out_nid = ALC880_DIGOUT_NID,
3906 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3907 .channel_mode = alc880_2_jack_modes,
3908 .input_mux = &alc880_capture_source,
3909 .unsol_event = alc880_uniwill_p53_unsol_event,
3910 .init_hook = alc880_uniwill_p53_init_hook,
3913 .mixers = { alc880_three_stack_mixer },
3914 .init_verbs = { alc880_volume_init_verbs,
3915 alc880_pin_clevo_init_verbs },
3916 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3917 .dac_nids = alc880_dac_nids,
3919 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3920 .channel_mode = alc880_threestack_modes,
3922 .input_mux = &alc880_capture_source,
3925 .mixers = { alc880_lg_mixer },
3926 .init_verbs = { alc880_volume_init_verbs,
3927 alc880_lg_init_verbs },
3928 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3929 .dac_nids = alc880_lg_dac_nids,
3930 .dig_out_nid = ALC880_DIGOUT_NID,
3931 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3932 .channel_mode = alc880_lg_ch_modes,
3934 .input_mux = &alc880_lg_capture_source,
3935 .unsol_event = alc_automute_amp_unsol_event,
3936 .init_hook = alc880_lg_init_hook,
3937 #ifdef CONFIG_SND_HDA_POWER_SAVE
3938 .loopbacks = alc880_lg_loopbacks,
3942 .mixers = { alc880_lg_lw_mixer },
3943 .init_verbs = { alc880_volume_init_verbs,
3944 alc880_lg_lw_init_verbs },
3945 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3946 .dac_nids = alc880_dac_nids,
3947 .dig_out_nid = ALC880_DIGOUT_NID,
3948 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3949 .channel_mode = alc880_lg_lw_modes,
3950 .input_mux = &alc880_lg_lw_capture_source,
3951 .unsol_event = alc_automute_amp_unsol_event,
3952 .init_hook = alc880_lg_lw_init_hook,
3954 [ALC880_MEDION_RIM] = {
3955 .mixers = { alc880_medion_rim_mixer },
3956 .init_verbs = { alc880_volume_init_verbs,
3957 alc880_medion_rim_init_verbs,
3958 alc_gpio2_init_verbs },
3959 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3960 .dac_nids = alc880_dac_nids,
3961 .dig_out_nid = ALC880_DIGOUT_NID,
3962 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3963 .channel_mode = alc880_2_jack_modes,
3964 .input_mux = &alc880_medion_rim_capture_source,
3965 .unsol_event = alc880_medion_rim_unsol_event,
3966 .init_hook = alc880_medion_rim_init_hook,
3968 #ifdef CONFIG_SND_DEBUG
3970 .mixers = { alc880_test_mixer },
3971 .init_verbs = { alc880_test_init_verbs },
3972 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3973 .dac_nids = alc880_test_dac_nids,
3974 .dig_out_nid = ALC880_DIGOUT_NID,
3975 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3976 .channel_mode = alc880_test_modes,
3977 .input_mux = &alc880_test_capture_source,
3983 * Automatic parse of I/O pins from the BIOS configuration
3988 ALC_CTL_WIDGET_MUTE,
3991 static struct snd_kcontrol_new alc880_control_templates[] = {
3992 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3993 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3994 HDA_BIND_MUTE(NULL, 0, 0, 0),
3997 /* add dynamic controls */
3998 static int add_control(struct alc_spec *spec, int type, const char *name,
4001 struct snd_kcontrol_new *knew;
4003 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4004 knew = snd_array_new(&spec->kctls);
4007 *knew = alc880_control_templates[type];
4008 knew->name = kstrdup(name, GFP_KERNEL);
4011 knew->private_value = val;
4015 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4016 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4017 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4018 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4019 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4020 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4021 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4022 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4023 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4024 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4025 #define ALC880_PIN_CD_NID 0x1c
4027 /* fill in the dac_nids table from the parsed pin configuration */
4028 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4029 const struct auto_pin_cfg *cfg)
4035 memset(assigned, 0, sizeof(assigned));
4036 spec->multiout.dac_nids = spec->private_dac_nids;
4038 /* check the pins hardwired to audio widget */
4039 for (i = 0; i < cfg->line_outs; i++) {
4040 nid = cfg->line_out_pins[i];
4041 if (alc880_is_fixed_pin(nid)) {
4042 int idx = alc880_fixed_pin_idx(nid);
4043 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4047 /* left pins can be connect to any audio widget */
4048 for (i = 0; i < cfg->line_outs; i++) {
4049 nid = cfg->line_out_pins[i];
4050 if (alc880_is_fixed_pin(nid))
4052 /* search for an empty channel */
4053 for (j = 0; j < cfg->line_outs; j++) {
4055 spec->multiout.dac_nids[i] =
4056 alc880_idx_to_dac(j);
4062 spec->multiout.num_dacs = cfg->line_outs;
4066 /* add playback controls from the parsed DAC table */
4067 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4068 const struct auto_pin_cfg *cfg)
4071 static const char *chname[4] = {
4072 "Front", "Surround", NULL /*CLFE*/, "Side"
4077 for (i = 0; i < cfg->line_outs; i++) {
4078 if (!spec->multiout.dac_nids[i])
4080 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4083 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4084 "Center Playback Volume",
4085 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4089 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4090 "LFE Playback Volume",
4091 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4095 err = add_control(spec, ALC_CTL_BIND_MUTE,
4096 "Center Playback Switch",
4097 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4101 err = add_control(spec, ALC_CTL_BIND_MUTE,
4102 "LFE Playback Switch",
4103 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4108 sprintf(name, "%s Playback Volume", chname[i]);
4109 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4110 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4114 sprintf(name, "%s Playback Switch", chname[i]);
4115 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4116 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4125 /* add playback controls for speaker and HP outputs */
4126 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4136 if (alc880_is_fixed_pin(pin)) {
4137 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4138 /* specify the DAC as the extra output */
4139 if (!spec->multiout.hp_nid)
4140 spec->multiout.hp_nid = nid;
4142 spec->multiout.extra_out_nid[0] = nid;
4143 /* control HP volume/switch on the output mixer amp */
4144 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4145 sprintf(name, "%s Playback Volume", pfx);
4146 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4147 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4150 sprintf(name, "%s Playback Switch", pfx);
4151 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4152 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4155 } else if (alc880_is_multi_pin(pin)) {
4156 /* set manual connection */
4157 /* we have only a switch on HP-out PIN */
4158 sprintf(name, "%s Playback Switch", pfx);
4159 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4160 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4167 /* create input playback/capture controls for the given pin */
4168 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4169 const char *ctlname,
4170 int idx, hda_nid_t mix_nid)
4175 sprintf(name, "%s Playback Volume", ctlname);
4176 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4177 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4180 sprintf(name, "%s Playback Switch", ctlname);
4181 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4182 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4188 /* create playback/capture controls for input pins */
4189 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4190 const struct auto_pin_cfg *cfg)
4192 struct hda_input_mux *imux = &spec->private_imux[0];
4195 for (i = 0; i < AUTO_PIN_LAST; i++) {
4196 if (alc880_is_input_pin(cfg->input_pins[i])) {
4197 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4198 err = new_analog_input(spec, cfg->input_pins[i],
4199 auto_pin_cfg_labels[i],
4203 imux->items[imux->num_items].label =
4204 auto_pin_cfg_labels[i];
4205 imux->items[imux->num_items].index =
4206 alc880_input_pin_idx(cfg->input_pins[i]);
4213 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4214 unsigned int pin_type)
4216 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4219 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4223 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4224 hda_nid_t nid, int pin_type,
4227 alc_set_pin_output(codec, nid, pin_type);
4228 /* need the manual connection? */
4229 if (alc880_is_multi_pin(nid)) {
4230 struct alc_spec *spec = codec->spec;
4231 int idx = alc880_multi_pin_idx(nid);
4232 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4233 AC_VERB_SET_CONNECT_SEL,
4234 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4238 static int get_pin_type(int line_out_type)
4240 if (line_out_type == AUTO_PIN_HP_OUT)
4246 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4248 struct alc_spec *spec = codec->spec;
4251 for (i = 0; i < spec->autocfg.line_outs; i++) {
4252 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4253 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4254 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4258 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4260 struct alc_spec *spec = codec->spec;
4263 pin = spec->autocfg.speaker_pins[0];
4264 if (pin) /* connect to front */
4265 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4266 pin = spec->autocfg.hp_pins[0];
4267 if (pin) /* connect to front */
4268 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4271 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4273 struct alc_spec *spec = codec->spec;
4276 for (i = 0; i < AUTO_PIN_LAST; i++) {
4277 hda_nid_t nid = spec->autocfg.input_pins[i];
4278 if (alc880_is_input_pin(nid)) {
4279 alc_set_input_pin(codec, nid, i);
4280 if (nid != ALC880_PIN_CD_NID &&
4281 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4282 snd_hda_codec_write(codec, nid, 0,
4283 AC_VERB_SET_AMP_GAIN_MUTE,
4289 /* parse the BIOS configuration and set up the alc_spec */
4290 /* return 1 if successful, 0 if the proper config is not found,
4291 * or a negative error code
4293 static int alc880_parse_auto_config(struct hda_codec *codec)
4295 struct alc_spec *spec = codec->spec;
4297 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4299 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4303 if (!spec->autocfg.line_outs)
4304 return 0; /* can't find valid BIOS pin config */
4306 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4309 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4312 err = alc880_auto_create_extra_out(spec,
4313 spec->autocfg.speaker_pins[0],
4317 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4321 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4325 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4327 /* check multiple SPDIF-out (for recent codecs) */
4328 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4330 err = snd_hda_get_connections(codec,
4331 spec->autocfg.dig_out_pins[i],
4336 spec->multiout.dig_out_nid = dig_nid;
4338 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4339 spec->slave_dig_outs[i - 1] = dig_nid;
4340 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4344 if (spec->autocfg.dig_in_pin)
4345 spec->dig_in_nid = ALC880_DIGIN_NID;
4347 if (spec->kctls.list)
4348 add_mixer(spec, spec->kctls.list);
4350 add_verb(spec, alc880_volume_init_verbs);
4352 spec->num_mux_defs = 1;
4353 spec->input_mux = &spec->private_imux[0];
4355 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4360 /* additional initialization for auto-configuration model */
4361 static void alc880_auto_init(struct hda_codec *codec)
4363 struct alc_spec *spec = codec->spec;
4364 alc880_auto_init_multi_out(codec);
4365 alc880_auto_init_extra_out(codec);
4366 alc880_auto_init_analog_input(codec);
4367 if (spec->unsol_event)
4368 alc_inithook(codec);
4371 static void set_capture_mixer(struct alc_spec *spec)
4373 static struct snd_kcontrol_new *caps[2][3] = {
4374 { alc_capture_mixer_nosrc1,
4375 alc_capture_mixer_nosrc2,
4376 alc_capture_mixer_nosrc3 },
4377 { alc_capture_mixer1,
4379 alc_capture_mixer3 },
4381 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4383 if (spec->input_mux && spec->input_mux->num_items > 1)
4387 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4391 #define set_beep_amp(spec, nid, idx, dir) \
4392 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4395 * OK, here we have finally the patch for ALC880
4398 static int patch_alc880(struct hda_codec *codec)
4400 struct alc_spec *spec;
4404 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4410 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4413 if (board_config < 0) {
4414 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4415 "trying auto-probe from BIOS...\n", codec->chip_name);
4416 board_config = ALC880_AUTO;
4419 if (board_config == ALC880_AUTO) {
4420 /* automatic parse from the BIOS config */
4421 err = alc880_parse_auto_config(codec);
4427 "hda_codec: Cannot set up configuration "
4428 "from BIOS. Using 3-stack mode...\n");
4429 board_config = ALC880_3ST;
4433 err = snd_hda_attach_beep_device(codec, 0x1);
4439 if (board_config != ALC880_AUTO)
4440 setup_preset(spec, &alc880_presets[board_config]);
4442 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4443 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4444 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4446 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4447 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4449 if (!spec->adc_nids && spec->input_mux) {
4450 /* check whether NID 0x07 is valid */
4451 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4453 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4454 if (wcap != AC_WID_AUD_IN) {
4455 spec->adc_nids = alc880_adc_nids_alt;
4456 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4458 spec->adc_nids = alc880_adc_nids;
4459 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4462 set_capture_mixer(spec);
4463 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4465 spec->vmaster_nid = 0x0c;
4467 codec->patch_ops = alc_patch_ops;
4468 if (board_config == ALC880_AUTO)
4469 spec->init_hook = alc880_auto_init;
4470 #ifdef CONFIG_SND_HDA_POWER_SAVE
4471 if (!spec->loopback.amplist)
4472 spec->loopback.amplist = alc880_loopbacks;
4474 codec->proc_widget_hook = print_realtek_coef;
4484 static hda_nid_t alc260_dac_nids[1] = {
4489 static hda_nid_t alc260_adc_nids[1] = {
4494 static hda_nid_t alc260_adc_nids_alt[1] = {
4499 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4500 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4502 static hda_nid_t alc260_dual_adc_nids[2] = {
4507 #define ALC260_DIGOUT_NID 0x03
4508 #define ALC260_DIGIN_NID 0x06
4510 static struct hda_input_mux alc260_capture_source = {
4514 { "Front Mic", 0x1 },
4520 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4521 * headphone jack and the internal CD lines since these are the only pins at
4522 * which audio can appear. For flexibility, also allow the option of
4523 * recording the mixer output on the second ADC (ADC0 doesn't have a
4524 * connection to the mixer output).
4526 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4530 { "Mic/Line", 0x0 },
4532 { "Headphone", 0x2 },
4538 { "Mic/Line", 0x0 },
4540 { "Headphone", 0x2 },
4547 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4548 * the Fujitsu S702x, but jacks are marked differently.
4550 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4557 { "Headphone", 0x5 },
4566 { "Headphone", 0x6 },
4572 /* Maxdata Favorit 100XS */
4573 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4577 { "Line/Mic", 0x0 },
4584 { "Line/Mic", 0x0 },
4592 * This is just place-holder, so there's something for alc_build_pcms to look
4593 * at when it calculates the maximum number of channels. ALC260 has no mixer
4594 * element which allows changing the channel mode, so the verb list is
4597 static struct hda_channel_mode alc260_modes[1] = {
4602 /* Mixer combinations
4604 * basic: base_output + input + pc_beep + capture
4605 * HP: base_output + input + capture_alt
4606 * HP_3013: hp_3013 + input + capture
4607 * fujitsu: fujitsu + capture
4608 * acer: acer + capture
4611 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4612 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4613 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4614 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4615 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4616 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4617 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4621 static struct snd_kcontrol_new alc260_input_mixer[] = {
4622 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4623 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4624 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4625 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4627 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4628 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4629 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4633 /* update HP, line and mono out pins according to the master switch */
4634 static void alc260_hp_master_update(struct hda_codec *codec,
4635 hda_nid_t hp, hda_nid_t line,
4638 struct alc_spec *spec = codec->spec;
4639 unsigned int val = spec->master_sw ? PIN_HP : 0;
4640 /* change HP and line-out pins */
4641 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4643 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4645 /* mono (speaker) depending on the HP jack sense */
4646 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4647 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4651 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4652 struct snd_ctl_elem_value *ucontrol)
4654 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4655 struct alc_spec *spec = codec->spec;
4656 *ucontrol->value.integer.value = spec->master_sw;
4660 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4661 struct snd_ctl_elem_value *ucontrol)
4663 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4664 struct alc_spec *spec = codec->spec;
4665 int val = !!*ucontrol->value.integer.value;
4666 hda_nid_t hp, line, mono;
4668 if (val == spec->master_sw)
4670 spec->master_sw = val;
4671 hp = (kcontrol->private_value >> 16) & 0xff;
4672 line = (kcontrol->private_value >> 8) & 0xff;
4673 mono = kcontrol->private_value & 0xff;
4674 alc260_hp_master_update(codec, hp, line, mono);
4678 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4681 .name = "Master Playback Switch",
4682 .info = snd_ctl_boolean_mono_info,
4683 .get = alc260_hp_master_sw_get,
4684 .put = alc260_hp_master_sw_put,
4685 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4687 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4688 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4689 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4690 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4691 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4693 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4697 static struct hda_verb alc260_hp_unsol_verbs[] = {
4698 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4702 static void alc260_hp_automute(struct hda_codec *codec)
4704 struct alc_spec *spec = codec->spec;
4705 unsigned int present;
4707 present = snd_hda_codec_read(codec, 0x10, 0,
4708 AC_VERB_GET_PIN_SENSE, 0);
4709 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4710 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4713 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4715 if ((res >> 26) == ALC880_HP_EVENT)
4716 alc260_hp_automute(codec);
4719 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4721 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4722 .name = "Master Playback Switch",
4723 .info = snd_ctl_boolean_mono_info,
4724 .get = alc260_hp_master_sw_get,
4725 .put = alc260_hp_master_sw_put,
4726 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4728 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4729 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4730 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4731 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4732 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4733 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4734 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4735 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4739 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4740 .ops = &snd_hda_bind_vol,
4742 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4743 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4744 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4749 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4750 .ops = &snd_hda_bind_sw,
4752 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4753 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4758 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4759 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4760 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4761 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4762 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4766 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4767 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4771 static void alc260_hp_3013_automute(struct hda_codec *codec)
4773 struct alc_spec *spec = codec->spec;
4774 unsigned int present;
4776 present = snd_hda_codec_read(codec, 0x15, 0,
4777 AC_VERB_GET_PIN_SENSE, 0);
4778 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4779 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4782 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4785 if ((res >> 26) == ALC880_HP_EVENT)
4786 alc260_hp_3013_automute(codec);
4789 static void alc260_hp_3012_automute(struct hda_codec *codec)
4791 unsigned int present, bits;
4793 present = snd_hda_codec_read(codec, 0x10, 0,
4794 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4796 bits = present ? 0 : PIN_OUT;
4797 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4799 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4801 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4805 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4808 if ((res >> 26) == ALC880_HP_EVENT)
4809 alc260_hp_3012_automute(codec);
4812 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4813 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4815 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4816 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4817 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4818 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4819 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4820 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4821 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4822 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4823 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4824 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4825 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4829 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4830 * versions of the ALC260 don't act on requests to enable mic bias from NID
4831 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4832 * datasheet doesn't mention this restriction. At this stage it's not clear
4833 * whether this behaviour is intentional or is a hardware bug in chip
4834 * revisions available in early 2006. Therefore for now allow the
4835 * "Headphone Jack Mode" control to span all choices, but if it turns out
4836 * that the lack of mic bias for this NID is intentional we could change the
4837 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4839 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4840 * don't appear to make the mic bias available from the "line" jack, even
4841 * though the NID used for this jack (0x14) can supply it. The theory is
4842 * that perhaps Acer have included blocking capacitors between the ALC260
4843 * and the output jack. If this turns out to be the case for all such
4844 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4845 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4847 * The C20x Tablet series have a mono internal speaker which is controlled
4848 * via the chip's Mono sum widget and pin complex, so include the necessary
4849 * controls for such models. On models without a "mono speaker" the control
4850 * won't do anything.
4852 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4853 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4854 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4855 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4856 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4858 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4860 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4861 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4862 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4863 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4864 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4865 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4866 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4867 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4871 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4873 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4874 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4875 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4876 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4877 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4878 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4879 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4883 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4884 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4886 static struct snd_kcontrol_new alc260_will_mixer[] = {
4887 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4888 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4889 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4890 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4891 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4892 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4893 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4894 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4895 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4896 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4900 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4901 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4903 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4904 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4905 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4906 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4907 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4908 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4909 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4910 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4911 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4912 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4913 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4918 * initialization verbs
4920 static struct hda_verb alc260_init_verbs[] = {
4921 /* Line In pin widget for input */
4922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4923 /* CD pin widget for input */
4924 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4925 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4926 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4927 /* Mic2 (front panel) pin widget for input and vref at 80% */
4928 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4929 /* LINE-2 is used for line-out in rear */
4930 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4931 /* select line-out */
4932 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4934 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4936 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4938 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4939 /* mute capture amp left and right */
4940 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4941 /* set connection select to line in (default select for this ADC) */
4942 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4943 /* mute capture amp left and right */
4944 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4945 /* set connection select to line in (default select for this ADC) */
4946 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4947 /* set vol=0 Line-Out mixer amp left and right */
4948 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4949 /* unmute pin widget amp left and right (no gain on this amp) */
4950 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4951 /* set vol=0 HP mixer amp left and right */
4952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4953 /* unmute pin widget amp left and right (no gain on this amp) */
4954 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4955 /* set vol=0 Mono mixer amp left and right */
4956 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4957 /* unmute pin widget amp left and right (no gain on this amp) */
4958 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4959 /* unmute LINE-2 out pin */
4960 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4961 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4964 /* mute analog inputs */
4965 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4970 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4971 /* mute Front out path */
4972 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4974 /* mute Headphone out path */
4975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4977 /* mute Mono out path */
4978 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4979 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4983 #if 0 /* should be identical with alc260_init_verbs? */
4984 static struct hda_verb alc260_hp_init_verbs[] = {
4985 /* Headphone and output */
4986 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4988 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4989 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4990 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4991 /* Mic2 (front panel) pin widget for input and vref at 80% */
4992 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4993 /* Line In pin widget for input */
4994 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4995 /* Line-2 pin widget for output */
4996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4997 /* CD pin widget for input */
4998 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4999 /* unmute amp left and right */
5000 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5001 /* set connection select to line in (default select for this ADC) */
5002 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5003 /* unmute Line-Out mixer amp left and right (volume = 0) */
5004 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5005 /* mute pin widget amp left and right (no gain on this amp) */
5006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5007 /* unmute HP mixer amp left and right (volume = 0) */
5008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5009 /* mute pin widget amp left and right (no gain on this amp) */
5010 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5011 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5014 /* mute analog inputs */
5015 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5019 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5020 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5021 /* Unmute Front out path */
5022 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5024 /* Unmute Headphone out path */
5025 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5027 /* Unmute Mono out path */
5028 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5029 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5034 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5035 /* Line out and output */
5036 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5038 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5039 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5040 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5041 /* Mic2 (front panel) pin widget for input and vref at 80% */
5042 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5043 /* Line In pin widget for input */
5044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5045 /* Headphone pin widget for output */
5046 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5047 /* CD pin widget for input */
5048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5049 /* unmute amp left and right */
5050 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5051 /* set connection select to line in (default select for this ADC) */
5052 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5053 /* unmute Line-Out mixer amp left and right (volume = 0) */
5054 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5055 /* mute pin widget amp left and right (no gain on this amp) */
5056 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5057 /* unmute HP mixer amp left and right (volume = 0) */
5058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5059 /* mute pin widget amp left and right (no gain on this amp) */
5060 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5061 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5064 /* mute analog inputs */
5065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5070 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5071 /* Unmute Front out path */
5072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5074 /* Unmute Headphone out path */
5075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5077 /* Unmute Mono out path */
5078 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5079 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5083 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5084 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5085 * audio = 0x16, internal speaker = 0x10.
5087 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5088 /* Disable all GPIOs */
5089 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5090 /* Internal speaker is connected to headphone pin */
5091 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5092 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5093 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5094 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5095 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5096 /* Ensure all other unused pins are disabled and muted. */
5097 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5098 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5099 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5100 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5101 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5102 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5103 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5104 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5106 /* Disable digital (SPDIF) pins */
5107 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5108 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5110 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5111 * when acting as an output.
5113 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5115 /* Start with output sum widgets muted and their output gains at min */
5116 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5117 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5118 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5119 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5120 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5122 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5123 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5124 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5126 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5127 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5128 /* Unmute Line1 pin widget output buffer since it starts as an output.
5129 * If the pin mode is changed by the user the pin mode control will
5130 * take care of enabling the pin's input/output buffers as needed.
5131 * Therefore there's no need to enable the input buffer at this
5134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5135 /* Unmute input buffer of pin widget used for Line-in (no equiv
5138 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5140 /* Mute capture amp left and right */
5141 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5142 /* Set ADC connection select to match default mixer setting - line
5145 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5147 /* Do the same for the second ADC: mute capture input amp and
5148 * set ADC connection to line in (on mic1 pin)
5150 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5151 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5153 /* Mute all inputs to mixer widget (even unconnected ones) */
5154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5156 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5158 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5159 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5166 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5167 * similar laptops (adapted from Fujitsu init verbs).
5169 static struct hda_verb alc260_acer_init_verbs[] = {
5170 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5171 * the headphone jack. Turn this on and rely on the standard mute
5172 * methods whenever the user wants to turn these outputs off.
5174 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5175 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5176 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5177 /* Internal speaker/Headphone jack is connected to Line-out pin */
5178 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5179 /* Internal microphone/Mic jack is connected to Mic1 pin */
5180 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5181 /* Line In jack is connected to Line1 pin */
5182 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5183 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5184 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5185 /* Ensure all other unused pins are disabled and muted. */
5186 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5187 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5188 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5189 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5190 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5192 /* Disable digital (SPDIF) pins */
5193 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5194 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5196 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5197 * bus when acting as outputs.
5199 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5200 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5202 /* Start with output sum widgets muted and their output gains at min */
5203 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5204 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5205 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5206 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5207 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5208 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5209 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5210 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5211 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5213 /* Unmute Line-out pin widget amp left and right
5214 * (no equiv mixer ctrl)
5216 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5217 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5218 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5219 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5220 * inputs. If the pin mode is changed by the user the pin mode control
5221 * will take care of enabling the pin's input/output buffers as needed.
5222 * Therefore there's no need to enable the input buffer at this
5225 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5228 /* Mute capture amp left and right */
5229 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5230 /* Set ADC connection select to match default mixer setting - mic
5233 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5235 /* Do similar with the second ADC: mute capture input amp and
5236 * set ADC connection to mic to match ALSA's default state.
5238 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5239 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5241 /* Mute all inputs to mixer widget (even unconnected ones) */
5242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5243 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5244 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5245 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5246 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5247 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5254 /* Initialisation sequence for Maxdata Favorit 100XS
5255 * (adapted from Acer init verbs).
5257 static struct hda_verb alc260_favorit100_init_verbs[] = {
5258 /* GPIO 0 enables the output jack.
5259 * Turn this on and rely on the standard mute
5260 * methods whenever the user wants to turn these outputs off.
5262 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5263 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5264 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5265 /* Line/Mic input jack is connected to Mic1 pin */
5266 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5267 /* Ensure all other unused pins are disabled and muted. */
5268 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5269 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5270 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5271 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5272 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5273 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5275 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5276 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5277 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5278 /* Disable digital (SPDIF) pins */
5279 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5280 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5282 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5283 * bus when acting as outputs.
5285 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5286 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5288 /* Start with output sum widgets muted and their output gains at min */
5289 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5290 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5292 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5293 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5294 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5295 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5296 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5297 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5299 /* Unmute Line-out pin widget amp left and right
5300 * (no equiv mixer ctrl)
5302 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5303 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5304 * inputs. If the pin mode is changed by the user the pin mode control
5305 * will take care of enabling the pin's input/output buffers as needed.
5306 * Therefore there's no need to enable the input buffer at this
5309 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5311 /* Mute capture amp left and right */
5312 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5313 /* Set ADC connection select to match default mixer setting - mic
5316 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5318 /* Do similar with the second ADC: mute capture input amp and
5319 * set ADC connection to mic to match ALSA's default state.
5321 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5322 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5324 /* Mute all inputs to mixer widget (even unconnected ones) */
5325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5328 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5337 static struct hda_verb alc260_will_verbs[] = {
5338 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5339 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5340 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5341 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5342 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5343 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5347 static struct hda_verb alc260_replacer_672v_verbs[] = {
5348 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5349 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5350 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5352 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5353 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5354 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5356 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5360 /* toggle speaker-output according to the hp-jack state */
5361 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5363 unsigned int present;
5365 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5366 present = snd_hda_codec_read(codec, 0x0f, 0,
5367 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5369 snd_hda_codec_write_cache(codec, 0x01, 0,
5370 AC_VERB_SET_GPIO_DATA, 1);
5371 snd_hda_codec_write_cache(codec, 0x0f, 0,
5372 AC_VERB_SET_PIN_WIDGET_CONTROL,
5375 snd_hda_codec_write_cache(codec, 0x01, 0,
5376 AC_VERB_SET_GPIO_DATA, 0);
5377 snd_hda_codec_write_cache(codec, 0x0f, 0,
5378 AC_VERB_SET_PIN_WIDGET_CONTROL,
5383 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5386 if ((res >> 26) == ALC880_HP_EVENT)
5387 alc260_replacer_672v_automute(codec);
5390 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5391 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5392 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5393 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5394 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5395 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5396 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5397 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5398 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5399 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5400 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5404 /* Test configuration for debugging, modelled after the ALC880 test
5407 #ifdef CONFIG_SND_DEBUG
5408 static hda_nid_t alc260_test_dac_nids[1] = {
5411 static hda_nid_t alc260_test_adc_nids[2] = {
5414 /* For testing the ALC260, each input MUX needs its own definition since
5415 * the signal assignments are different. This assumes that the first ADC
5418 static struct hda_input_mux alc260_test_capture_sources[2] = {
5422 { "MIC1 pin", 0x0 },
5423 { "MIC2 pin", 0x1 },
5424 { "LINE1 pin", 0x2 },
5425 { "LINE2 pin", 0x3 },
5427 { "LINE-OUT pin", 0x5 },
5428 { "HP-OUT pin", 0x6 },
5434 { "MIC1 pin", 0x0 },
5435 { "MIC2 pin", 0x1 },
5436 { "LINE1 pin", 0x2 },
5437 { "LINE2 pin", 0x3 },
5440 { "LINE-OUT pin", 0x6 },
5441 { "HP-OUT pin", 0x7 },
5445 static struct snd_kcontrol_new alc260_test_mixer[] = {
5446 /* Output driver widgets */
5447 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5448 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5449 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5450 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5451 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5452 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5454 /* Modes for retasking pin widgets
5455 * Note: the ALC260 doesn't seem to act on requests to enable mic
5456 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5457 * mention this restriction. At this stage it's not clear whether
5458 * this behaviour is intentional or is a hardware bug in chip
5459 * revisions available at least up until early 2006. Therefore for
5460 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5461 * choices, but if it turns out that the lack of mic bias for these
5462 * NIDs is intentional we could change their modes from
5463 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5465 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5466 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5467 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5468 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5469 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5470 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5472 /* Loopback mixer controls */
5473 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5474 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5475 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5476 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5477 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5478 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5479 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5480 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5481 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5482 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5483 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5484 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5485 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5486 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5488 /* Controls for GPIO pins, assuming they are configured as outputs */
5489 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5490 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5491 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5492 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5494 /* Switches to allow the digital IO pins to be enabled. The datasheet
5495 * is ambigious as to which NID is which; testing on laptops which
5496 * make this output available should provide clarification.
5498 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5499 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5501 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5502 * this output to turn on an external amplifier.
5504 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5505 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5509 static struct hda_verb alc260_test_init_verbs[] = {
5510 /* Enable all GPIOs as outputs with an initial value of 0 */
5511 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5512 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5513 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5515 /* Enable retasking pins as output, initially without power amp */
5516 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5517 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5518 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5520 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5521 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5523 /* Disable digital (SPDIF) pins initially, but users can enable
5524 * them via a mixer switch. In the case of SPDIF-out, this initverb
5525 * payload also sets the generation to 0, output to be in "consumer"
5526 * PCM format, copyright asserted, no pre-emphasis and no validity
5529 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5530 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5532 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5533 * OUT1 sum bus when acting as an output.
5535 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5536 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5537 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5538 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5540 /* Start with output sum widgets muted and their output gains at min */
5541 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5543 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5544 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5545 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5547 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5548 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5549 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5551 /* Unmute retasking pin widget output buffers since the default
5552 * state appears to be output. As the pin mode is changed by the
5553 * user the pin mode control will take care of enabling the pin's
5554 * input/output buffers as needed.
5556 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5557 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5559 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5560 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5561 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5562 /* Also unmute the mono-out pin widget */
5563 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5565 /* Mute capture amp left and right */
5566 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5567 /* Set ADC connection select to match default mixer setting (mic1
5570 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5572 /* Do the same for the second ADC: mute capture input amp and
5573 * set ADC connection to mic1 pin
5575 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5576 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5578 /* Mute all inputs to mixer widget (even unconnected ones) */
5579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5580 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5581 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5582 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5583 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5584 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5592 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5593 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5595 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5596 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5599 * for BIOS auto-configuration
5602 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5603 const char *pfx, int *vol_bits)
5606 unsigned long vol_val, sw_val;
5610 if (nid >= 0x0f && nid < 0x11) {
5611 nid_vol = nid - 0x7;
5612 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5613 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5614 } else if (nid == 0x11) {
5615 nid_vol = nid - 0x7;
5616 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5617 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5618 } else if (nid >= 0x12 && nid <= 0x15) {
5620 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5621 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5625 if (!(*vol_bits & (1 << nid_vol))) {
5626 /* first control for the volume widget */
5627 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5628 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5631 *vol_bits |= (1 << nid_vol);
5633 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5634 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5640 /* add playback controls from the parsed DAC table */
5641 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5642 const struct auto_pin_cfg *cfg)
5648 spec->multiout.num_dacs = 1;
5649 spec->multiout.dac_nids = spec->private_dac_nids;
5650 spec->multiout.dac_nids[0] = 0x02;
5652 nid = cfg->line_out_pins[0];
5654 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5659 nid = cfg->speaker_pins[0];
5661 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5666 nid = cfg->hp_pins[0];
5668 err = alc260_add_playback_controls(spec, nid, "Headphone",
5676 /* create playback/capture controls for input pins */
5677 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5678 const struct auto_pin_cfg *cfg)
5680 struct hda_input_mux *imux = &spec->private_imux[0];
5683 for (i = 0; i < AUTO_PIN_LAST; i++) {
5684 if (cfg->input_pins[i] >= 0x12) {
5685 idx = cfg->input_pins[i] - 0x12;
5686 err = new_analog_input(spec, cfg->input_pins[i],
5687 auto_pin_cfg_labels[i], idx,
5691 imux->items[imux->num_items].label =
5692 auto_pin_cfg_labels[i];
5693 imux->items[imux->num_items].index = idx;
5696 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5697 idx = cfg->input_pins[i] - 0x09;
5698 err = new_analog_input(spec, cfg->input_pins[i],
5699 auto_pin_cfg_labels[i], idx,
5703 imux->items[imux->num_items].label =
5704 auto_pin_cfg_labels[i];
5705 imux->items[imux->num_items].index = idx;
5712 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5713 hda_nid_t nid, int pin_type,
5716 alc_set_pin_output(codec, nid, pin_type);
5717 /* need the manual connection? */
5719 int idx = nid - 0x12;
5720 snd_hda_codec_write(codec, idx + 0x0b, 0,
5721 AC_VERB_SET_CONNECT_SEL, sel_idx);
5725 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5727 struct alc_spec *spec = codec->spec;
5730 nid = spec->autocfg.line_out_pins[0];
5732 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5733 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5736 nid = spec->autocfg.speaker_pins[0];
5738 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5740 nid = spec->autocfg.hp_pins[0];
5742 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5745 #define ALC260_PIN_CD_NID 0x16
5746 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5748 struct alc_spec *spec = codec->spec;
5751 for (i = 0; i < AUTO_PIN_LAST; i++) {
5752 hda_nid_t nid = spec->autocfg.input_pins[i];
5754 alc_set_input_pin(codec, nid, i);
5755 if (nid != ALC260_PIN_CD_NID &&
5756 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5757 snd_hda_codec_write(codec, nid, 0,
5758 AC_VERB_SET_AMP_GAIN_MUTE,
5765 * generic initialization of ADC, input mixers and output mixers
5767 static struct hda_verb alc260_volume_init_verbs[] = {
5769 * Unmute ADC0-1 and set the default input to mic-in
5771 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5772 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5773 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5774 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5776 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5778 * Note: PASD motherboards uses the Line In 2 as the input for
5779 * front panel mic (mic 2)
5781 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5782 /* mute analog inputs */
5783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5784 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5785 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5787 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5790 * Set up output mixers (0x08 - 0x0a)
5792 /* set vol=0 to output mixers */
5793 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5795 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5796 /* set up input amps for analog loopback */
5797 /* Amp Indices: DAC = 0, mixer = 1 */
5798 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5799 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5800 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5802 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5803 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5808 static int alc260_parse_auto_config(struct hda_codec *codec)
5810 struct alc_spec *spec = codec->spec;
5812 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5814 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5818 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5821 if (!spec->kctls.list)
5822 return 0; /* can't find valid BIOS pin config */
5823 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5827 spec->multiout.max_channels = 2;
5829 if (spec->autocfg.dig_outs)
5830 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5831 if (spec->kctls.list)
5832 add_mixer(spec, spec->kctls.list);
5834 add_verb(spec, alc260_volume_init_verbs);
5836 spec->num_mux_defs = 1;
5837 spec->input_mux = &spec->private_imux[0];
5839 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5844 /* additional initialization for auto-configuration model */
5845 static void alc260_auto_init(struct hda_codec *codec)
5847 struct alc_spec *spec = codec->spec;
5848 alc260_auto_init_multi_out(codec);
5849 alc260_auto_init_analog_input(codec);
5850 if (spec->unsol_event)
5851 alc_inithook(codec);
5854 #ifdef CONFIG_SND_HDA_POWER_SAVE
5855 static struct hda_amp_list alc260_loopbacks[] = {
5856 { 0x07, HDA_INPUT, 0 },
5857 { 0x07, HDA_INPUT, 1 },
5858 { 0x07, HDA_INPUT, 2 },
5859 { 0x07, HDA_INPUT, 3 },
5860 { 0x07, HDA_INPUT, 4 },
5866 * ALC260 configurations
5868 static const char *alc260_models[ALC260_MODEL_LAST] = {
5869 [ALC260_BASIC] = "basic",
5871 [ALC260_HP_3013] = "hp-3013",
5872 [ALC260_HP_DC7600] = "hp-dc7600",
5873 [ALC260_FUJITSU_S702X] = "fujitsu",
5874 [ALC260_ACER] = "acer",
5875 [ALC260_WILL] = "will",
5876 [ALC260_REPLACER_672V] = "replacer",
5877 [ALC260_FAVORIT100] = "favorit100",
5878 #ifdef CONFIG_SND_DEBUG
5879 [ALC260_TEST] = "test",
5881 [ALC260_AUTO] = "auto",
5884 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5885 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5886 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5887 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5888 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5889 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5890 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5891 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5892 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5893 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5894 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5895 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5896 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5897 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5898 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5899 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5900 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5901 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5902 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5903 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5907 static struct alc_config_preset alc260_presets[] = {
5909 .mixers = { alc260_base_output_mixer,
5910 alc260_input_mixer },
5911 .init_verbs = { alc260_init_verbs },
5912 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5913 .dac_nids = alc260_dac_nids,
5914 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5915 .adc_nids = alc260_adc_nids,
5916 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5917 .channel_mode = alc260_modes,
5918 .input_mux = &alc260_capture_source,
5921 .mixers = { alc260_hp_output_mixer,
5922 alc260_input_mixer },
5923 .init_verbs = { alc260_init_verbs,
5924 alc260_hp_unsol_verbs },
5925 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5926 .dac_nids = alc260_dac_nids,
5927 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5928 .adc_nids = alc260_adc_nids_alt,
5929 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5930 .channel_mode = alc260_modes,
5931 .input_mux = &alc260_capture_source,
5932 .unsol_event = alc260_hp_unsol_event,
5933 .init_hook = alc260_hp_automute,
5935 [ALC260_HP_DC7600] = {
5936 .mixers = { alc260_hp_dc7600_mixer,
5937 alc260_input_mixer },
5938 .init_verbs = { alc260_init_verbs,
5939 alc260_hp_dc7600_verbs },
5940 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5941 .dac_nids = alc260_dac_nids,
5942 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5943 .adc_nids = alc260_adc_nids_alt,
5944 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5945 .channel_mode = alc260_modes,
5946 .input_mux = &alc260_capture_source,
5947 .unsol_event = alc260_hp_3012_unsol_event,
5948 .init_hook = alc260_hp_3012_automute,
5950 [ALC260_HP_3013] = {
5951 .mixers = { alc260_hp_3013_mixer,
5952 alc260_input_mixer },
5953 .init_verbs = { alc260_hp_3013_init_verbs,
5954 alc260_hp_3013_unsol_verbs },
5955 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5956 .dac_nids = alc260_dac_nids,
5957 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5958 .adc_nids = alc260_adc_nids_alt,
5959 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5960 .channel_mode = alc260_modes,
5961 .input_mux = &alc260_capture_source,
5962 .unsol_event = alc260_hp_3013_unsol_event,
5963 .init_hook = alc260_hp_3013_automute,
5965 [ALC260_FUJITSU_S702X] = {
5966 .mixers = { alc260_fujitsu_mixer },
5967 .init_verbs = { alc260_fujitsu_init_verbs },
5968 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5969 .dac_nids = alc260_dac_nids,
5970 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5971 .adc_nids = alc260_dual_adc_nids,
5972 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5973 .channel_mode = alc260_modes,
5974 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5975 .input_mux = alc260_fujitsu_capture_sources,
5978 .mixers = { alc260_acer_mixer },
5979 .init_verbs = { alc260_acer_init_verbs },
5980 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5981 .dac_nids = alc260_dac_nids,
5982 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5983 .adc_nids = alc260_dual_adc_nids,
5984 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5985 .channel_mode = alc260_modes,
5986 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5987 .input_mux = alc260_acer_capture_sources,
5989 [ALC260_FAVORIT100] = {
5990 .mixers = { alc260_favorit100_mixer },
5991 .init_verbs = { alc260_favorit100_init_verbs },
5992 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5993 .dac_nids = alc260_dac_nids,
5994 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5995 .adc_nids = alc260_dual_adc_nids,
5996 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5997 .channel_mode = alc260_modes,
5998 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5999 .input_mux = alc260_favorit100_capture_sources,
6002 .mixers = { alc260_will_mixer },
6003 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6004 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6005 .dac_nids = alc260_dac_nids,
6006 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6007 .adc_nids = alc260_adc_nids,
6008 .dig_out_nid = ALC260_DIGOUT_NID,
6009 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6010 .channel_mode = alc260_modes,
6011 .input_mux = &alc260_capture_source,
6013 [ALC260_REPLACER_672V] = {
6014 .mixers = { alc260_replacer_672v_mixer },
6015 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6016 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6017 .dac_nids = alc260_dac_nids,
6018 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6019 .adc_nids = alc260_adc_nids,
6020 .dig_out_nid = ALC260_DIGOUT_NID,
6021 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6022 .channel_mode = alc260_modes,
6023 .input_mux = &alc260_capture_source,
6024 .unsol_event = alc260_replacer_672v_unsol_event,
6025 .init_hook = alc260_replacer_672v_automute,
6027 #ifdef CONFIG_SND_DEBUG
6029 .mixers = { alc260_test_mixer },
6030 .init_verbs = { alc260_test_init_verbs },
6031 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6032 .dac_nids = alc260_test_dac_nids,
6033 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6034 .adc_nids = alc260_test_adc_nids,
6035 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6036 .channel_mode = alc260_modes,
6037 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6038 .input_mux = alc260_test_capture_sources,
6043 static int patch_alc260(struct hda_codec *codec)
6045 struct alc_spec *spec;
6046 int err, board_config;
6048 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6054 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6057 if (board_config < 0) {
6058 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6059 "trying auto-probe from BIOS...\n",
6061 board_config = ALC260_AUTO;
6064 if (board_config == ALC260_AUTO) {
6065 /* automatic parse from the BIOS config */
6066 err = alc260_parse_auto_config(codec);
6072 "hda_codec: Cannot set up configuration "
6073 "from BIOS. Using base mode...\n");
6074 board_config = ALC260_BASIC;
6078 err = snd_hda_attach_beep_device(codec, 0x1);
6084 if (board_config != ALC260_AUTO)
6085 setup_preset(spec, &alc260_presets[board_config]);
6087 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6088 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6090 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6091 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6093 if (!spec->adc_nids && spec->input_mux) {
6094 /* check whether NID 0x04 is valid */
6095 unsigned int wcap = get_wcaps(codec, 0x04);
6096 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6098 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6099 spec->adc_nids = alc260_adc_nids_alt;
6100 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6102 spec->adc_nids = alc260_adc_nids;
6103 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6106 set_capture_mixer(spec);
6107 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6109 spec->vmaster_nid = 0x08;
6111 codec->patch_ops = alc_patch_ops;
6112 if (board_config == ALC260_AUTO)
6113 spec->init_hook = alc260_auto_init;
6114 #ifdef CONFIG_SND_HDA_POWER_SAVE
6115 if (!spec->loopback.amplist)
6116 spec->loopback.amplist = alc260_loopbacks;
6118 codec->proc_widget_hook = print_realtek_coef;
6127 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6128 * configuration. Each pin widget can choose any input DACs and a mixer.
6129 * Each ADC is connected from a mixer of all inputs. This makes possible
6130 * 6-channel independent captures.
6132 * In addition, an independent DAC for the multi-playback (not used in this
6135 #define ALC882_DIGOUT_NID 0x06
6136 #define ALC882_DIGIN_NID 0x0a
6138 static struct hda_channel_mode alc882_ch_modes[1] = {
6142 static hda_nid_t alc882_dac_nids[4] = {
6143 /* front, rear, clfe, rear_surr */
6144 0x02, 0x03, 0x04, 0x05
6147 /* identical with ALC880 */
6148 #define alc882_adc_nids alc880_adc_nids
6149 #define alc882_adc_nids_alt alc880_adc_nids_alt
6151 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6152 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6155 /* FIXME: should be a matrix-type input source selection */
6157 static struct hda_input_mux alc882_capture_source = {
6161 { "Front Mic", 0x1 },
6167 static struct hda_input_mux mb5_capture_source = {
6179 static struct hda_verb alc882_3ST_ch2_init[] = {
6180 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6181 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6182 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6183 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6190 static struct hda_verb alc882_3ST_ch6_init[] = {
6191 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6192 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6193 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6194 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6195 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6196 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6200 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6201 { 2, alc882_3ST_ch2_init },
6202 { 6, alc882_3ST_ch6_init },
6208 static struct hda_verb alc882_sixstack_ch6_init[] = {
6209 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6210 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6211 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6212 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6219 static struct hda_verb alc882_sixstack_ch8_init[] = {
6220 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6221 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6222 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6223 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6227 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6228 { 6, alc882_sixstack_ch6_init },
6229 { 8, alc882_sixstack_ch8_init },
6233 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6239 static struct hda_verb alc885_mbp_ch2_init[] = {
6240 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6241 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6242 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6249 static struct hda_verb alc885_mbp_ch6_init[] = {
6250 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6251 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6252 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6253 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6254 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6258 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6259 { 2, alc885_mbp_ch2_init },
6260 { 6, alc885_mbp_ch6_init },
6264 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6265 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6267 static struct snd_kcontrol_new alc882_base_mixer[] = {
6268 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6269 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6270 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6271 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6272 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6273 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6274 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6275 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6276 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6277 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6278 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6279 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6280 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6281 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6282 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6283 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6284 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6286 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6287 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6288 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6292 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6293 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6294 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6295 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6296 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6297 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6298 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6299 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6300 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6301 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6302 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6306 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6308 HDA_BIND_MUTE ("Front Playback Switch", 0x0d, 0x02, HDA_INPUT),
6309 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6310 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
6311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6312 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6314 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6315 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6316 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6319 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6322 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6323 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6324 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6325 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6326 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6327 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6332 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6333 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6334 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6335 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6336 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6337 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6338 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6339 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6341 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6342 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6343 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6344 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6345 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6349 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6350 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6352 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6353 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6354 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6355 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6356 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6357 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6358 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6359 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6360 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6361 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6362 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6363 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6364 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6365 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6369 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6371 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6372 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6373 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6374 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6375 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6376 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6378 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6379 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6383 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6386 .name = "Channel Mode",
6387 .info = alc_ch_mode_info,
6388 .get = alc_ch_mode_get,
6389 .put = alc_ch_mode_put,
6394 static struct hda_verb alc882_init_verbs[] = {
6395 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6396 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6397 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6398 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6400 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6401 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6402 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6404 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6405 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6408 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6410 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6412 /* Front Pin: output 0 (0x0c) */
6413 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6414 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6415 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6416 /* Rear Pin: output 1 (0x0d) */
6417 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6418 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6419 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6420 /* CLFE Pin: output 2 (0x0e) */
6421 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6422 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6423 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6424 /* Side Pin: output 3 (0x0f) */
6425 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6426 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6427 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6428 /* Mic (rear) pin: input vref at 80% */
6429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6431 /* Front Mic pin: input vref at 80% */
6432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6434 /* Line In pin: input */
6435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6437 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6438 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6439 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6440 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6441 /* CD pin widget for input */
6442 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6444 /* FIXME: use matrix-type input source selection */
6445 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6446 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6461 /* ADC1: mute amp left and right */
6462 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6463 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6464 /* ADC2: mute amp left and right */
6465 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6466 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6467 /* ADC3: mute amp left and right */
6468 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6469 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6474 static struct hda_verb alc882_eapd_verbs[] = {
6475 /* change to EAPD mode */
6476 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6477 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6482 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6483 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6484 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6486 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6487 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6488 /* FIXME: this looks suspicious...
6489 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6490 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6495 static struct hda_verb alc882_macpro_init_verbs[] = {
6496 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6497 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6498 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6500 /* Front Pin: output 0 (0x0c) */
6501 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6502 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6503 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6504 /* Front Mic pin: input vref at 80% */
6505 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6506 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6507 /* Speaker: output */
6508 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6510 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6511 /* Headphone output (output 0 - 0x0c) */
6512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6514 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6516 /* FIXME: use matrix-type input source selection */
6517 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6518 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6524 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6525 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6533 /* ADC1: mute amp left and right */
6534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6535 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6536 /* ADC2: mute amp left and right */
6537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6538 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6539 /* ADC3: mute amp left and right */
6540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6541 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6547 static struct hda_verb alc885_mb5_init_verbs[] = {
6549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6551 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6556 /* Front Pin: output 0 (0x0d) */
6557 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6558 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6559 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},
6560 /* HP Pin: output 0 (0x0c) */
6561 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6562 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6563 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6564 /* Front Mic pin: input vref at 80% */
6565 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6568 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6571 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6572 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6573 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6578 /* Macbook Pro rev3 */
6579 static struct hda_verb alc885_mbp3_init_verbs[] = {
6580 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6585 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6586 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6587 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6588 /* Front Pin: output 0 (0x0c) */
6589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6591 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6592 /* HP Pin: output 0 (0x0d) */
6593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6594 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6595 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6596 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6597 /* Mic (rear) pin: input vref at 80% */
6598 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6600 /* Front Mic pin: input vref at 80% */
6601 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6602 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6603 /* Line In pin: use output 1 when in LineOut mode */
6604 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6605 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6606 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6608 /* FIXME: use matrix-type input source selection */
6609 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6610 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6612 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6613 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6614 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6617 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6618 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6619 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6622 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6624 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6625 /* ADC1: mute amp left and right */
6626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6627 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6628 /* ADC2: mute amp left and right */
6629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6630 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6631 /* ADC3: mute amp left and right */
6632 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6633 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6638 /* iMac 24 mixer. */
6639 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6640 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6641 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6645 /* iMac 24 init verbs. */
6646 static struct hda_verb alc885_imac24_init_verbs[] = {
6647 /* Internal speakers: output 0 (0x0c) */
6648 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6649 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6650 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6651 /* Internal speakers: output 0 (0x0c) */
6652 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6653 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6654 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6655 /* Headphone: output 0 (0x0c) */
6656 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6657 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6658 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6659 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6660 /* Front Mic: input vref at 80% */
6661 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6662 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6666 /* Toggle speaker-output according to the hp-jack state */
6667 static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
6669 struct alc_spec *spec = codec->spec;
6671 spec->autocfg.hp_pins[0] = 0x14;
6672 spec->autocfg.speaker_pins[0] = 0x18;
6673 spec->autocfg.speaker_pins[1] = 0x1a;
6674 alc_automute_amp(codec);
6677 static void alc885_mbp3_init_hook(struct hda_codec *codec)
6679 struct alc_spec *spec = codec->spec;
6681 spec->autocfg.hp_pins[0] = 0x15;
6682 spec->autocfg.speaker_pins[0] = 0x14;
6683 alc_automute_amp(codec);
6687 static struct hda_verb alc882_targa_verbs[] = {
6688 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6689 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6694 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6695 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6696 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6698 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6699 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6700 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6701 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6705 /* toggle speaker-output according to the hp-jack state */
6706 static void alc882_targa_automute(struct hda_codec *codec)
6708 struct alc_spec *spec = codec->spec;
6709 alc_automute_amp(codec);
6710 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6711 spec->jack_present ? 1 : 3);
6714 static void alc882_targa_init_hook(struct hda_codec *codec)
6716 struct alc_spec *spec = codec->spec;
6718 spec->autocfg.hp_pins[0] = 0x14;
6719 spec->autocfg.speaker_pins[0] = 0x1b;
6720 alc882_targa_automute(codec);
6723 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6725 if ((res >> 26) == ALC880_HP_EVENT)
6726 alc882_targa_automute(codec);
6729 static struct hda_verb alc882_asus_a7j_verbs[] = {
6730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6734 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6735 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6737 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6738 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6739 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6741 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6742 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6743 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6747 static struct hda_verb alc882_asus_a7m_verbs[] = {
6748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6749 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6751 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6753 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6755 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6756 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6757 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6759 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6760 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6761 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6765 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6767 unsigned int gpiostate, gpiomask, gpiodir;
6769 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6770 AC_VERB_GET_GPIO_DATA, 0);
6773 gpiostate |= (1 << pin);
6775 gpiostate &= ~(1 << pin);
6777 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6778 AC_VERB_GET_GPIO_MASK, 0);
6779 gpiomask |= (1 << pin);
6781 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6782 AC_VERB_GET_GPIO_DIRECTION, 0);
6783 gpiodir |= (1 << pin);
6786 snd_hda_codec_write(codec, codec->afg, 0,
6787 AC_VERB_SET_GPIO_MASK, gpiomask);
6788 snd_hda_codec_write(codec, codec->afg, 0,
6789 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6793 snd_hda_codec_write(codec, codec->afg, 0,
6794 AC_VERB_SET_GPIO_DATA, gpiostate);
6797 /* set up GPIO at initialization */
6798 static void alc885_macpro_init_hook(struct hda_codec *codec)
6800 alc882_gpio_mute(codec, 0, 0);
6801 alc882_gpio_mute(codec, 1, 0);
6804 /* set up GPIO and update auto-muting at initialization */
6805 static void alc885_imac24_init_hook(struct hda_codec *codec)
6807 alc885_macpro_init_hook(codec);
6808 alc885_imac24_automute_init_hook(codec);
6812 * generic initialization of ADC, input mixers and output mixers
6814 static struct hda_verb alc882_auto_init_verbs[] = {
6816 * Unmute ADC0-2 and set the default input to mic-in
6818 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6820 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6821 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6822 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6823 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6825 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6827 * Note: PASD motherboards uses the Line In 2 as the input for
6828 * front panel mic (mic 2)
6830 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6834 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6838 * Set up output mixers (0x0c - 0x0f)
6840 /* set vol=0 to output mixers */
6841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6843 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6844 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6845 /* set up input amps for analog loopback */
6846 /* Amp Indices: DAC = 0, mixer = 1 */
6847 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6848 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6849 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6850 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6851 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6852 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6853 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6854 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6855 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6856 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6858 /* FIXME: use matrix-type input source selection */
6859 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6860 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6861 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6862 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6863 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6864 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6866 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6867 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6868 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6869 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6871 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6879 #ifdef CONFIG_SND_HDA_POWER_SAVE
6880 #define alc882_loopbacks alc880_loopbacks
6883 /* pcm configuration: identiacal with ALC880 */
6884 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6885 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6886 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6887 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6890 * configuration and preset
6892 static const char *alc882_models[ALC882_MODEL_LAST] = {
6893 [ALC882_3ST_DIG] = "3stack-dig",
6894 [ALC882_6ST_DIG] = "6stack-dig",
6895 [ALC882_ARIMA] = "arima",
6896 [ALC882_W2JC] = "w2jc",
6897 [ALC882_TARGA] = "targa",
6898 [ALC882_ASUS_A7J] = "asus-a7j",
6899 [ALC882_ASUS_A7M] = "asus-a7m",
6900 [ALC885_MACPRO] = "macpro",
6901 [ALC885_MB5] = "mb5",
6902 [ALC885_MBP3] = "mbp3",
6903 [ALC885_IMAC24] = "imac24",
6904 [ALC882_AUTO] = "auto",
6907 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6908 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6909 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6910 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6911 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6912 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6913 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6914 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6915 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6916 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6917 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6918 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6919 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6923 static struct alc_config_preset alc882_presets[] = {
6924 [ALC882_3ST_DIG] = {
6925 .mixers = { alc882_base_mixer },
6926 .init_verbs = { alc882_init_verbs },
6927 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6928 .dac_nids = alc882_dac_nids,
6929 .dig_out_nid = ALC882_DIGOUT_NID,
6930 .dig_in_nid = ALC882_DIGIN_NID,
6931 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6932 .channel_mode = alc882_ch_modes,
6934 .input_mux = &alc882_capture_source,
6936 [ALC882_6ST_DIG] = {
6937 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6938 .init_verbs = { alc882_init_verbs },
6939 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6940 .dac_nids = alc882_dac_nids,
6941 .dig_out_nid = ALC882_DIGOUT_NID,
6942 .dig_in_nid = ALC882_DIGIN_NID,
6943 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6944 .channel_mode = alc882_sixstack_modes,
6945 .input_mux = &alc882_capture_source,
6948 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6949 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6950 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6951 .dac_nids = alc882_dac_nids,
6952 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6953 .channel_mode = alc882_sixstack_modes,
6954 .input_mux = &alc882_capture_source,
6957 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6958 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6959 alc880_gpio1_init_verbs },
6960 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6961 .dac_nids = alc882_dac_nids,
6962 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6963 .channel_mode = alc880_threestack_modes,
6965 .input_mux = &alc882_capture_source,
6966 .dig_out_nid = ALC882_DIGOUT_NID,
6969 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6970 .init_verbs = { alc885_mbp3_init_verbs,
6971 alc880_gpio1_init_verbs },
6972 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6973 .dac_nids = alc882_dac_nids,
6974 .channel_mode = alc885_mbp_6ch_modes,
6975 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6976 .input_mux = &alc882_capture_source,
6977 .dig_out_nid = ALC882_DIGOUT_NID,
6978 .dig_in_nid = ALC882_DIGIN_NID,
6979 .unsol_event = alc_automute_amp_unsol_event,
6980 .init_hook = alc885_mbp3_init_hook,
6983 .mixers = { alc885_mb5_mixer },
6984 .init_verbs = { alc885_mb5_init_verbs,
6985 alc880_gpio1_init_verbs },
6986 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6987 .dac_nids = alc882_dac_nids,
6988 .channel_mode = alc885_mbp_6ch_modes,
6989 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6990 .input_mux = &mb5_capture_source,
6991 .dig_out_nid = ALC882_DIGOUT_NID,
6992 .dig_in_nid = ALC882_DIGIN_NID,
6995 .mixers = { alc882_macpro_mixer },
6996 .init_verbs = { alc882_macpro_init_verbs },
6997 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6998 .dac_nids = alc882_dac_nids,
6999 .dig_out_nid = ALC882_DIGOUT_NID,
7000 .dig_in_nid = ALC882_DIGIN_NID,
7001 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7002 .channel_mode = alc882_ch_modes,
7003 .input_mux = &alc882_capture_source,
7004 .init_hook = alc885_macpro_init_hook,
7007 .mixers = { alc885_imac24_mixer },
7008 .init_verbs = { alc885_imac24_init_verbs },
7009 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7010 .dac_nids = alc882_dac_nids,
7011 .dig_out_nid = ALC882_DIGOUT_NID,
7012 .dig_in_nid = ALC882_DIGIN_NID,
7013 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7014 .channel_mode = alc882_ch_modes,
7015 .input_mux = &alc882_capture_source,
7016 .unsol_event = alc_automute_amp_unsol_event,
7017 .init_hook = alc885_imac24_init_hook,
7020 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7021 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7022 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7023 .dac_nids = alc882_dac_nids,
7024 .dig_out_nid = ALC882_DIGOUT_NID,
7025 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7026 .adc_nids = alc882_adc_nids,
7027 .capsrc_nids = alc882_capsrc_nids,
7028 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7029 .channel_mode = alc882_3ST_6ch_modes,
7031 .input_mux = &alc882_capture_source,
7032 .unsol_event = alc882_targa_unsol_event,
7033 .init_hook = alc882_targa_init_hook,
7035 [ALC882_ASUS_A7J] = {
7036 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7037 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7038 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7039 .dac_nids = alc882_dac_nids,
7040 .dig_out_nid = ALC882_DIGOUT_NID,
7041 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7042 .adc_nids = alc882_adc_nids,
7043 .capsrc_nids = alc882_capsrc_nids,
7044 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7045 .channel_mode = alc882_3ST_6ch_modes,
7047 .input_mux = &alc882_capture_source,
7049 [ALC882_ASUS_A7M] = {
7050 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7051 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7052 alc880_gpio1_init_verbs,
7053 alc882_asus_a7m_verbs },
7054 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7055 .dac_nids = alc882_dac_nids,
7056 .dig_out_nid = ALC882_DIGOUT_NID,
7057 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7058 .channel_mode = alc880_threestack_modes,
7060 .input_mux = &alc882_capture_source,
7069 PINFIX_ABIT_AW9D_MAX
7072 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7073 { 0x15, 0x01080104 }, /* side */
7074 { 0x16, 0x01011012 }, /* rear */
7075 { 0x17, 0x01016011 }, /* clfe */
7079 static const struct alc_pincfg *alc882_pin_fixes[] = {
7080 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7083 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7084 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7089 * BIOS auto configuration
7091 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7092 hda_nid_t nid, int pin_type,
7096 struct alc_spec *spec = codec->spec;
7099 alc_set_pin_output(codec, nid, pin_type);
7100 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7103 idx = spec->multiout.dac_nids[dac_idx] - 2;
7104 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7108 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7110 struct alc_spec *spec = codec->spec;
7113 for (i = 0; i <= HDA_SIDE; i++) {
7114 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7115 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7117 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7122 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7124 struct alc_spec *spec = codec->spec;
7127 pin = spec->autocfg.hp_pins[0];
7128 if (pin) /* connect to front */
7130 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7131 pin = spec->autocfg.speaker_pins[0];
7133 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7136 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7137 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7139 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7141 struct alc_spec *spec = codec->spec;
7144 for (i = 0; i < AUTO_PIN_LAST; i++) {
7145 hda_nid_t nid = spec->autocfg.input_pins[i];
7148 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7149 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7150 snd_hda_codec_write(codec, nid, 0,
7151 AC_VERB_SET_AMP_GAIN_MUTE,
7156 static void alc882_auto_init_input_src(struct hda_codec *codec)
7158 struct alc_spec *spec = codec->spec;
7161 for (c = 0; c < spec->num_adc_nids; c++) {
7162 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7163 hda_nid_t nid = spec->capsrc_nids[c];
7164 unsigned int mux_idx;
7165 const struct hda_input_mux *imux;
7166 int conns, mute, idx, item;
7168 conns = snd_hda_get_connections(codec, nid, conn_list,
7169 ARRAY_SIZE(conn_list));
7172 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7173 imux = &spec->input_mux[mux_idx];
7174 for (idx = 0; idx < conns; idx++) {
7175 /* if the current connection is the selected one,
7176 * unmute it as default - otherwise mute it
7178 mute = AMP_IN_MUTE(idx);
7179 for (item = 0; item < imux->num_items; item++) {
7180 if (imux->items[item].index == idx) {
7181 if (spec->cur_mux[c] == item)
7182 mute = AMP_IN_UNMUTE(idx);
7186 /* check if we have a selector or mixer
7187 * we could check for the widget type instead, but
7188 * just check for Amp-In presence (in case of mixer
7189 * without amp-in there is something wrong, this
7190 * function shouldn't be used or capsrc nid is wrong)
7192 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7193 snd_hda_codec_write(codec, nid, 0,
7194 AC_VERB_SET_AMP_GAIN_MUTE,
7196 else if (mute != AMP_IN_MUTE(idx))
7197 snd_hda_codec_write(codec, nid, 0,
7198 AC_VERB_SET_CONNECT_SEL,
7204 /* add mic boosts if needed */
7205 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7207 struct alc_spec *spec = codec->spec;
7211 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7212 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7213 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7215 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7219 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7220 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7221 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7223 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7230 /* almost identical with ALC880 parser... */
7231 static int alc882_parse_auto_config(struct hda_codec *codec)
7233 struct alc_spec *spec = codec->spec;
7234 int err = alc880_parse_auto_config(codec);
7239 return 0; /* no config found */
7241 err = alc_auto_add_mic_boost(codec);
7245 /* hack - override the init verbs */
7246 spec->init_verbs[0] = alc882_auto_init_verbs;
7248 return 1; /* config found */
7251 /* additional initialization for auto-configuration model */
7252 static void alc882_auto_init(struct hda_codec *codec)
7254 struct alc_spec *spec = codec->spec;
7255 alc882_auto_init_multi_out(codec);
7256 alc882_auto_init_hp_out(codec);
7257 alc882_auto_init_analog_input(codec);
7258 alc882_auto_init_input_src(codec);
7259 if (spec->unsol_event)
7260 alc_inithook(codec);
7263 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7265 static int patch_alc882(struct hda_codec *codec)
7267 struct alc_spec *spec;
7268 int err, board_config;
7270 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7276 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7280 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7281 /* Pick up systems that don't supply PCI SSID */
7282 switch (codec->subsystem_id) {
7283 case 0x106b0c00: /* Mac Pro */
7284 board_config = ALC885_MACPRO;
7286 case 0x106b1000: /* iMac 24 */
7287 case 0x106b2800: /* AppleTV */
7288 case 0x106b3e00: /* iMac 24 Aluminium */
7289 board_config = ALC885_IMAC24;
7291 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7292 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7293 case 0x106b00a4: /* MacbookPro4,1 */
7294 case 0x106b2c00: /* Macbook Pro rev3 */
7295 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7296 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7297 board_config = ALC885_MBP3;
7299 case 0x106b3f00: /* Macbook 5,1 */
7300 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7301 * seems not working, so apparently
7302 * no perfect solution yet
7304 board_config = ALC885_MB5;
7307 /* ALC889A is handled better as ALC888-compatible */
7308 if (codec->revision_id == 0x100101 ||
7309 codec->revision_id == 0x100103) {
7311 return patch_alc883(codec);
7313 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7314 "trying auto-probe from BIOS...\n",
7316 board_config = ALC882_AUTO;
7320 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7322 if (board_config == ALC882_AUTO) {
7323 /* automatic parse from the BIOS config */
7324 err = alc882_parse_auto_config(codec);
7330 "hda_codec: Cannot set up configuration "
7331 "from BIOS. Using base mode...\n");
7332 board_config = ALC882_3ST_DIG;
7336 err = snd_hda_attach_beep_device(codec, 0x1);
7342 if (board_config != ALC882_AUTO)
7343 setup_preset(spec, &alc882_presets[board_config]);
7345 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7346 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7347 /* FIXME: setup DAC5 */
7348 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7349 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7351 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7352 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7354 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7355 if (!spec->adc_nids && spec->input_mux) {
7356 /* check whether NID 0x07 is valid */
7357 unsigned int wcap = get_wcaps(codec, 0x07);
7359 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7360 if (wcap != AC_WID_AUD_IN) {
7361 spec->adc_nids = alc882_adc_nids_alt;
7362 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7363 spec->capsrc_nids = alc882_capsrc_nids_alt;
7365 spec->adc_nids = alc882_adc_nids;
7366 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7367 spec->capsrc_nids = alc882_capsrc_nids;
7370 set_capture_mixer(spec);
7371 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7373 spec->vmaster_nid = 0x0c;
7375 codec->patch_ops = alc_patch_ops;
7376 if (board_config == ALC882_AUTO)
7377 spec->init_hook = alc882_auto_init;
7378 #ifdef CONFIG_SND_HDA_POWER_SAVE
7379 if (!spec->loopback.amplist)
7380 spec->loopback.amplist = alc882_loopbacks;
7382 codec->proc_widget_hook = print_realtek_coef;
7390 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7391 * configuration. Each pin widget can choose any input DACs and a mixer.
7392 * Each ADC is connected from a mixer of all inputs. This makes possible
7393 * 6-channel independent captures.
7395 * In addition, an independent DAC for the multi-playback (not used in this
7398 #define ALC883_DIGOUT_NID 0x06
7399 #define ALC883_DIGIN_NID 0x0a
7401 #define ALC1200_DIGOUT_NID 0x10
7403 static hda_nid_t alc883_dac_nids[4] = {
7404 /* front, rear, clfe, rear_surr */
7405 0x02, 0x03, 0x04, 0x05
7408 static hda_nid_t alc883_adc_nids[2] = {
7413 static hda_nid_t alc883_adc_nids_alt[1] = {
7418 static hda_nid_t alc883_adc_nids_rev[2] = {
7423 #define alc889_adc_nids alc880_adc_nids
7425 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7427 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7429 #define alc889_capsrc_nids alc882_capsrc_nids
7432 /* FIXME: should be a matrix-type input source selection */
7434 static struct hda_input_mux alc883_capture_source = {
7438 { "Front Mic", 0x1 },
7444 static struct hda_input_mux alc883_3stack_6ch_intel = {
7448 { "Front Mic", 0x0 },
7454 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7462 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7472 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7480 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7484 { "Front Mic", 0x1 },
7489 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7497 static struct hda_input_mux alc889A_mb31_capture_source = {
7501 /* Front Mic (0x01) unused */
7503 /* Line 2 (0x03) unused */
7504 /* CD (0x04) unsused? */
7511 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7518 static struct hda_verb alc883_3ST_ch2_init[] = {
7519 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7520 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7521 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7522 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7529 static struct hda_verb alc883_3ST_ch4_init[] = {
7530 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7531 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7532 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7533 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7534 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7541 static struct hda_verb alc883_3ST_ch6_init[] = {
7542 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7543 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7544 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7545 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7546 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7547 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7551 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7552 { 2, alc883_3ST_ch2_init },
7553 { 4, alc883_3ST_ch4_init },
7554 { 6, alc883_3ST_ch6_init },
7560 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7561 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7562 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7563 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7564 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7571 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7572 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7573 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7574 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7575 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7576 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7583 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7584 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7585 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7586 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7587 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7588 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7589 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7593 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7594 { 2, alc883_3ST_ch2_intel_init },
7595 { 4, alc883_3ST_ch4_intel_init },
7596 { 6, alc883_3ST_ch6_intel_init },
7602 static struct hda_verb alc883_sixstack_ch6_init[] = {
7603 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7604 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7605 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7606 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7613 static struct hda_verb alc883_sixstack_ch8_init[] = {
7614 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7615 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7616 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7617 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7621 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7622 { 6, alc883_sixstack_ch6_init },
7623 { 8, alc883_sixstack_ch8_init },
7626 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7627 static struct hda_verb alc889A_mb31_ch2_init[] = {
7628 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7629 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7630 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7631 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7635 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7636 static struct hda_verb alc889A_mb31_ch4_init[] = {
7637 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7638 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7639 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7640 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7644 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7645 static struct hda_verb alc889A_mb31_ch5_init[] = {
7646 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7647 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7648 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7649 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7653 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7654 static struct hda_verb alc889A_mb31_ch6_init[] = {
7655 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7656 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7657 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7658 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7662 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7663 { 2, alc889A_mb31_ch2_init },
7664 { 4, alc889A_mb31_ch4_init },
7665 { 5, alc889A_mb31_ch5_init },
7666 { 6, alc889A_mb31_ch6_init },
7669 static struct hda_verb alc883_medion_eapd_verbs[] = {
7670 /* eanable EAPD on medion laptop */
7671 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7672 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7676 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7677 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7680 static struct snd_kcontrol_new alc883_base_mixer[] = {
7681 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7682 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7683 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7684 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7685 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7686 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7687 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7688 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7689 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7690 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7692 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7693 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7694 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7695 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7696 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7697 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7698 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7700 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7701 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7705 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7706 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7707 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7708 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7709 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7710 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7711 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7712 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7716 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7717 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7718 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7722 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7723 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7724 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7725 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7726 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7728 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7730 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7731 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7732 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7736 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7737 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7738 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7739 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7740 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7742 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7743 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7744 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7745 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7746 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7750 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7751 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7752 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7753 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7754 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7755 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7756 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7757 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7759 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7760 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7761 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7762 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7763 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7767 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7768 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7769 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7770 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7771 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7772 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7773 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7774 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7775 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7776 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7777 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7778 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7779 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7780 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7782 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7784 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7785 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7786 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7790 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7791 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7792 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7794 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7795 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7797 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7798 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7799 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7800 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7801 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7802 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7803 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7804 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7806 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7807 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7808 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7809 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7810 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7814 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7815 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7816 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7817 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7818 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7819 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7820 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7821 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7822 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7823 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7824 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7825 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7829 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7830 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7831 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7832 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7833 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7837 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7838 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7839 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7840 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7841 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7842 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7843 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7844 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7845 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7846 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7847 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7848 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7849 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7850 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7852 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7857 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7858 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7860 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7861 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7862 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7863 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7864 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7865 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7866 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7867 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7868 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7872 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7873 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7874 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7875 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7876 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7879 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7880 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7884 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7885 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7886 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7887 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7888 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7889 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7890 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7891 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7892 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7893 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7897 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7898 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7899 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7900 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7901 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7902 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7905 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7906 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7910 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7911 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7912 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7914 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7915 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7917 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7922 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7923 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7924 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7925 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7926 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7927 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7928 0x0d, 1, 0x0, HDA_OUTPUT),
7929 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7930 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7931 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7932 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7933 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7934 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7935 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7936 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7937 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7938 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7939 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7940 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7941 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7942 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7943 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7947 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
7949 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7950 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7951 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7952 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7953 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
7955 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
7956 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
7957 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
7958 /* Output switches */
7959 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
7960 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
7961 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
7963 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7964 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7968 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7969 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7973 static struct hda_bind_ctls alc883_bind_cap_vol = {
7974 .ops = &snd_hda_bind_vol,
7976 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7977 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7982 static struct hda_bind_ctls alc883_bind_cap_switch = {
7983 .ops = &snd_hda_bind_sw,
7985 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7986 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7991 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7992 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7993 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7994 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7998 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7999 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8003 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8004 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8005 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8008 /* .name = "Capture Source", */
8009 .name = "Input Source",
8011 .info = alc_mux_enum_info,
8012 .get = alc_mux_enum_get,
8013 .put = alc_mux_enum_put,
8018 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8020 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8021 .name = "Channel Mode",
8022 .info = alc_ch_mode_info,
8023 .get = alc_ch_mode_get,
8024 .put = alc_ch_mode_put,
8029 static struct hda_verb alc883_init_verbs[] = {
8030 /* ADC1: mute amp left and right */
8031 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8032 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8033 /* ADC2: mute amp left and right */
8034 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8035 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8036 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8039 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8042 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8043 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8045 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8046 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8047 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8051 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8053 /* mute analog input loopbacks */
8054 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8055 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8056 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8057 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8058 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8060 /* Front Pin: output 0 (0x0c) */
8061 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8062 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8063 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8064 /* Rear Pin: output 1 (0x0d) */
8065 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8067 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8068 /* CLFE Pin: output 2 (0x0e) */
8069 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8070 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8071 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8072 /* Side Pin: output 3 (0x0f) */
8073 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8074 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8075 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8076 /* Mic (rear) pin: input vref at 80% */
8077 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8078 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8079 /* Front Mic pin: input vref at 80% */
8080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8081 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8082 /* Line In pin: input */
8083 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8084 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8085 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8086 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8087 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8088 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8089 /* CD pin widget for input */
8090 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8092 /* FIXME: use matrix-type input source selection */
8093 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8095 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8096 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8097 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8098 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8100 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8103 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8107 /* toggle speaker-output according to the hp-jack state */
8108 static void alc883_mitac_init_hook(struct hda_codec *codec)
8110 struct alc_spec *spec = codec->spec;
8112 spec->autocfg.hp_pins[0] = 0x15;
8113 spec->autocfg.speaker_pins[0] = 0x14;
8114 spec->autocfg.speaker_pins[1] = 0x17;
8115 alc_automute_amp(codec);
8118 /* auto-toggle front mic */
8120 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8122 unsigned int present;
8125 present = snd_hda_codec_read(codec, 0x18, 0,
8126 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8127 bits = present ? HDA_AMP_MUTE : 0;
8128 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8132 static struct hda_verb alc883_mitac_verbs[] = {
8134 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8135 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8137 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8138 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8140 /* enable unsolicited event */
8141 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8142 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8147 static struct hda_verb alc883_clevo_m720_verbs[] = {
8149 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8150 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8152 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8153 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8155 /* enable unsolicited event */
8156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8162 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8164 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8165 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8168 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8170 /* enable unsolicited event */
8171 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8176 static struct hda_verb alc883_tagra_verbs[] = {
8177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8178 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8180 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8183 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8184 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8185 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8187 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8188 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8189 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8190 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8195 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8197 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8198 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8202 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8205 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8210 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8211 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8213 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8214 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8215 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8219 static struct hda_verb alc883_haier_w66_verbs[] = {
8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8223 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8225 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8226 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8227 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8228 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8232 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8233 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8234 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8235 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8236 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8237 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8238 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8239 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8240 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8244 static struct hda_verb alc888_6st_dell_verbs[] = {
8245 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8249 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8251 struct alc_spec *spec = codec->spec;
8253 spec->autocfg.hp_pins[0] = 0x1b;
8254 spec->autocfg.speaker_pins[0] = 0x14;
8255 spec->autocfg.speaker_pins[1] = 0x16;
8256 spec->autocfg.speaker_pins[2] = 0x18;
8257 alc_automute_amp(codec);
8260 static struct hda_verb alc888_3st_hp_verbs[] = {
8261 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8262 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8263 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8264 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8271 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8272 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8273 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8274 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8275 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8282 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8283 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8284 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8285 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8286 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8287 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8294 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8295 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8296 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8297 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8298 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8299 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8300 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8304 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8305 { 2, alc888_3st_hp_2ch_init },
8306 { 4, alc888_3st_hp_4ch_init },
8307 { 6, alc888_3st_hp_6ch_init },
8310 /* toggle front-jack and RCA according to the hp-jack state */
8311 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8313 unsigned int present;
8315 present = snd_hda_codec_read(codec, 0x1b, 0,
8316 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8317 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8318 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8319 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8320 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8323 /* toggle RCA according to the front-jack state */
8324 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8326 unsigned int present;
8328 present = snd_hda_codec_read(codec, 0x14, 0,
8329 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8330 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8331 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8334 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8337 if ((res >> 26) == ALC880_HP_EVENT)
8338 alc888_lenovo_ms7195_front_automute(codec);
8339 if ((res >> 26) == ALC880_FRONT_EVENT)
8340 alc888_lenovo_ms7195_rca_automute(codec);
8343 static struct hda_verb alc883_medion_md2_verbs[] = {
8344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8347 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8349 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8353 /* toggle speaker-output according to the hp-jack state */
8354 static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8356 struct alc_spec *spec = codec->spec;
8358 spec->autocfg.hp_pins[0] = 0x14;
8359 spec->autocfg.speaker_pins[0] = 0x15;
8360 alc_automute_amp(codec);
8363 /* toggle speaker-output according to the hp-jack state */
8364 #define alc883_tagra_init_hook alc882_targa_init_hook
8365 #define alc883_tagra_unsol_event alc882_targa_unsol_event
8367 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8369 unsigned int present;
8371 present = snd_hda_codec_read(codec, 0x18, 0,
8372 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8373 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8374 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8377 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8379 struct alc_spec *spec = codec->spec;
8381 spec->autocfg.hp_pins[0] = 0x15;
8382 spec->autocfg.speaker_pins[0] = 0x14;
8383 alc_automute_amp(codec);
8384 alc883_clevo_m720_mic_automute(codec);
8387 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8390 switch (res >> 26) {
8391 case ALC880_MIC_EVENT:
8392 alc883_clevo_m720_mic_automute(codec);
8395 alc_automute_amp_unsol_event(codec, res);
8400 /* toggle speaker-output according to the hp-jack state */
8401 static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8403 struct alc_spec *spec = codec->spec;
8405 spec->autocfg.hp_pins[0] = 0x14;
8406 spec->autocfg.speaker_pins[0] = 0x15;
8407 alc_automute_amp(codec);
8410 static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8412 struct alc_spec *spec = codec->spec;
8414 spec->autocfg.hp_pins[0] = 0x1b;
8415 spec->autocfg.speaker_pins[0] = 0x14;
8416 alc_automute_amp(codec);
8419 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8421 unsigned int present;
8424 present = snd_hda_codec_read(codec, 0x14, 0,
8425 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8426 bits = present ? HDA_AMP_MUTE : 0;
8427 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8428 HDA_AMP_MUTE, bits);
8431 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8433 unsigned int present;
8436 present = snd_hda_codec_read(codec, 0x1b, 0,
8437 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8438 bits = present ? HDA_AMP_MUTE : 0;
8439 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8440 HDA_AMP_MUTE, bits);
8441 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8442 HDA_AMP_MUTE, bits);
8445 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8448 if ((res >> 26) == ALC880_HP_EVENT)
8449 alc883_lenovo_101e_all_automute(codec);
8450 if ((res >> 26) == ALC880_FRONT_EVENT)
8451 alc883_lenovo_101e_ispeaker_automute(codec);
8454 /* toggle speaker-output according to the hp-jack state */
8455 static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8457 struct alc_spec *spec = codec->spec;
8459 spec->autocfg.hp_pins[0] = 0x14;
8460 spec->autocfg.speaker_pins[0] = 0x15;
8461 spec->autocfg.speaker_pins[1] = 0x16;
8462 alc_automute_amp(codec);
8465 static struct hda_verb alc883_acer_eapd_verbs[] = {
8466 /* HP Pin: output 0 (0x0c) */
8467 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8468 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8469 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8470 /* Front Pin: output 0 (0x0c) */
8471 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8472 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8473 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8474 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8475 /* eanable EAPD on medion laptop */
8476 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8477 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8478 /* enable unsolicited event */
8479 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8483 static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8485 struct alc_spec *spec = codec->spec;
8487 spec->autocfg.hp_pins[0] = 0x1b;
8488 spec->autocfg.speaker_pins[0] = 0x14;
8489 spec->autocfg.speaker_pins[1] = 0x15;
8490 spec->autocfg.speaker_pins[2] = 0x16;
8491 spec->autocfg.speaker_pins[3] = 0x17;
8492 alc_automute_amp(codec);
8495 static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8497 struct alc_spec *spec = codec->spec;
8499 spec->autocfg.hp_pins[0] = 0x1b;
8500 spec->autocfg.speaker_pins[0] = 0x14;
8501 spec->autocfg.speaker_pins[1] = 0x15;
8502 spec->autocfg.speaker_pins[2] = 0x16;
8503 spec->autocfg.speaker_pins[3] = 0x17;
8504 spec->autocfg.speaker_pins[4] = 0x1a;
8505 alc_automute_amp(codec);
8509 * generic initialization of ADC, input mixers and output mixers
8511 static struct hda_verb alc883_auto_init_verbs[] = {
8513 * Unmute ADC0-2 and set the default input to mic-in
8515 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8517 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8518 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8520 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8522 * Note: PASD motherboards uses the Line In 2 as the input for
8523 * front panel mic (mic 2)
8525 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8529 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8533 * Set up output mixers (0x0c - 0x0f)
8535 /* set vol=0 to output mixers */
8536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8540 /* set up input amps for analog loopback */
8541 /* Amp Indices: DAC = 0, mixer = 1 */
8542 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8544 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8546 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8547 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8548 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8549 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8550 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8551 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8553 /* FIXME: use matrix-type input source selection */
8554 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8556 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8557 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8558 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8559 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8562 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8565 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8571 static struct hda_verb alc888_asus_m90v_verbs[] = {
8572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8575 /* enable unsolicited event */
8576 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8577 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8581 static void alc883_nb_mic_automute(struct hda_codec *codec)
8583 unsigned int present;
8585 present = snd_hda_codec_read(codec, 0x18, 0,
8586 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8587 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8588 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8589 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8590 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8593 static void alc883_M90V_init_hook(struct hda_codec *codec)
8595 struct alc_spec *spec = codec->spec;
8597 spec->autocfg.hp_pins[0] = 0x1b;
8598 spec->autocfg.speaker_pins[0] = 0x14;
8599 spec->autocfg.speaker_pins[1] = 0x15;
8600 spec->autocfg.speaker_pins[2] = 0x16;
8601 alc_automute_pin(codec);
8604 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8607 switch (res >> 26) {
8608 case ALC880_MIC_EVENT:
8609 alc883_nb_mic_automute(codec);
8612 alc_sku_unsol_event(codec, res);
8617 static void alc883_mode2_inithook(struct hda_codec *codec)
8619 alc883_M90V_init_hook(codec);
8620 alc883_nb_mic_automute(codec);
8623 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8627 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8629 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8630 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8631 /* enable unsolicited event */
8632 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8636 static void alc883_eee1601_inithook(struct hda_codec *codec)
8638 struct alc_spec *spec = codec->spec;
8640 spec->autocfg.hp_pins[0] = 0x14;
8641 spec->autocfg.speaker_pins[0] = 0x1b;
8642 alc_automute_pin(codec);
8645 static struct hda_verb alc889A_mb31_verbs[] = {
8646 /* Init rear pin (used as headphone output) */
8647 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8648 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8649 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8650 /* Init line pin (used as output in 4ch and 6ch mode) */
8651 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8652 /* Init line 2 pin (used as headphone out by default) */
8653 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8654 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8658 /* Mute speakers according to the headphone jack state */
8659 static void alc889A_mb31_automute(struct hda_codec *codec)
8661 unsigned int present;
8663 /* Mute only in 2ch or 4ch mode */
8664 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8666 present = snd_hda_codec_read(codec, 0x15, 0,
8667 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8668 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8669 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8670 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8671 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8675 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8677 if ((res >> 26) == ALC880_HP_EVENT)
8678 alc889A_mb31_automute(codec);
8681 #ifdef CONFIG_SND_HDA_POWER_SAVE
8682 #define alc883_loopbacks alc880_loopbacks
8685 /* pcm configuration: identiacal with ALC880 */
8686 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8687 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8688 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8689 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8690 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8693 * configuration and preset
8695 static const char *alc883_models[ALC883_MODEL_LAST] = {
8696 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8697 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8698 [ALC883_3ST_6ch] = "3stack-6ch",
8699 [ALC883_6ST_DIG] = "6stack-dig",
8700 [ALC883_TARGA_DIG] = "targa-dig",
8701 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8702 [ALC883_ACER] = "acer",
8703 [ALC883_ACER_ASPIRE] = "acer-aspire",
8704 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8705 [ALC883_MEDION] = "medion",
8706 [ALC883_MEDION_MD2] = "medion-md2",
8707 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8708 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8709 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8710 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8711 [ALC888_LENOVO_SKY] = "lenovo-sky",
8712 [ALC883_HAIER_W66] = "haier-w66",
8713 [ALC888_3ST_HP] = "3stack-hp",
8714 [ALC888_6ST_DELL] = "6stack-dell",
8715 [ALC883_MITAC] = "mitac",
8716 [ALC883_CLEVO_M720] = "clevo-m720",
8717 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8718 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8719 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8720 [ALC1200_ASUS_P5Q] = "asus-p5q",
8721 [ALC889A_MB31] = "mb31",
8722 [ALC883_AUTO] = "auto",
8725 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8726 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8727 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8728 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8729 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8730 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8731 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8732 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8733 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8734 ALC888_ACER_ASPIRE_4930G),
8735 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8736 ALC888_ACER_ASPIRE_4930G),
8737 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8738 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8739 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8740 ALC888_ACER_ASPIRE_4930G),
8741 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8742 ALC888_ACER_ASPIRE_4930G),
8743 /* default Acer -- disabled as it causes more problems.
8744 * model=auto should work fine now
8746 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8747 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8748 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8749 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8750 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8751 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8752 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8753 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8754 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8755 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8756 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8757 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8758 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8759 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8760 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8761 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8762 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8763 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8764 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8765 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8766 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8767 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8768 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8769 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8770 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8771 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8772 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8773 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8774 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8775 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8776 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8777 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8778 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8779 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8780 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8781 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8782 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8783 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8784 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8785 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8786 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8787 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8788 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8789 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8790 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8791 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8792 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8793 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8794 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8795 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8796 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8797 ALC883_FUJITSU_PI2515),
8798 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8799 ALC888_FUJITSU_XA3530),
8800 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8801 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8802 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8803 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8804 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8805 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8806 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8807 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8808 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8809 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8810 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8811 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8812 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8813 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8817 static hda_nid_t alc883_slave_dig_outs[] = {
8818 ALC1200_DIGOUT_NID, 0,
8821 static hda_nid_t alc1200_slave_dig_outs[] = {
8822 ALC883_DIGOUT_NID, 0,
8825 static struct alc_config_preset alc883_presets[] = {
8826 [ALC883_3ST_2ch_DIG] = {
8827 .mixers = { alc883_3ST_2ch_mixer },
8828 .init_verbs = { alc883_init_verbs },
8829 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8830 .dac_nids = alc883_dac_nids,
8831 .dig_out_nid = ALC883_DIGOUT_NID,
8832 .dig_in_nid = ALC883_DIGIN_NID,
8833 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8834 .channel_mode = alc883_3ST_2ch_modes,
8835 .input_mux = &alc883_capture_source,
8837 [ALC883_3ST_6ch_DIG] = {
8838 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8839 .init_verbs = { alc883_init_verbs },
8840 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8841 .dac_nids = alc883_dac_nids,
8842 .dig_out_nid = ALC883_DIGOUT_NID,
8843 .dig_in_nid = ALC883_DIGIN_NID,
8844 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8845 .channel_mode = alc883_3ST_6ch_modes,
8847 .input_mux = &alc883_capture_source,
8849 [ALC883_3ST_6ch] = {
8850 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8851 .init_verbs = { alc883_init_verbs },
8852 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8853 .dac_nids = alc883_dac_nids,
8854 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8855 .channel_mode = alc883_3ST_6ch_modes,
8857 .input_mux = &alc883_capture_source,
8859 [ALC883_3ST_6ch_INTEL] = {
8860 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8861 .init_verbs = { alc883_init_verbs },
8862 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8863 .dac_nids = alc883_dac_nids,
8864 .dig_out_nid = ALC883_DIGOUT_NID,
8865 .dig_in_nid = ALC883_DIGIN_NID,
8866 .slave_dig_outs = alc883_slave_dig_outs,
8867 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8868 .channel_mode = alc883_3ST_6ch_intel_modes,
8870 .input_mux = &alc883_3stack_6ch_intel,
8872 [ALC883_6ST_DIG] = {
8873 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8874 .init_verbs = { alc883_init_verbs },
8875 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8876 .dac_nids = alc883_dac_nids,
8877 .dig_out_nid = ALC883_DIGOUT_NID,
8878 .dig_in_nid = ALC883_DIGIN_NID,
8879 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8880 .channel_mode = alc883_sixstack_modes,
8881 .input_mux = &alc883_capture_source,
8883 [ALC883_TARGA_DIG] = {
8884 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8885 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8886 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8887 .dac_nids = alc883_dac_nids,
8888 .dig_out_nid = ALC883_DIGOUT_NID,
8889 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8890 .channel_mode = alc883_3ST_6ch_modes,
8892 .input_mux = &alc883_capture_source,
8893 .unsol_event = alc883_tagra_unsol_event,
8894 .init_hook = alc883_tagra_init_hook,
8896 [ALC883_TARGA_2ch_DIG] = {
8897 .mixers = { alc883_tagra_2ch_mixer},
8898 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8899 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8900 .dac_nids = alc883_dac_nids,
8901 .adc_nids = alc883_adc_nids_alt,
8902 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8903 .dig_out_nid = ALC883_DIGOUT_NID,
8904 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8905 .channel_mode = alc883_3ST_2ch_modes,
8906 .input_mux = &alc883_capture_source,
8907 .unsol_event = alc883_tagra_unsol_event,
8908 .init_hook = alc883_tagra_init_hook,
8911 .mixers = { alc883_base_mixer },
8912 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8913 * and the headphone jack. Turn this on and rely on the
8914 * standard mute methods whenever the user wants to turn
8915 * these outputs off.
8917 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8918 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8919 .dac_nids = alc883_dac_nids,
8920 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8921 .channel_mode = alc883_3ST_2ch_modes,
8922 .input_mux = &alc883_capture_source,
8924 [ALC883_ACER_ASPIRE] = {
8925 .mixers = { alc883_acer_aspire_mixer },
8926 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8927 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8928 .dac_nids = alc883_dac_nids,
8929 .dig_out_nid = ALC883_DIGOUT_NID,
8930 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8931 .channel_mode = alc883_3ST_2ch_modes,
8932 .input_mux = &alc883_capture_source,
8933 .unsol_event = alc_automute_amp_unsol_event,
8934 .init_hook = alc883_acer_aspire_init_hook,
8936 [ALC888_ACER_ASPIRE_4930G] = {
8937 .mixers = { alc888_base_mixer,
8938 alc883_chmode_mixer },
8939 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8940 alc888_acer_aspire_4930g_verbs },
8941 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8942 .dac_nids = alc883_dac_nids,
8943 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8944 .adc_nids = alc883_adc_nids_rev,
8945 .capsrc_nids = alc883_capsrc_nids_rev,
8946 .dig_out_nid = ALC883_DIGOUT_NID,
8947 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8948 .channel_mode = alc883_3ST_6ch_modes,
8951 ARRAY_SIZE(alc888_2_capture_sources),
8952 .input_mux = alc888_2_capture_sources,
8953 .unsol_event = alc_automute_amp_unsol_event,
8954 .init_hook = alc888_acer_aspire_4930g_init_hook,
8957 .mixers = { alc883_fivestack_mixer,
8958 alc883_chmode_mixer },
8959 .init_verbs = { alc883_init_verbs,
8960 alc883_medion_eapd_verbs },
8961 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8962 .dac_nids = alc883_dac_nids,
8963 .adc_nids = alc883_adc_nids_alt,
8964 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8965 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8966 .channel_mode = alc883_sixstack_modes,
8967 .input_mux = &alc883_capture_source,
8969 [ALC883_MEDION_MD2] = {
8970 .mixers = { alc883_medion_md2_mixer},
8971 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8972 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8973 .dac_nids = alc883_dac_nids,
8974 .dig_out_nid = ALC883_DIGOUT_NID,
8975 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8976 .channel_mode = alc883_3ST_2ch_modes,
8977 .input_mux = &alc883_capture_source,
8978 .unsol_event = alc_automute_amp_unsol_event,
8979 .init_hook = alc883_medion_md2_init_hook,
8981 [ALC883_LAPTOP_EAPD] = {
8982 .mixers = { alc883_base_mixer },
8983 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8984 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8985 .dac_nids = alc883_dac_nids,
8986 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8987 .channel_mode = alc883_3ST_2ch_modes,
8988 .input_mux = &alc883_capture_source,
8990 [ALC883_CLEVO_M720] = {
8991 .mixers = { alc883_clevo_m720_mixer },
8992 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8993 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8994 .dac_nids = alc883_dac_nids,
8995 .dig_out_nid = ALC883_DIGOUT_NID,
8996 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8997 .channel_mode = alc883_3ST_2ch_modes,
8998 .input_mux = &alc883_capture_source,
8999 .unsol_event = alc883_clevo_m720_unsol_event,
9000 .init_hook = alc883_clevo_m720_init_hook,
9002 [ALC883_LENOVO_101E_2ch] = {
9003 .mixers = { alc883_lenovo_101e_2ch_mixer},
9004 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9005 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9006 .dac_nids = alc883_dac_nids,
9007 .adc_nids = alc883_adc_nids_alt,
9008 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9009 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9010 .channel_mode = alc883_3ST_2ch_modes,
9011 .input_mux = &alc883_lenovo_101e_capture_source,
9012 .unsol_event = alc883_lenovo_101e_unsol_event,
9013 .init_hook = alc883_lenovo_101e_all_automute,
9015 [ALC883_LENOVO_NB0763] = {
9016 .mixers = { alc883_lenovo_nb0763_mixer },
9017 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9018 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9019 .dac_nids = alc883_dac_nids,
9020 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9021 .channel_mode = alc883_3ST_2ch_modes,
9023 .input_mux = &alc883_lenovo_nb0763_capture_source,
9024 .unsol_event = alc_automute_amp_unsol_event,
9025 .init_hook = alc883_medion_md2_init_hook,
9027 [ALC888_LENOVO_MS7195_DIG] = {
9028 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9029 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9030 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9031 .dac_nids = alc883_dac_nids,
9032 .dig_out_nid = ALC883_DIGOUT_NID,
9033 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9034 .channel_mode = alc883_3ST_6ch_modes,
9036 .input_mux = &alc883_capture_source,
9037 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9038 .init_hook = alc888_lenovo_ms7195_front_automute,
9040 [ALC883_HAIER_W66] = {
9041 .mixers = { alc883_tagra_2ch_mixer},
9042 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9043 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9044 .dac_nids = alc883_dac_nids,
9045 .dig_out_nid = ALC883_DIGOUT_NID,
9046 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9047 .channel_mode = alc883_3ST_2ch_modes,
9048 .input_mux = &alc883_capture_source,
9049 .unsol_event = alc_automute_amp_unsol_event,
9050 .init_hook = alc883_haier_w66_init_hook,
9053 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9054 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9055 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9056 .dac_nids = alc883_dac_nids,
9057 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9058 .channel_mode = alc888_3st_hp_modes,
9060 .input_mux = &alc883_capture_source,
9061 .unsol_event = alc_automute_amp_unsol_event,
9062 .init_hook = alc888_3st_hp_init_hook,
9064 [ALC888_6ST_DELL] = {
9065 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9066 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9067 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9068 .dac_nids = alc883_dac_nids,
9069 .dig_out_nid = ALC883_DIGOUT_NID,
9070 .dig_in_nid = ALC883_DIGIN_NID,
9071 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9072 .channel_mode = alc883_sixstack_modes,
9073 .input_mux = &alc883_capture_source,
9074 .unsol_event = alc_automute_amp_unsol_event,
9075 .init_hook = alc888_6st_dell_init_hook,
9078 .mixers = { alc883_mitac_mixer },
9079 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9080 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9081 .dac_nids = alc883_dac_nids,
9082 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9083 .channel_mode = alc883_3ST_2ch_modes,
9084 .input_mux = &alc883_capture_source,
9085 .unsol_event = alc_automute_amp_unsol_event,
9086 .init_hook = alc883_mitac_init_hook,
9088 [ALC883_FUJITSU_PI2515] = {
9089 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9090 .init_verbs = { alc883_init_verbs,
9091 alc883_2ch_fujitsu_pi2515_verbs},
9092 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9093 .dac_nids = alc883_dac_nids,
9094 .dig_out_nid = ALC883_DIGOUT_NID,
9095 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9096 .channel_mode = alc883_3ST_2ch_modes,
9097 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9098 .unsol_event = alc_automute_amp_unsol_event,
9099 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
9101 [ALC888_FUJITSU_XA3530] = {
9102 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9103 .init_verbs = { alc883_init_verbs,
9104 alc888_fujitsu_xa3530_verbs },
9105 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9106 .dac_nids = alc883_dac_nids,
9107 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9108 .adc_nids = alc883_adc_nids_rev,
9109 .capsrc_nids = alc883_capsrc_nids_rev,
9110 .dig_out_nid = ALC883_DIGOUT_NID,
9111 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9112 .channel_mode = alc888_4ST_8ch_intel_modes,
9114 ARRAY_SIZE(alc888_2_capture_sources),
9115 .input_mux = alc888_2_capture_sources,
9116 .unsol_event = alc_automute_amp_unsol_event,
9117 .init_hook = alc888_fujitsu_xa3530_init_hook,
9119 [ALC888_LENOVO_SKY] = {
9120 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9121 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9122 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9123 .dac_nids = alc883_dac_nids,
9124 .dig_out_nid = ALC883_DIGOUT_NID,
9125 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9126 .channel_mode = alc883_sixstack_modes,
9128 .input_mux = &alc883_lenovo_sky_capture_source,
9129 .unsol_event = alc_automute_amp_unsol_event,
9130 .init_hook = alc888_lenovo_sky_init_hook,
9132 [ALC888_ASUS_M90V] = {
9133 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9134 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9135 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9136 .dac_nids = alc883_dac_nids,
9137 .dig_out_nid = ALC883_DIGOUT_NID,
9138 .dig_in_nid = ALC883_DIGIN_NID,
9139 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9140 .channel_mode = alc883_3ST_6ch_modes,
9142 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9143 .unsol_event = alc883_mode2_unsol_event,
9144 .init_hook = alc883_mode2_inithook,
9146 [ALC888_ASUS_EEE1601] = {
9147 .mixers = { alc883_asus_eee1601_mixer },
9148 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9149 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9150 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9151 .dac_nids = alc883_dac_nids,
9152 .dig_out_nid = ALC883_DIGOUT_NID,
9153 .dig_in_nid = ALC883_DIGIN_NID,
9154 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9155 .channel_mode = alc883_3ST_2ch_modes,
9157 .input_mux = &alc883_asus_eee1601_capture_source,
9158 .unsol_event = alc_sku_unsol_event,
9159 .init_hook = alc883_eee1601_inithook,
9161 [ALC1200_ASUS_P5Q] = {
9162 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9163 .init_verbs = { alc883_init_verbs },
9164 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9165 .dac_nids = alc883_dac_nids,
9166 .dig_out_nid = ALC1200_DIGOUT_NID,
9167 .dig_in_nid = ALC883_DIGIN_NID,
9168 .slave_dig_outs = alc1200_slave_dig_outs,
9169 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9170 .channel_mode = alc883_sixstack_modes,
9171 .input_mux = &alc883_capture_source,
9174 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9175 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9176 alc880_gpio1_init_verbs },
9177 .adc_nids = alc883_adc_nids,
9178 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9179 .dac_nids = alc883_dac_nids,
9180 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9181 .channel_mode = alc889A_mb31_6ch_modes,
9182 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9183 .input_mux = &alc889A_mb31_capture_source,
9184 .dig_out_nid = ALC883_DIGOUT_NID,
9185 .unsol_event = alc889A_mb31_unsol_event,
9186 .init_hook = alc889A_mb31_automute,
9192 * BIOS auto configuration
9194 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9195 hda_nid_t nid, int pin_type,
9199 struct alc_spec *spec = codec->spec;
9202 alc_set_pin_output(codec, nid, pin_type);
9203 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9206 idx = spec->multiout.dac_nids[dac_idx] - 2;
9207 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9211 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9213 struct alc_spec *spec = codec->spec;
9216 for (i = 0; i <= HDA_SIDE; i++) {
9217 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9218 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9220 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9225 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9227 struct alc_spec *spec = codec->spec;
9230 pin = spec->autocfg.hp_pins[0];
9231 if (pin) /* connect to front */
9233 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9234 pin = spec->autocfg.speaker_pins[0];
9236 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9239 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9240 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9242 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9244 struct alc_spec *spec = codec->spec;
9247 for (i = 0; i < AUTO_PIN_LAST; i++) {
9248 hda_nid_t nid = spec->autocfg.input_pins[i];
9249 if (alc883_is_input_pin(nid)) {
9250 alc_set_input_pin(codec, nid, i);
9251 if (nid != ALC883_PIN_CD_NID &&
9252 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9253 snd_hda_codec_write(codec, nid, 0,
9254 AC_VERB_SET_AMP_GAIN_MUTE,
9260 #define alc883_auto_init_input_src alc882_auto_init_input_src
9262 /* almost identical with ALC880 parser... */
9263 static int alc883_parse_auto_config(struct hda_codec *codec)
9265 struct alc_spec *spec = codec->spec;
9266 int err = alc880_parse_auto_config(codec);
9267 struct auto_pin_cfg *cfg = &spec->autocfg;
9273 return 0; /* no config found */
9275 err = alc_auto_add_mic_boost(codec);
9279 /* hack - override the init verbs */
9280 spec->init_verbs[0] = alc883_auto_init_verbs;
9282 /* setup input_mux for ALC889 */
9283 if (codec->vendor_id == 0x10ec0889) {
9284 /* digital-mic input pin is excluded in alc880_auto_create..()
9285 * because it's under 0x18
9287 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9288 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9289 struct hda_input_mux *imux = &spec->private_imux[0];
9290 for (i = 1; i < 3; i++)
9291 memcpy(&spec->private_imux[i],
9292 &spec->private_imux[0],
9293 sizeof(spec->private_imux[0]));
9294 imux->items[imux->num_items].label = "Int DMic";
9295 imux->items[imux->num_items].index = 0x0b;
9297 spec->num_mux_defs = 3;
9298 spec->input_mux = spec->private_imux;
9302 return 1; /* config found */
9305 /* additional initialization for auto-configuration model */
9306 static void alc883_auto_init(struct hda_codec *codec)
9308 struct alc_spec *spec = codec->spec;
9309 alc883_auto_init_multi_out(codec);
9310 alc883_auto_init_hp_out(codec);
9311 alc883_auto_init_analog_input(codec);
9312 alc883_auto_init_input_src(codec);
9313 if (spec->unsol_event)
9314 alc_inithook(codec);
9317 static int patch_alc883(struct hda_codec *codec)
9319 struct alc_spec *spec;
9320 int err, board_config;
9322 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9328 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9330 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9333 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
9334 /* Pick up systems that don't supply PCI SSID */
9335 switch (codec->subsystem_id) {
9336 case 0x106b3600: /* Macbook 3.1 */
9337 board_config = ALC889A_MB31;
9341 "hda_codec: Unknown model for %s, trying "
9342 "auto-probe from BIOS...\n", codec->chip_name);
9343 board_config = ALC883_AUTO;
9347 if (board_config == ALC883_AUTO) {
9348 /* automatic parse from the BIOS config */
9349 err = alc883_parse_auto_config(codec);
9355 "hda_codec: Cannot set up configuration "
9356 "from BIOS. Using base mode...\n");
9357 board_config = ALC883_3ST_2ch_DIG;
9361 err = snd_hda_attach_beep_device(codec, 0x1);
9367 if (board_config != ALC883_AUTO)
9368 setup_preset(spec, &alc883_presets[board_config]);
9370 switch (codec->vendor_id) {
9372 if (!spec->num_adc_nids) {
9373 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9374 spec->adc_nids = alc883_adc_nids;
9376 if (!spec->capsrc_nids)
9377 spec->capsrc_nids = alc883_capsrc_nids;
9378 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9379 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9382 if (!spec->num_adc_nids) {
9383 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9384 spec->adc_nids = alc889_adc_nids;
9386 if (!spec->capsrc_nids)
9387 spec->capsrc_nids = alc889_capsrc_nids;
9388 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9392 if (!spec->num_adc_nids) {
9393 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9394 spec->adc_nids = alc883_adc_nids;
9396 if (!spec->capsrc_nids)
9397 spec->capsrc_nids = alc883_capsrc_nids;
9398 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9402 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9403 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9404 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9406 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9407 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9409 if (!spec->cap_mixer)
9410 set_capture_mixer(spec);
9411 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9413 spec->vmaster_nid = 0x0c;
9415 codec->patch_ops = alc_patch_ops;
9416 if (board_config == ALC883_AUTO)
9417 spec->init_hook = alc883_auto_init;
9419 #ifdef CONFIG_SND_HDA_POWER_SAVE
9420 if (!spec->loopback.amplist)
9421 spec->loopback.amplist = alc883_loopbacks;
9423 codec->proc_widget_hook = print_realtek_coef;
9432 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9433 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9435 #define alc262_dac_nids alc260_dac_nids
9436 #define alc262_adc_nids alc882_adc_nids
9437 #define alc262_adc_nids_alt alc882_adc_nids_alt
9438 #define alc262_capsrc_nids alc882_capsrc_nids
9439 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9441 #define alc262_modes alc260_modes
9442 #define alc262_capture_source alc882_capture_source
9444 static hda_nid_t alc262_dmic_adc_nids[1] = {
9449 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9451 static struct snd_kcontrol_new alc262_base_mixer[] = {
9452 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9453 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9454 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9455 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9456 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9457 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9460 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9461 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9462 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9463 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9464 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9465 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9466 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9467 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9471 /* update HP, line and mono-out pins according to the master switch */
9472 static void alc262_hp_master_update(struct hda_codec *codec)
9474 struct alc_spec *spec = codec->spec;
9475 int val = spec->master_sw;
9478 snd_hda_codec_write_cache(codec, 0x1b, 0,
9479 AC_VERB_SET_PIN_WIDGET_CONTROL,
9481 snd_hda_codec_write_cache(codec, 0x15, 0,
9482 AC_VERB_SET_PIN_WIDGET_CONTROL,
9484 /* mono (speaker) depending on the HP jack sense */
9485 val = val && !spec->jack_present;
9486 snd_hda_codec_write_cache(codec, 0x16, 0,
9487 AC_VERB_SET_PIN_WIDGET_CONTROL,
9491 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9493 struct alc_spec *spec = codec->spec;
9494 unsigned int presence;
9495 presence = snd_hda_codec_read(codec, 0x1b, 0,
9496 AC_VERB_GET_PIN_SENSE, 0);
9497 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9498 alc262_hp_master_update(codec);
9501 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9503 if ((res >> 26) != ALC880_HP_EVENT)
9505 alc262_hp_bpc_automute(codec);
9508 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9510 struct alc_spec *spec = codec->spec;
9511 unsigned int presence;
9512 presence = snd_hda_codec_read(codec, 0x15, 0,
9513 AC_VERB_GET_PIN_SENSE, 0);
9514 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9515 alc262_hp_master_update(codec);
9518 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9521 if ((res >> 26) != ALC880_HP_EVENT)
9523 alc262_hp_wildwest_automute(codec);
9526 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
9528 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9529 struct snd_ctl_elem_value *ucontrol)
9531 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9532 struct alc_spec *spec = codec->spec;
9533 int val = !!*ucontrol->value.integer.value;
9535 if (val == spec->master_sw)
9537 spec->master_sw = val;
9538 alc262_hp_master_update(codec);
9542 #define ALC262_HP_MASTER_SWITCH \
9544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9545 .name = "Master Playback Switch", \
9546 .info = snd_ctl_boolean_mono_info, \
9547 .get = alc262_hp_master_sw_get, \
9548 .put = alc262_hp_master_sw_put, \
9551 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9552 ALC262_HP_MASTER_SWITCH,
9553 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9554 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9555 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9556 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9558 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9560 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9561 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9562 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9563 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9564 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9565 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9566 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9567 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9568 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9569 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9570 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9571 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9575 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9576 ALC262_HP_MASTER_SWITCH,
9577 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9578 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9579 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9580 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9581 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9583 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9585 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9586 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9587 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9588 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9589 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9590 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9591 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9595 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9596 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9597 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9598 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9602 /* mute/unmute internal speaker according to the hp jack and mute state */
9603 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9605 struct alc_spec *spec = codec->spec;
9607 spec->autocfg.hp_pins[0] = 0x15;
9608 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9609 alc_automute_amp(codec);
9612 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9613 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9614 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9615 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9619 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9623 static struct hda_verb alc262_hp_t5735_verbs[] = {
9624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9627 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9631 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9632 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9633 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9634 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9635 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9636 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9637 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9641 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9642 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9643 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9644 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9645 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9646 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9647 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9648 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9650 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9651 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9655 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9662 /* bind hp and internal speaker mute (with plug check) as master switch */
9663 static void alc262_hippo_master_update(struct hda_codec *codec)
9665 struct alc_spec *spec = codec->spec;
9666 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9667 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9668 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9672 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9673 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9674 HDA_AMP_MUTE, mute);
9675 /* mute internal speaker per jack sense */
9676 if (spec->jack_present)
9677 mute = HDA_AMP_MUTE;
9679 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9680 HDA_AMP_MUTE, mute);
9681 if (speaker_nid && speaker_nid != line_nid)
9682 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9683 HDA_AMP_MUTE, mute);
9686 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9688 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9689 struct snd_ctl_elem_value *ucontrol)
9691 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9692 struct alc_spec *spec = codec->spec;
9693 int val = !!*ucontrol->value.integer.value;
9695 if (val == spec->master_sw)
9697 spec->master_sw = val;
9698 alc262_hippo_master_update(codec);
9702 #define ALC262_HIPPO_MASTER_SWITCH \
9704 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9705 .name = "Master Playback Switch", \
9706 .info = snd_ctl_boolean_mono_info, \
9707 .get = alc262_hippo_master_sw_get, \
9708 .put = alc262_hippo_master_sw_put, \
9711 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9712 ALC262_HIPPO_MASTER_SWITCH,
9713 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9714 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9715 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9716 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9717 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9718 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9719 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9720 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9721 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9722 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9723 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9724 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9728 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9729 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9730 ALC262_HIPPO_MASTER_SWITCH,
9731 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9732 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9733 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9734 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9735 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9736 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9737 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9738 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9739 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9740 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9744 /* mute/unmute internal speaker according to the hp jack and mute state */
9745 static void alc262_hippo_automute(struct hda_codec *codec)
9747 struct alc_spec *spec = codec->spec;
9748 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9749 unsigned int present;
9751 /* need to execute and sync at first */
9752 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9753 present = snd_hda_codec_read(codec, hp_nid, 0,
9754 AC_VERB_GET_PIN_SENSE, 0);
9755 spec->jack_present = (present & 0x80000000) != 0;
9756 alc262_hippo_master_update(codec);
9759 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9761 if ((res >> 26) != ALC880_HP_EVENT)
9763 alc262_hippo_automute(codec);
9766 static void alc262_hippo_init_hook(struct hda_codec *codec)
9768 struct alc_spec *spec = codec->spec;
9770 spec->autocfg.hp_pins[0] = 0x15;
9771 spec->autocfg.speaker_pins[0] = 0x14;
9772 alc262_hippo_automute(codec);
9775 static void alc262_hippo1_init_hook(struct hda_codec *codec)
9777 struct alc_spec *spec = codec->spec;
9779 spec->autocfg.hp_pins[0] = 0x1b;
9780 spec->autocfg.speaker_pins[0] = 0x14;
9781 alc262_hippo_automute(codec);
9785 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9786 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9787 ALC262_HIPPO_MASTER_SWITCH,
9788 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9789 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9790 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9791 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9795 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9796 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9797 ALC262_HIPPO_MASTER_SWITCH,
9798 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9799 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9800 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9801 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9802 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9806 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9807 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9808 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9809 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9810 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9811 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9812 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9815 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9816 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9817 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9818 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9822 static struct hda_verb alc262_tyan_verbs[] = {
9823 /* Headphone automute */
9824 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9825 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9826 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9828 /* P11 AUX_IN, white 4-pin connector */
9829 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9830 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9831 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9832 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9837 /* unsolicited event for HP jack sensing */
9838 static void alc262_tyan_init_hook(struct hda_codec *codec)
9840 struct alc_spec *spec = codec->spec;
9842 spec->autocfg.hp_pins[0] = 0x1b;
9843 spec->autocfg.speaker_pins[0] = 0x15;
9844 alc_automute_amp(codec);
9848 #define alc262_capture_mixer alc882_capture_mixer
9849 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9852 * generic initialization of ADC, input mixers and output mixers
9854 static struct hda_verb alc262_init_verbs[] = {
9856 * Unmute ADC0-2 and set the default input to mic-in
9858 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9859 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9860 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9861 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9862 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9865 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9867 * Note: PASD motherboards uses the Line In 2 as the input for
9868 * front panel mic (mic 2)
9870 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9871 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9872 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9873 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9874 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9875 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9878 * Set up output mixers (0x0c - 0x0e)
9880 /* set vol=0 to output mixers */
9881 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9882 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9883 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9884 /* set up input amps for analog loopback */
9885 /* Amp Indices: DAC = 0, mixer = 1 */
9886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9894 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9897 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9898 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9900 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9901 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9902 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9903 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9904 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9906 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9907 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9909 /* FIXME: use matrix-type input source selection */
9910 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9911 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9912 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9913 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9914 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9915 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9917 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9918 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9919 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9920 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9924 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9925 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9930 static struct hda_verb alc262_eapd_verbs[] = {
9931 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9932 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9936 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9937 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9938 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9942 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9943 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9944 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9945 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9947 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9948 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9952 static struct hda_verb alc262_sony_unsol_verbs[] = {
9953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9954 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9955 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9957 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9958 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9962 static struct hda_input_mux alc262_dmic_capture_source = {
9965 { "Int DMic", 0x9 },
9970 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9971 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9972 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9973 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9979 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9980 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9982 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9984 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9985 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9986 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9987 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9991 static void alc262_dmic_automute(struct hda_codec *codec)
9993 unsigned int present;
9995 present = snd_hda_codec_read(codec, 0x18, 0,
9996 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9997 snd_hda_codec_write(codec, 0x22, 0,
9998 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
10002 /* unsolicited event for HP jack sensing */
10003 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
10006 if ((res >> 26) == ALC880_MIC_EVENT)
10007 alc262_dmic_automute(codec);
10009 alc_sku_unsol_event(codec, res);
10012 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
10014 struct alc_spec *spec = codec->spec;
10016 spec->autocfg.hp_pins[0] = 0x15;
10017 spec->autocfg.speaker_pins[0] = 0x14;
10018 alc_automute_pin(codec);
10019 alc262_dmic_automute(codec);
10025 * 0x16 = internal speaker
10026 * 0x18 = external mic
10029 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10030 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10031 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10035 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10037 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10038 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10042 static struct hda_verb alc262_nec_verbs[] = {
10043 /* Unmute Speaker */
10044 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10047 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10048 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10050 /* External mic to headphone */
10051 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10052 /* External mic to speaker */
10053 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10059 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10060 * 0x1b = port replicator headphone out
10063 #define ALC_HP_EVENT 0x37
10065 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10066 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10067 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10068 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10069 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10073 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10074 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10075 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10079 static struct hda_input_mux alc262_fujitsu_capture_source = {
10083 { "Int Mic", 0x1 },
10088 static struct hda_input_mux alc262_HP_capture_source = {
10092 { "Front Mic", 0x1 },
10099 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10103 { "Front Mic", 0x2 },
10109 /* mute/unmute internal speaker according to the hp jacks and mute state */
10110 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10112 struct alc_spec *spec = codec->spec;
10115 if (force || !spec->sense_updated) {
10116 unsigned int present;
10117 /* need to execute and sync at first */
10118 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10119 /* check laptop HP jack */
10120 present = snd_hda_codec_read(codec, 0x14, 0,
10121 AC_VERB_GET_PIN_SENSE, 0);
10122 /* need to execute and sync at first */
10123 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10124 /* check docking HP jack */
10125 present |= snd_hda_codec_read(codec, 0x1b, 0,
10126 AC_VERB_GET_PIN_SENSE, 0);
10127 if (present & AC_PINSENSE_PRESENCE)
10128 spec->jack_present = 1;
10130 spec->jack_present = 0;
10131 spec->sense_updated = 1;
10133 /* unmute internal speaker only if both HPs are unplugged and
10134 * master switch is on
10136 if (spec->jack_present)
10137 mute = HDA_AMP_MUTE;
10139 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10140 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10141 HDA_AMP_MUTE, mute);
10144 /* unsolicited event for HP jack sensing */
10145 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10148 if ((res >> 26) != ALC_HP_EVENT)
10150 alc262_fujitsu_automute(codec, 1);
10153 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10155 alc262_fujitsu_automute(codec, 1);
10158 /* bind volumes of both NID 0x0c and 0x0d */
10159 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10160 .ops = &snd_hda_bind_vol,
10162 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10163 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10168 /* mute/unmute internal speaker according to the hp jack and mute state */
10169 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10171 struct alc_spec *spec = codec->spec;
10174 if (force || !spec->sense_updated) {
10175 unsigned int present_int_hp;
10176 /* need to execute and sync at first */
10177 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10178 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10179 AC_VERB_GET_PIN_SENSE, 0);
10180 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10181 spec->sense_updated = 1;
10183 if (spec->jack_present) {
10184 /* mute internal speaker */
10185 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10186 HDA_AMP_MUTE, HDA_AMP_MUTE);
10187 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10188 HDA_AMP_MUTE, HDA_AMP_MUTE);
10190 /* unmute internal speaker if necessary */
10191 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10192 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10193 HDA_AMP_MUTE, mute);
10194 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10195 HDA_AMP_MUTE, mute);
10199 /* unsolicited event for HP jack sensing */
10200 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10203 if ((res >> 26) != ALC_HP_EVENT)
10205 alc262_lenovo_3000_automute(codec, 1);
10208 /* bind hp and internal speaker mute (with plug check) */
10209 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10210 struct snd_ctl_elem_value *ucontrol)
10212 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10213 long *valp = ucontrol->value.integer.value;
10216 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10218 valp ? 0 : HDA_AMP_MUTE);
10219 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10221 valp ? 0 : HDA_AMP_MUTE);
10224 alc262_fujitsu_automute(codec, 0);
10228 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10229 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10231 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10232 .name = "Master Playback Switch",
10233 .info = snd_hda_mixer_amp_switch_info,
10234 .get = snd_hda_mixer_amp_switch_get,
10235 .put = alc262_fujitsu_master_sw_put,
10236 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10238 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10239 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10240 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10241 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10242 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10243 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10244 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10245 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10249 /* bind hp and internal speaker mute (with plug check) */
10250 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10251 struct snd_ctl_elem_value *ucontrol)
10253 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10254 long *valp = ucontrol->value.integer.value;
10257 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10259 valp ? 0 : HDA_AMP_MUTE);
10262 alc262_lenovo_3000_automute(codec, 0);
10266 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10267 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10270 .name = "Master Playback Switch",
10271 .info = snd_hda_mixer_amp_switch_info,
10272 .get = snd_hda_mixer_amp_switch_get,
10273 .put = alc262_lenovo_3000_master_sw_put,
10274 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10278 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10279 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10280 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10281 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10282 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10283 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10287 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10288 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10289 ALC262_HIPPO_MASTER_SWITCH,
10290 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10291 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10292 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10293 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10294 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10295 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10299 /* additional init verbs for Benq laptops */
10300 static struct hda_verb alc262_EAPD_verbs[] = {
10301 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10302 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10306 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10308 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10310 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10311 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10315 /* Samsung Q1 Ultra Vista model setup */
10316 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10317 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10318 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10321 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10322 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10326 static struct hda_verb alc262_ultra_verbs[] = {
10328 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10332 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10333 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10334 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10335 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10338 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10339 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10340 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10341 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10343 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10344 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10345 /* ADC, choose mic */
10346 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10349 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10350 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10351 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10359 /* mute/unmute internal speaker according to the hp jack and mute state */
10360 static void alc262_ultra_automute(struct hda_codec *codec)
10362 struct alc_spec *spec = codec->spec;
10366 /* auto-mute only when HP is used as HP */
10367 if (!spec->cur_mux[0]) {
10368 unsigned int present;
10369 /* need to execute and sync at first */
10370 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10371 present = snd_hda_codec_read(codec, 0x15, 0,
10372 AC_VERB_GET_PIN_SENSE, 0);
10373 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10374 if (spec->jack_present)
10375 mute = HDA_AMP_MUTE;
10377 /* mute/unmute internal speaker */
10378 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10379 HDA_AMP_MUTE, mute);
10380 /* mute/unmute HP */
10381 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10382 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10385 /* unsolicited event for HP jack sensing */
10386 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10389 if ((res >> 26) != ALC880_HP_EVENT)
10391 alc262_ultra_automute(codec);
10394 static struct hda_input_mux alc262_ultra_capture_source = {
10398 { "Headphone", 0x7 },
10402 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10403 struct snd_ctl_elem_value *ucontrol)
10405 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10406 struct alc_spec *spec = codec->spec;
10409 ret = alc_mux_enum_put(kcontrol, ucontrol);
10412 /* reprogram the HP pin as mic or HP according to the input source */
10413 snd_hda_codec_write_cache(codec, 0x15, 0,
10414 AC_VERB_SET_PIN_WIDGET_CONTROL,
10415 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10416 alc262_ultra_automute(codec); /* mute/unmute HP */
10420 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10421 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10422 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10425 .name = "Capture Source",
10426 .info = alc_mux_enum_info,
10427 .get = alc_mux_enum_get,
10428 .put = alc262_ultra_mux_enum_put,
10433 /* add playback controls from the parsed DAC table */
10434 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10435 const struct auto_pin_cfg *cfg)
10440 spec->multiout.num_dacs = 1; /* only use one dac */
10441 spec->multiout.dac_nids = spec->private_dac_nids;
10442 spec->multiout.dac_nids[0] = 2;
10444 nid = cfg->line_out_pins[0];
10446 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10447 "Front Playback Volume",
10448 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10451 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10452 "Front Playback Switch",
10453 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10458 nid = cfg->speaker_pins[0];
10461 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10462 "Speaker Playback Volume",
10463 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10467 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10468 "Speaker Playback Switch",
10469 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10474 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10475 "Speaker Playback Switch",
10476 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10482 nid = cfg->hp_pins[0];
10484 /* spec->multiout.hp_nid = 2; */
10486 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10487 "Headphone Playback Volume",
10488 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10492 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10493 "Headphone Playback Switch",
10494 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10499 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10500 "Headphone Playback Switch",
10501 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10510 /* identical with ALC880 */
10511 #define alc262_auto_create_analog_input_ctls \
10512 alc880_auto_create_analog_input_ctls
10515 * generic initialization of ADC, input mixers and output mixers
10517 static struct hda_verb alc262_volume_init_verbs[] = {
10519 * Unmute ADC0-2 and set the default input to mic-in
10521 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10523 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10524 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10525 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10526 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10528 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10530 * Note: PASD motherboards uses the Line In 2 as the input for
10531 * front panel mic (mic 2)
10533 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10534 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10535 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10536 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10537 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10538 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10541 * Set up output mixers (0x0c - 0x0f)
10543 /* set vol=0 to output mixers */
10544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10546 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10548 /* set up input amps for analog loopback */
10549 /* Amp Indices: DAC = 0, mixer = 1 */
10550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10552 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10553 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10554 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10555 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10557 /* FIXME: use matrix-type input source selection */
10558 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10559 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10560 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10561 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10562 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10563 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10566 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10567 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10568 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10573 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10578 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10580 * Unmute ADC0-2 and set the default input to mic-in
10582 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10583 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10584 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10585 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10586 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10587 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10589 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10591 * Note: PASD motherboards uses the Line In 2 as the input for
10592 * front panel mic (mic 2)
10594 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10595 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10596 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10597 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10598 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10599 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10604 * Set up output mixers (0x0c - 0x0e)
10606 /* set vol=0 to output mixers */
10607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10608 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10609 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10611 /* set up input amps for analog loopback */
10612 /* Amp Indices: DAC = 0, mixer = 1 */
10613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10620 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10621 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10622 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10624 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10627 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10628 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10631 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10632 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10633 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10634 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10637 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10638 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10639 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10640 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10641 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10644 /* FIXME: use matrix-type input source selection */
10645 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10646 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10650 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10652 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10653 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10657 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10660 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10662 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10667 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10669 * Unmute ADC0-2 and set the default input to mic-in
10671 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10672 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10673 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10675 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10676 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10678 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10680 * Note: PASD motherboards uses the Line In 2 as the input for front
10681 * panel mic (mic 2)
10683 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10684 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10693 * Set up output mixers (0x0c - 0x0e)
10695 /* set vol=0 to output mixers */
10696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10697 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10698 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10700 /* set up input amps for analog loopback */
10701 /* Amp Indices: DAC = 0, mixer = 1 */
10702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10704 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10705 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10707 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10710 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10711 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10712 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10713 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10714 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10715 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10716 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10718 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10719 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10721 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10724 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10725 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10726 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10727 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10728 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10729 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10731 /* FIXME: use matrix-type input source selection */
10732 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10733 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10737 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10738 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10739 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10742 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10743 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10744 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10745 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10746 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10747 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10748 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10750 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10751 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10752 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10753 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10754 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10755 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10758 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10763 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10767 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10769 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10770 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10774 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10775 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10776 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10781 #ifdef CONFIG_SND_HDA_POWER_SAVE
10782 #define alc262_loopbacks alc880_loopbacks
10785 /* pcm configuration: identiacal with ALC880 */
10786 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10787 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10788 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10789 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10792 * BIOS auto configuration
10794 static int alc262_parse_auto_config(struct hda_codec *codec)
10796 struct alc_spec *spec = codec->spec;
10798 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10800 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10804 if (!spec->autocfg.line_outs) {
10805 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10806 spec->multiout.max_channels = 2;
10807 spec->no_analog = 1;
10810 return 0; /* can't find valid BIOS pin config */
10812 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10815 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10819 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10822 if (spec->autocfg.dig_outs) {
10823 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10824 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10826 if (spec->autocfg.dig_in_pin)
10827 spec->dig_in_nid = ALC262_DIGIN_NID;
10829 if (spec->kctls.list)
10830 add_mixer(spec, spec->kctls.list);
10832 add_verb(spec, alc262_volume_init_verbs);
10833 spec->num_mux_defs = 1;
10834 spec->input_mux = &spec->private_imux[0];
10836 err = alc_auto_add_mic_boost(codec);
10840 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10845 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10846 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10847 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10848 #define alc262_auto_init_input_src alc882_auto_init_input_src
10851 /* init callback for auto-configuration model -- overriding the default init */
10852 static void alc262_auto_init(struct hda_codec *codec)
10854 struct alc_spec *spec = codec->spec;
10855 alc262_auto_init_multi_out(codec);
10856 alc262_auto_init_hp_out(codec);
10857 alc262_auto_init_analog_input(codec);
10858 alc262_auto_init_input_src(codec);
10859 if (spec->unsol_event)
10860 alc_inithook(codec);
10864 * configuration and preset
10866 static const char *alc262_models[ALC262_MODEL_LAST] = {
10867 [ALC262_BASIC] = "basic",
10868 [ALC262_HIPPO] = "hippo",
10869 [ALC262_HIPPO_1] = "hippo_1",
10870 [ALC262_FUJITSU] = "fujitsu",
10871 [ALC262_HP_BPC] = "hp-bpc",
10872 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10873 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10874 [ALC262_HP_RP5700] = "hp-rp5700",
10875 [ALC262_BENQ_ED8] = "benq",
10876 [ALC262_BENQ_T31] = "benq-t31",
10877 [ALC262_SONY_ASSAMD] = "sony-assamd",
10878 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10879 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10880 [ALC262_ULTRA] = "ultra",
10881 [ALC262_LENOVO_3000] = "lenovo-3000",
10882 [ALC262_NEC] = "nec",
10883 [ALC262_TYAN] = "tyan",
10884 [ALC262_AUTO] = "auto",
10887 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10888 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10889 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10890 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10892 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10894 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10896 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10897 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10898 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10899 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10900 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10901 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10902 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10903 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10904 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10905 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10906 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10907 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10908 ALC262_HP_TC_T5735),
10909 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10910 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10911 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10912 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10913 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10914 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10915 ALC262_SONY_ASSAMD),
10916 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10917 ALC262_TOSHIBA_RX1),
10918 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10919 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10920 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10921 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10922 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10924 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10925 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10926 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10927 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10928 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10932 static struct alc_config_preset alc262_presets[] = {
10934 .mixers = { alc262_base_mixer },
10935 .init_verbs = { alc262_init_verbs },
10936 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10937 .dac_nids = alc262_dac_nids,
10939 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10940 .channel_mode = alc262_modes,
10941 .input_mux = &alc262_capture_source,
10944 .mixers = { alc262_hippo_mixer },
10945 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10946 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10947 .dac_nids = alc262_dac_nids,
10949 .dig_out_nid = ALC262_DIGOUT_NID,
10950 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10951 .channel_mode = alc262_modes,
10952 .input_mux = &alc262_capture_source,
10953 .unsol_event = alc262_hippo_unsol_event,
10954 .init_hook = alc262_hippo_init_hook,
10956 [ALC262_HIPPO_1] = {
10957 .mixers = { alc262_hippo1_mixer },
10958 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10959 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10960 .dac_nids = alc262_dac_nids,
10962 .dig_out_nid = ALC262_DIGOUT_NID,
10963 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10964 .channel_mode = alc262_modes,
10965 .input_mux = &alc262_capture_source,
10966 .unsol_event = alc262_hippo_unsol_event,
10967 .init_hook = alc262_hippo1_init_hook,
10969 [ALC262_FUJITSU] = {
10970 .mixers = { alc262_fujitsu_mixer },
10971 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10972 alc262_fujitsu_unsol_verbs },
10973 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10974 .dac_nids = alc262_dac_nids,
10976 .dig_out_nid = ALC262_DIGOUT_NID,
10977 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10978 .channel_mode = alc262_modes,
10979 .input_mux = &alc262_fujitsu_capture_source,
10980 .unsol_event = alc262_fujitsu_unsol_event,
10981 .init_hook = alc262_fujitsu_init_hook,
10983 [ALC262_HP_BPC] = {
10984 .mixers = { alc262_HP_BPC_mixer },
10985 .init_verbs = { alc262_HP_BPC_init_verbs },
10986 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10987 .dac_nids = alc262_dac_nids,
10989 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10990 .channel_mode = alc262_modes,
10991 .input_mux = &alc262_HP_capture_source,
10992 .unsol_event = alc262_hp_bpc_unsol_event,
10993 .init_hook = alc262_hp_bpc_automute,
10995 [ALC262_HP_BPC_D7000_WF] = {
10996 .mixers = { alc262_HP_BPC_WildWest_mixer },
10997 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10998 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10999 .dac_nids = alc262_dac_nids,
11001 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11002 .channel_mode = alc262_modes,
11003 .input_mux = &alc262_HP_D7000_capture_source,
11004 .unsol_event = alc262_hp_wildwest_unsol_event,
11005 .init_hook = alc262_hp_wildwest_automute,
11007 [ALC262_HP_BPC_D7000_WL] = {
11008 .mixers = { alc262_HP_BPC_WildWest_mixer,
11009 alc262_HP_BPC_WildWest_option_mixer },
11010 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11011 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11012 .dac_nids = alc262_dac_nids,
11014 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11015 .channel_mode = alc262_modes,
11016 .input_mux = &alc262_HP_D7000_capture_source,
11017 .unsol_event = alc262_hp_wildwest_unsol_event,
11018 .init_hook = alc262_hp_wildwest_automute,
11020 [ALC262_HP_TC_T5735] = {
11021 .mixers = { alc262_hp_t5735_mixer },
11022 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11023 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11024 .dac_nids = alc262_dac_nids,
11026 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11027 .channel_mode = alc262_modes,
11028 .input_mux = &alc262_capture_source,
11029 .unsol_event = alc_automute_amp_unsol_event,
11030 .init_hook = alc262_hp_t5735_init_hook,
11032 [ALC262_HP_RP5700] = {
11033 .mixers = { alc262_hp_rp5700_mixer },
11034 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11035 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11036 .dac_nids = alc262_dac_nids,
11037 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11038 .channel_mode = alc262_modes,
11039 .input_mux = &alc262_hp_rp5700_capture_source,
11041 [ALC262_BENQ_ED8] = {
11042 .mixers = { alc262_base_mixer },
11043 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11044 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11045 .dac_nids = alc262_dac_nids,
11047 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11048 .channel_mode = alc262_modes,
11049 .input_mux = &alc262_capture_source,
11051 [ALC262_SONY_ASSAMD] = {
11052 .mixers = { alc262_sony_mixer },
11053 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11054 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11055 .dac_nids = alc262_dac_nids,
11057 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11058 .channel_mode = alc262_modes,
11059 .input_mux = &alc262_capture_source,
11060 .unsol_event = alc262_hippo_unsol_event,
11061 .init_hook = alc262_hippo_init_hook,
11063 [ALC262_BENQ_T31] = {
11064 .mixers = { alc262_benq_t31_mixer },
11065 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11066 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11067 .dac_nids = alc262_dac_nids,
11069 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11070 .channel_mode = alc262_modes,
11071 .input_mux = &alc262_capture_source,
11072 .unsol_event = alc262_hippo_unsol_event,
11073 .init_hook = alc262_hippo_init_hook,
11076 .mixers = { alc262_ultra_mixer },
11077 .cap_mixer = alc262_ultra_capture_mixer,
11078 .init_verbs = { alc262_ultra_verbs },
11079 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11080 .dac_nids = alc262_dac_nids,
11081 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11082 .channel_mode = alc262_modes,
11083 .input_mux = &alc262_ultra_capture_source,
11084 .adc_nids = alc262_adc_nids, /* ADC0 */
11085 .capsrc_nids = alc262_capsrc_nids,
11086 .num_adc_nids = 1, /* single ADC */
11087 .unsol_event = alc262_ultra_unsol_event,
11088 .init_hook = alc262_ultra_automute,
11090 [ALC262_LENOVO_3000] = {
11091 .mixers = { alc262_lenovo_3000_mixer },
11092 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11093 alc262_lenovo_3000_unsol_verbs },
11094 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11095 .dac_nids = alc262_dac_nids,
11097 .dig_out_nid = ALC262_DIGOUT_NID,
11098 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11099 .channel_mode = alc262_modes,
11100 .input_mux = &alc262_fujitsu_capture_source,
11101 .unsol_event = alc262_lenovo_3000_unsol_event,
11104 .mixers = { alc262_nec_mixer },
11105 .init_verbs = { alc262_nec_verbs },
11106 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11107 .dac_nids = alc262_dac_nids,
11109 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11110 .channel_mode = alc262_modes,
11111 .input_mux = &alc262_capture_source,
11113 [ALC262_TOSHIBA_S06] = {
11114 .mixers = { alc262_toshiba_s06_mixer },
11115 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11116 alc262_eapd_verbs },
11117 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11118 .capsrc_nids = alc262_dmic_capsrc_nids,
11119 .dac_nids = alc262_dac_nids,
11120 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11121 .dig_out_nid = ALC262_DIGOUT_NID,
11122 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11123 .channel_mode = alc262_modes,
11124 .input_mux = &alc262_dmic_capture_source,
11125 .unsol_event = alc262_toshiba_s06_unsol_event,
11126 .init_hook = alc262_toshiba_s06_init_hook,
11128 [ALC262_TOSHIBA_RX1] = {
11129 .mixers = { alc262_toshiba_rx1_mixer },
11130 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11131 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11132 .dac_nids = alc262_dac_nids,
11134 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11135 .channel_mode = alc262_modes,
11136 .input_mux = &alc262_capture_source,
11137 .unsol_event = alc262_hippo_unsol_event,
11138 .init_hook = alc262_hippo_init_hook,
11141 .mixers = { alc262_tyan_mixer },
11142 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11143 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11144 .dac_nids = alc262_dac_nids,
11146 .dig_out_nid = ALC262_DIGOUT_NID,
11147 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11148 .channel_mode = alc262_modes,
11149 .input_mux = &alc262_capture_source,
11150 .unsol_event = alc_automute_amp_unsol_event,
11151 .init_hook = alc262_tyan_init_hook,
11155 static int patch_alc262(struct hda_codec *codec)
11157 struct alc_spec *spec;
11161 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11165 codec->spec = spec;
11167 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11172 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11173 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11174 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11175 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11179 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11181 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11185 if (board_config < 0) {
11186 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11187 "trying auto-probe from BIOS...\n", codec->chip_name);
11188 board_config = ALC262_AUTO;
11191 if (board_config == ALC262_AUTO) {
11192 /* automatic parse from the BIOS config */
11193 err = alc262_parse_auto_config(codec);
11199 "hda_codec: Cannot set up configuration "
11200 "from BIOS. Using base mode...\n");
11201 board_config = ALC262_BASIC;
11205 if (!spec->no_analog) {
11206 err = snd_hda_attach_beep_device(codec, 0x1);
11213 if (board_config != ALC262_AUTO)
11214 setup_preset(spec, &alc262_presets[board_config]);
11216 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11217 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11219 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11220 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11222 spec->capture_style = CAPT_MIX;
11223 if (!spec->adc_nids && spec->input_mux) {
11224 /* check whether NID 0x07 is valid */
11225 unsigned int wcap = get_wcaps(codec, 0x07);
11228 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11229 if (wcap != AC_WID_AUD_IN) {
11230 spec->adc_nids = alc262_adc_nids_alt;
11231 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11232 spec->capsrc_nids = alc262_capsrc_nids_alt;
11234 spec->adc_nids = alc262_adc_nids;
11235 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11236 spec->capsrc_nids = alc262_capsrc_nids;
11239 if (!spec->cap_mixer && !spec->no_analog)
11240 set_capture_mixer(spec);
11241 if (!spec->no_analog)
11242 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11244 spec->vmaster_nid = 0x0c;
11246 codec->patch_ops = alc_patch_ops;
11247 if (board_config == ALC262_AUTO)
11248 spec->init_hook = alc262_auto_init;
11249 #ifdef CONFIG_SND_HDA_POWER_SAVE
11250 if (!spec->loopback.amplist)
11251 spec->loopback.amplist = alc262_loopbacks;
11253 codec->proc_widget_hook = print_realtek_coef;
11259 * ALC268 channel source setting (2 channel)
11261 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11262 #define alc268_modes alc260_modes
11264 static hda_nid_t alc268_dac_nids[2] = {
11269 static hda_nid_t alc268_adc_nids[2] = {
11274 static hda_nid_t alc268_adc_nids_alt[1] = {
11279 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11281 static struct snd_kcontrol_new alc268_base_mixer[] = {
11282 /* output mixer control */
11283 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11284 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11285 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11287 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11288 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11289 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11293 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11294 /* output mixer control */
11295 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11296 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11297 ALC262_HIPPO_MASTER_SWITCH,
11298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11299 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11300 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11304 /* bind Beep switches of both NID 0x0f and 0x10 */
11305 static struct hda_bind_ctls alc268_bind_beep_sw = {
11306 .ops = &snd_hda_bind_sw,
11308 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11309 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11314 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11315 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11316 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11320 static struct hda_verb alc268_eapd_verbs[] = {
11321 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11322 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11326 /* Toshiba specific */
11327 static struct hda_verb alc268_toshiba_verbs[] = {
11328 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11332 static struct hda_input_mux alc268_acer_lc_capture_source = {
11340 /* Acer specific */
11341 /* bind volumes of both NID 0x02 and 0x03 */
11342 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11343 .ops = &snd_hda_bind_vol,
11345 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11346 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11351 /* mute/unmute internal speaker according to the hp jack and mute state */
11352 static void alc268_acer_automute(struct hda_codec *codec, int force)
11354 struct alc_spec *spec = codec->spec;
11357 if (force || !spec->sense_updated) {
11358 unsigned int present;
11359 present = snd_hda_codec_read(codec, 0x14, 0,
11360 AC_VERB_GET_PIN_SENSE, 0);
11361 spec->jack_present = (present & 0x80000000) != 0;
11362 spec->sense_updated = 1;
11364 if (spec->jack_present)
11365 mute = HDA_AMP_MUTE; /* mute internal speaker */
11366 else /* unmute internal speaker if necessary */
11367 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11368 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11369 HDA_AMP_MUTE, mute);
11373 /* bind hp and internal speaker mute (with plug check) */
11374 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11375 struct snd_ctl_elem_value *ucontrol)
11377 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11378 long *valp = ucontrol->value.integer.value;
11381 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11383 valp[0] ? 0 : HDA_AMP_MUTE);
11384 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11386 valp[1] ? 0 : HDA_AMP_MUTE);
11388 alc268_acer_automute(codec, 0);
11392 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11393 /* output mixer control */
11394 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11396 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11397 .name = "Master Playback Switch",
11398 .info = snd_hda_mixer_amp_switch_info,
11399 .get = snd_hda_mixer_amp_switch_get,
11400 .put = alc268_acer_master_sw_put,
11401 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11403 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11407 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11408 /* output mixer control */
11409 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11412 .name = "Master Playback Switch",
11413 .info = snd_hda_mixer_amp_switch_info,
11414 .get = snd_hda_mixer_amp_switch_get,
11415 .put = alc268_acer_master_sw_put,
11416 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11418 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11419 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11420 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11424 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11425 /* output mixer control */
11426 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11429 .name = "Master Playback Switch",
11430 .info = snd_hda_mixer_amp_switch_info,
11431 .get = snd_hda_mixer_amp_switch_get,
11432 .put = alc268_acer_master_sw_put,
11433 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11436 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11440 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11441 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11444 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11445 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11446 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11450 static struct hda_verb alc268_acer_verbs[] = {
11451 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11452 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11453 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11454 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11455 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11457 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11461 /* unsolicited event for HP jack sensing */
11462 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11463 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11465 static void alc268_acer_unsol_event(struct hda_codec *codec,
11468 if ((res >> 26) != ALC880_HP_EVENT)
11470 alc268_acer_automute(codec, 1);
11473 static void alc268_acer_init_hook(struct hda_codec *codec)
11475 alc268_acer_automute(codec, 1);
11478 /* toggle speaker-output according to the hp-jack state */
11479 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11481 unsigned int present;
11482 unsigned char bits;
11484 present = snd_hda_codec_read(codec, 0x15, 0,
11485 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11486 bits = present ? AMP_IN_MUTE(0) : 0;
11487 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11488 AMP_IN_MUTE(0), bits);
11489 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11490 AMP_IN_MUTE(0), bits);
11494 static void alc268_acer_mic_automute(struct hda_codec *codec)
11496 unsigned int present;
11498 present = snd_hda_codec_read(codec, 0x18, 0,
11499 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11500 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11501 present ? 0x0 : 0x6);
11504 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11507 if ((res >> 26) == ALC880_HP_EVENT)
11508 alc268_aspire_one_speaker_automute(codec);
11509 if ((res >> 26) == ALC880_MIC_EVENT)
11510 alc268_acer_mic_automute(codec);
11513 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11515 alc268_aspire_one_speaker_automute(codec);
11516 alc268_acer_mic_automute(codec);
11519 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11520 /* output mixer control */
11521 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11522 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11523 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11524 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11525 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11526 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11530 static struct hda_verb alc268_dell_verbs[] = {
11531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11532 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11533 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11537 /* mute/unmute internal speaker according to the hp jack and mute state */
11538 static void alc268_dell_init_hook(struct hda_codec *codec)
11540 struct alc_spec *spec = codec->spec;
11542 spec->autocfg.hp_pins[0] = 0x15;
11543 spec->autocfg.speaker_pins[0] = 0x14;
11544 alc_automute_pin(codec);
11547 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11548 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11549 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11550 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11551 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11552 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11553 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11554 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11555 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11559 static struct hda_verb alc267_quanta_il1_verbs[] = {
11560 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11561 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11565 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11567 unsigned int present;
11569 present = snd_hda_codec_read(codec, 0x18, 0,
11570 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11571 snd_hda_codec_write(codec, 0x23, 0,
11572 AC_VERB_SET_CONNECT_SEL,
11573 present ? 0x00 : 0x01);
11576 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11578 struct alc_spec *spec = codec->spec;
11580 spec->autocfg.hp_pins[0] = 0x15;
11581 spec->autocfg.speaker_pins[0] = 0x14;
11582 alc_automute_pin(codec);
11583 alc267_quanta_il1_mic_automute(codec);
11586 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11589 switch (res >> 26) {
11590 case ALC880_MIC_EVENT:
11591 alc267_quanta_il1_mic_automute(codec);
11594 alc_sku_unsol_event(codec, res);
11600 * generic initialization of ADC, input mixers and output mixers
11602 static struct hda_verb alc268_base_init_verbs[] = {
11603 /* Unmute DAC0-1 and set vol = 0 */
11604 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11605 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11608 * Set up output mixers (0x0c - 0x0e)
11610 /* set vol=0 to output mixers */
11611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11612 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11614 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11615 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11618 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11619 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11620 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11621 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11622 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11623 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11624 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11627 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11628 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11632 /* set PCBEEP vol = 0, mute connections */
11633 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11634 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11635 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11637 /* Unmute Selector 23h,24h and set the default input to mic-in */
11639 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11640 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11641 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11642 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11648 * generic initialization of ADC, input mixers and output mixers
11650 static struct hda_verb alc268_volume_init_verbs[] = {
11651 /* set output DAC */
11652 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11653 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11656 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11657 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11658 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11659 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11661 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11662 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11663 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11666 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11668 /* set PCBEEP vol = 0, mute connections */
11669 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11670 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11671 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11676 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11677 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11678 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11681 /* The multiple "Capture Source" controls confuse alsamixer
11682 * So call somewhat different..
11684 /* .name = "Capture Source", */
11685 .name = "Input Source",
11687 .info = alc_mux_enum_info,
11688 .get = alc_mux_enum_get,
11689 .put = alc_mux_enum_put,
11694 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11695 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11696 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11697 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11698 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11701 /* The multiple "Capture Source" controls confuse alsamixer
11702 * So call somewhat different..
11704 /* .name = "Capture Source", */
11705 .name = "Input Source",
11707 .info = alc_mux_enum_info,
11708 .get = alc_mux_enum_get,
11709 .put = alc_mux_enum_put,
11714 static struct hda_input_mux alc268_capture_source = {
11718 { "Front Mic", 0x1 },
11724 static struct hda_input_mux alc268_acer_capture_source = {
11728 { "Internal Mic", 0x1 },
11733 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11737 { "Internal Mic", 0x6 },
11742 #ifdef CONFIG_SND_DEBUG
11743 static struct snd_kcontrol_new alc268_test_mixer[] = {
11744 /* Volume widgets */
11745 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11746 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11747 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11748 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11749 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11750 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11751 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11752 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11753 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11754 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11755 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11756 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11757 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11758 /* The below appears problematic on some hardwares */
11759 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11760 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11761 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11762 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11763 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11765 /* Modes for retasking pin widgets */
11766 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11767 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11768 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11769 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11771 /* Controls for GPIO pins, assuming they are configured as outputs */
11772 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11773 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11774 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11775 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11777 /* Switches to allow the digital SPDIF output pin to be enabled.
11778 * The ALC268 does not have an SPDIF input.
11780 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11782 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11783 * this output to turn on an external amplifier.
11785 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11786 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11792 /* create input playback/capture controls for the given pin */
11793 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11794 const char *ctlname, int idx)
11799 sprintf(name, "%s Playback Volume", ctlname);
11801 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11802 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11806 } else if (nid == 0x15) {
11807 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11808 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11814 sprintf(name, "%s Playback Switch", ctlname);
11815 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11816 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11822 /* add playback controls from the parsed DAC table */
11823 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11824 const struct auto_pin_cfg *cfg)
11829 spec->multiout.num_dacs = 2; /* only use one dac */
11830 spec->multiout.dac_nids = spec->private_dac_nids;
11831 spec->multiout.dac_nids[0] = 2;
11832 spec->multiout.dac_nids[1] = 3;
11834 nid = cfg->line_out_pins[0];
11836 alc268_new_analog_output(spec, nid, "Front", 0);
11838 nid = cfg->speaker_pins[0];
11840 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11841 "Speaker Playback Volume",
11842 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11846 nid = cfg->hp_pins[0];
11848 alc268_new_analog_output(spec, nid, "Headphone", 0);
11850 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11852 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11853 "Mono Playback Switch",
11854 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11861 /* create playback/capture controls for input pins */
11862 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11863 const struct auto_pin_cfg *cfg)
11865 struct hda_input_mux *imux = &spec->private_imux[0];
11868 for (i = 0; i < AUTO_PIN_LAST; i++) {
11869 switch(cfg->input_pins[i]) {
11871 idx1 = 0; /* Mic 1 */
11874 idx1 = 1; /* Mic 2 */
11877 idx1 = 2; /* Line In */
11884 idx1 = 6; /* digital mics */
11889 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11890 imux->items[imux->num_items].index = idx1;
11896 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11898 struct alc_spec *spec = codec->spec;
11899 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11900 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11901 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11902 unsigned int dac_vol1, dac_vol2;
11905 snd_hda_codec_write(codec, speaker_nid, 0,
11906 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11907 snd_hda_codec_write(codec, 0x0f, 0,
11908 AC_VERB_SET_AMP_GAIN_MUTE,
11910 snd_hda_codec_write(codec, 0x10, 0,
11911 AC_VERB_SET_AMP_GAIN_MUTE,
11914 snd_hda_codec_write(codec, 0x0f, 0,
11915 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11916 snd_hda_codec_write(codec, 0x10, 0,
11917 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11920 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11921 if (line_nid == 0x14)
11922 dac_vol2 = AMP_OUT_ZERO;
11923 else if (line_nid == 0x15)
11924 dac_vol1 = AMP_OUT_ZERO;
11925 if (hp_nid == 0x14)
11926 dac_vol2 = AMP_OUT_ZERO;
11927 else if (hp_nid == 0x15)
11928 dac_vol1 = AMP_OUT_ZERO;
11929 if (line_nid != 0x16 || hp_nid != 0x16 ||
11930 spec->autocfg.line_out_pins[1] != 0x16 ||
11931 spec->autocfg.line_out_pins[2] != 0x16)
11932 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11934 snd_hda_codec_write(codec, 0x02, 0,
11935 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11936 snd_hda_codec_write(codec, 0x03, 0,
11937 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11940 /* pcm configuration: identiacal with ALC880 */
11941 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11942 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11943 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11944 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11947 * BIOS auto configuration
11949 static int alc268_parse_auto_config(struct hda_codec *codec)
11951 struct alc_spec *spec = codec->spec;
11953 static hda_nid_t alc268_ignore[] = { 0 };
11955 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11959 if (!spec->autocfg.line_outs) {
11960 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11961 spec->multiout.max_channels = 2;
11962 spec->no_analog = 1;
11965 return 0; /* can't find valid BIOS pin config */
11967 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11970 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11974 spec->multiout.max_channels = 2;
11977 /* digital only support output */
11978 if (spec->autocfg.dig_outs) {
11979 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11980 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11982 if (spec->kctls.list)
11983 add_mixer(spec, spec->kctls.list);
11985 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
11986 add_mixer(spec, alc268_beep_mixer);
11988 add_verb(spec, alc268_volume_init_verbs);
11989 spec->num_mux_defs = 1;
11990 spec->input_mux = &spec->private_imux[0];
11992 err = alc_auto_add_mic_boost(codec);
11999 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12000 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12001 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12003 /* init callback for auto-configuration model -- overriding the default init */
12004 static void alc268_auto_init(struct hda_codec *codec)
12006 struct alc_spec *spec = codec->spec;
12007 alc268_auto_init_multi_out(codec);
12008 alc268_auto_init_hp_out(codec);
12009 alc268_auto_init_mono_speaker_out(codec);
12010 alc268_auto_init_analog_input(codec);
12011 if (spec->unsol_event)
12012 alc_inithook(codec);
12016 * configuration and preset
12018 static const char *alc268_models[ALC268_MODEL_LAST] = {
12019 [ALC267_QUANTA_IL1] = "quanta-il1",
12020 [ALC268_3ST] = "3stack",
12021 [ALC268_TOSHIBA] = "toshiba",
12022 [ALC268_ACER] = "acer",
12023 [ALC268_ACER_DMIC] = "acer-dmic",
12024 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12025 [ALC268_DELL] = "dell",
12026 [ALC268_ZEPTO] = "zepto",
12027 #ifdef CONFIG_SND_DEBUG
12028 [ALC268_TEST] = "test",
12030 [ALC268_AUTO] = "auto",
12033 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12034 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12035 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12036 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12037 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12038 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12039 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12040 ALC268_ACER_ASPIRE_ONE),
12041 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12042 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12043 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
12044 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12045 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
12046 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
12047 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
12048 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12049 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12050 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12051 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12055 static struct alc_config_preset alc268_presets[] = {
12056 [ALC267_QUANTA_IL1] = {
12057 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12058 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12059 alc267_quanta_il1_verbs },
12060 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12061 .dac_nids = alc268_dac_nids,
12062 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12063 .adc_nids = alc268_adc_nids_alt,
12065 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12066 .channel_mode = alc268_modes,
12067 .input_mux = &alc268_capture_source,
12068 .unsol_event = alc267_quanta_il1_unsol_event,
12069 .init_hook = alc267_quanta_il1_init_hook,
12072 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12073 alc268_beep_mixer },
12074 .init_verbs = { alc268_base_init_verbs },
12075 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12076 .dac_nids = alc268_dac_nids,
12077 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12078 .adc_nids = alc268_adc_nids_alt,
12079 .capsrc_nids = alc268_capsrc_nids,
12081 .dig_out_nid = ALC268_DIGOUT_NID,
12082 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12083 .channel_mode = alc268_modes,
12084 .input_mux = &alc268_capture_source,
12086 [ALC268_TOSHIBA] = {
12087 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12088 alc268_beep_mixer },
12089 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12090 alc268_toshiba_verbs },
12091 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12092 .dac_nids = alc268_dac_nids,
12093 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12094 .adc_nids = alc268_adc_nids_alt,
12095 .capsrc_nids = alc268_capsrc_nids,
12097 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12098 .channel_mode = alc268_modes,
12099 .input_mux = &alc268_capture_source,
12100 .unsol_event = alc268_toshiba_unsol_event,
12101 .init_hook = alc268_toshiba_init_hook,
12104 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12105 alc268_beep_mixer },
12106 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12107 alc268_acer_verbs },
12108 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12109 .dac_nids = alc268_dac_nids,
12110 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12111 .adc_nids = alc268_adc_nids_alt,
12112 .capsrc_nids = alc268_capsrc_nids,
12114 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12115 .channel_mode = alc268_modes,
12116 .input_mux = &alc268_acer_capture_source,
12117 .unsol_event = alc268_acer_unsol_event,
12118 .init_hook = alc268_acer_init_hook,
12120 [ALC268_ACER_DMIC] = {
12121 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12122 alc268_beep_mixer },
12123 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12124 alc268_acer_verbs },
12125 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12126 .dac_nids = alc268_dac_nids,
12127 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12128 .adc_nids = alc268_adc_nids_alt,
12129 .capsrc_nids = alc268_capsrc_nids,
12131 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12132 .channel_mode = alc268_modes,
12133 .input_mux = &alc268_acer_dmic_capture_source,
12134 .unsol_event = alc268_acer_unsol_event,
12135 .init_hook = alc268_acer_init_hook,
12137 [ALC268_ACER_ASPIRE_ONE] = {
12138 .mixers = { alc268_acer_aspire_one_mixer,
12140 alc268_capture_alt_mixer },
12141 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12142 alc268_acer_aspire_one_verbs },
12143 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12144 .dac_nids = alc268_dac_nids,
12145 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12146 .adc_nids = alc268_adc_nids_alt,
12147 .capsrc_nids = alc268_capsrc_nids,
12149 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12150 .channel_mode = alc268_modes,
12151 .input_mux = &alc268_acer_lc_capture_source,
12152 .unsol_event = alc268_acer_lc_unsol_event,
12153 .init_hook = alc268_acer_lc_init_hook,
12156 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12157 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12158 alc268_dell_verbs },
12159 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12160 .dac_nids = alc268_dac_nids,
12162 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12163 .channel_mode = alc268_modes,
12164 .unsol_event = alc_sku_unsol_event,
12165 .init_hook = alc268_dell_init_hook,
12166 .input_mux = &alc268_capture_source,
12169 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12170 alc268_beep_mixer },
12171 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12172 alc268_toshiba_verbs },
12173 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12174 .dac_nids = alc268_dac_nids,
12175 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12176 .adc_nids = alc268_adc_nids_alt,
12177 .capsrc_nids = alc268_capsrc_nids,
12179 .dig_out_nid = ALC268_DIGOUT_NID,
12180 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12181 .channel_mode = alc268_modes,
12182 .input_mux = &alc268_capture_source,
12183 .unsol_event = alc268_toshiba_unsol_event,
12184 .init_hook = alc268_toshiba_init_hook
12186 #ifdef CONFIG_SND_DEBUG
12188 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12189 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12190 alc268_volume_init_verbs },
12191 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12192 .dac_nids = alc268_dac_nids,
12193 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12194 .adc_nids = alc268_adc_nids_alt,
12195 .capsrc_nids = alc268_capsrc_nids,
12197 .dig_out_nid = ALC268_DIGOUT_NID,
12198 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12199 .channel_mode = alc268_modes,
12200 .input_mux = &alc268_capture_source,
12205 static int patch_alc268(struct hda_codec *codec)
12207 struct alc_spec *spec;
12209 int i, has_beep, err;
12211 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12215 codec->spec = spec;
12217 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12221 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12222 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12223 "trying auto-probe from BIOS...\n", codec->chip_name);
12224 board_config = ALC268_AUTO;
12227 if (board_config == ALC268_AUTO) {
12228 /* automatic parse from the BIOS config */
12229 err = alc268_parse_auto_config(codec);
12235 "hda_codec: Cannot set up configuration "
12236 "from BIOS. Using base mode...\n");
12237 board_config = ALC268_3ST;
12241 if (board_config != ALC268_AUTO)
12242 setup_preset(spec, &alc268_presets[board_config]);
12244 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12245 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12246 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12248 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12251 for (i = 0; i < spec->num_mixers; i++) {
12252 if (spec->mixers[i] == alc268_beep_mixer) {
12259 err = snd_hda_attach_beep_device(codec, 0x1);
12264 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12265 /* override the amp caps for beep generator */
12266 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12267 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12268 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12269 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12270 (0 << AC_AMPCAP_MUTE_SHIFT));
12273 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12274 /* check whether NID 0x07 is valid */
12275 unsigned int wcap = get_wcaps(codec, 0x07);
12279 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12280 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12281 spec->adc_nids = alc268_adc_nids_alt;
12282 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12283 add_mixer(spec, alc268_capture_alt_mixer);
12285 spec->adc_nids = alc268_adc_nids;
12286 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12287 add_mixer(spec, alc268_capture_mixer);
12289 spec->capsrc_nids = alc268_capsrc_nids;
12290 /* set default input source */
12291 for (i = 0; i < spec->num_adc_nids; i++)
12292 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12293 0, AC_VERB_SET_CONNECT_SEL,
12294 spec->input_mux->items[0].index);
12297 spec->vmaster_nid = 0x02;
12299 codec->patch_ops = alc_patch_ops;
12300 if (board_config == ALC268_AUTO)
12301 spec->init_hook = alc268_auto_init;
12303 codec->proc_widget_hook = print_realtek_coef;
12309 * ALC269 channel source setting (2 channel)
12311 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12313 #define alc269_dac_nids alc260_dac_nids
12315 static hda_nid_t alc269_adc_nids[1] = {
12320 static hda_nid_t alc269_capsrc_nids[1] = {
12324 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12328 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12336 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12344 #define alc269_modes alc260_modes
12345 #define alc269_capture_source alc880_lg_lw_capture_source
12347 static struct snd_kcontrol_new alc269_base_mixer[] = {
12348 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12349 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12350 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12351 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12352 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12354 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12355 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12356 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12357 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12358 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12359 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12363 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12364 /* output mixer control */
12365 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12367 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12368 .name = "Master Playback Switch",
12369 .info = snd_hda_mixer_amp_switch_info,
12370 .get = snd_hda_mixer_amp_switch_get,
12371 .put = alc268_acer_master_sw_put,
12372 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12374 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12375 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12376 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12377 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12378 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12379 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12383 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12384 /* output mixer control */
12385 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12388 .name = "Master Playback Switch",
12389 .info = snd_hda_mixer_amp_switch_info,
12390 .get = snd_hda_mixer_amp_switch_get,
12391 .put = alc268_acer_master_sw_put,
12392 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12395 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12396 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12397 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12398 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12399 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12400 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12401 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12402 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12406 /* bind volumes of both NID 0x0c and 0x0d */
12407 static struct hda_bind_ctls alc269_epc_bind_vol = {
12408 .ops = &snd_hda_bind_vol,
12410 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12411 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12416 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12417 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12418 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12419 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12423 /* capture mixer elements */
12424 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12425 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12426 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12432 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12433 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12434 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12435 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12439 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12440 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12441 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12444 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12445 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12449 static struct hda_verb alc269_lifebook_verbs[] = {
12450 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12451 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12454 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12455 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12457 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12458 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12459 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12463 /* toggle speaker-output according to the hp-jack state */
12464 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12466 unsigned int present;
12467 unsigned char bits;
12469 present = snd_hda_codec_read(codec, 0x15, 0,
12470 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12471 bits = present ? AMP_IN_MUTE(0) : 0;
12472 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12473 AMP_IN_MUTE(0), bits);
12474 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12475 AMP_IN_MUTE(0), bits);
12477 snd_hda_codec_write(codec, 0x20, 0,
12478 AC_VERB_SET_COEF_INDEX, 0x0c);
12479 snd_hda_codec_write(codec, 0x20, 0,
12480 AC_VERB_SET_PROC_COEF, 0x680);
12482 snd_hda_codec_write(codec, 0x20, 0,
12483 AC_VERB_SET_COEF_INDEX, 0x0c);
12484 snd_hda_codec_write(codec, 0x20, 0,
12485 AC_VERB_SET_PROC_COEF, 0x480);
12488 /* toggle speaker-output according to the hp-jacks state */
12489 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12491 unsigned int present;
12492 unsigned char bits;
12494 /* Check laptop headphone socket */
12495 present = snd_hda_codec_read(codec, 0x15, 0,
12496 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12498 /* Check port replicator headphone socket */
12499 present |= snd_hda_codec_read(codec, 0x1a, 0,
12500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12502 bits = present ? AMP_IN_MUTE(0) : 0;
12503 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12504 AMP_IN_MUTE(0), bits);
12505 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12506 AMP_IN_MUTE(0), bits);
12508 snd_hda_codec_write(codec, 0x20, 0,
12509 AC_VERB_SET_COEF_INDEX, 0x0c);
12510 snd_hda_codec_write(codec, 0x20, 0,
12511 AC_VERB_SET_PROC_COEF, 0x680);
12513 snd_hda_codec_write(codec, 0x20, 0,
12514 AC_VERB_SET_COEF_INDEX, 0x0c);
12515 snd_hda_codec_write(codec, 0x20, 0,
12516 AC_VERB_SET_PROC_COEF, 0x480);
12519 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12521 unsigned int present;
12523 present = snd_hda_codec_read(codec, 0x18, 0,
12524 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12525 snd_hda_codec_write(codec, 0x23, 0,
12526 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12529 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12531 unsigned int present_laptop;
12532 unsigned int present_dock;
12534 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12535 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12537 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12538 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12540 /* Laptop mic port overrides dock mic port, design decision */
12542 snd_hda_codec_write(codec, 0x23, 0,
12543 AC_VERB_SET_CONNECT_SEL, 0x3);
12544 if (present_laptop)
12545 snd_hda_codec_write(codec, 0x23, 0,
12546 AC_VERB_SET_CONNECT_SEL, 0x0);
12547 if (!present_dock && !present_laptop)
12548 snd_hda_codec_write(codec, 0x23, 0,
12549 AC_VERB_SET_CONNECT_SEL, 0x1);
12552 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12555 if ((res >> 26) == ALC880_HP_EVENT)
12556 alc269_quanta_fl1_speaker_automute(codec);
12557 if ((res >> 26) == ALC880_MIC_EVENT)
12558 alc269_quanta_fl1_mic_automute(codec);
12561 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12564 if ((res >> 26) == ALC880_HP_EVENT)
12565 alc269_lifebook_speaker_automute(codec);
12566 if ((res >> 26) == ALC880_MIC_EVENT)
12567 alc269_lifebook_mic_autoswitch(codec);
12570 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12572 alc269_quanta_fl1_speaker_automute(codec);
12573 alc269_quanta_fl1_mic_automute(codec);
12576 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12578 alc269_lifebook_speaker_automute(codec);
12579 alc269_lifebook_mic_autoswitch(codec);
12582 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12583 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12584 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12585 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12586 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12587 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12588 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12589 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12593 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12594 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12595 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12596 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12597 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12598 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12599 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12603 /* toggle speaker-output according to the hp-jack state */
12604 static void alc269_speaker_automute(struct hda_codec *codec)
12606 unsigned int present;
12607 unsigned char bits;
12609 present = snd_hda_codec_read(codec, 0x15, 0,
12610 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12611 bits = present ? AMP_IN_MUTE(0) : 0;
12612 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12613 AMP_IN_MUTE(0), bits);
12614 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12615 AMP_IN_MUTE(0), bits);
12618 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12620 unsigned int present;
12622 present = snd_hda_codec_read(codec, 0x18, 0,
12623 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12624 snd_hda_codec_write(codec, 0x23, 0,
12625 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12628 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12630 unsigned int present;
12632 present = snd_hda_codec_read(codec, 0x18, 0,
12633 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12634 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12635 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12636 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12637 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12640 /* unsolicited event for HP jack sensing */
12641 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12644 if ((res >> 26) == ALC880_HP_EVENT)
12645 alc269_speaker_automute(codec);
12647 if ((res >> 26) == ALC880_MIC_EVENT)
12648 alc269_eeepc_dmic_automute(codec);
12651 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12653 alc269_speaker_automute(codec);
12654 alc269_eeepc_dmic_automute(codec);
12657 /* unsolicited event for HP jack sensing */
12658 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12661 if ((res >> 26) == ALC880_HP_EVENT)
12662 alc269_speaker_automute(codec);
12664 if ((res >> 26) == ALC880_MIC_EVENT)
12665 alc269_eeepc_amic_automute(codec);
12668 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12670 alc269_speaker_automute(codec);
12671 alc269_eeepc_amic_automute(codec);
12675 * generic initialization of ADC, input mixers and output mixers
12677 static struct hda_verb alc269_init_verbs[] = {
12679 * Unmute ADC0 and set the default input to mic-in
12681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12683 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12684 * analog-loopback mixer widget
12685 * Note: PASD motherboards uses the Line In 2 as the input for
12686 * front panel mic (mic 2)
12688 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12696 * Set up output mixers (0x0c - 0x0e)
12698 /* set vol=0 to output mixers */
12699 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12700 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12702 /* set up input amps for analog loopback */
12703 /* Amp Indices: DAC = 0, mixer = 1 */
12704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12706 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12707 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12708 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12709 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12711 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12712 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12713 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12714 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12716 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12717 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12719 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12720 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12721 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12722 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12723 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12724 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12725 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12727 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12728 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12730 /* FIXME: use matrix-type input source selection */
12731 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12732 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12733 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12739 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12740 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12744 /* add playback controls from the parsed DAC table */
12745 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12746 const struct auto_pin_cfg *cfg)
12751 spec->multiout.num_dacs = 1; /* only use one dac */
12752 spec->multiout.dac_nids = spec->private_dac_nids;
12753 spec->multiout.dac_nids[0] = 2;
12755 nid = cfg->line_out_pins[0];
12757 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12758 "Front Playback Volume",
12759 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12762 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12763 "Front Playback Switch",
12764 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12769 nid = cfg->speaker_pins[0];
12771 if (!cfg->line_out_pins[0]) {
12772 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12773 "Speaker Playback Volume",
12774 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12780 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12781 "Speaker Playback Switch",
12782 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12787 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12788 "Speaker Playback Switch",
12789 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12795 nid = cfg->hp_pins[0];
12797 /* spec->multiout.hp_nid = 2; */
12798 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12799 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12800 "Headphone Playback Volume",
12801 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12807 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12808 "Headphone Playback Switch",
12809 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12814 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12815 "Headphone Playback Switch",
12816 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12825 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12826 const struct auto_pin_cfg *cfg)
12830 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12833 /* digital-mic input pin is excluded in alc880_auto_create..()
12834 * because it's under 0x18
12836 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12837 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12838 struct hda_input_mux *imux = &spec->private_imux[0];
12839 imux->items[imux->num_items].label = "Int Mic";
12840 imux->items[imux->num_items].index = 0x05;
12846 #ifdef CONFIG_SND_HDA_POWER_SAVE
12847 #define alc269_loopbacks alc880_loopbacks
12850 /* pcm configuration: identiacal with ALC880 */
12851 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12852 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12853 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12854 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12856 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12860 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12861 /* NID is set in alc_build_pcms */
12863 .open = alc880_playback_pcm_open,
12864 .prepare = alc880_playback_pcm_prepare,
12865 .cleanup = alc880_playback_pcm_cleanup
12869 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12873 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12874 /* NID is set in alc_build_pcms */
12878 * BIOS auto configuration
12880 static int alc269_parse_auto_config(struct hda_codec *codec)
12882 struct alc_spec *spec = codec->spec;
12884 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12886 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12891 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12894 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12898 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12900 if (spec->autocfg.dig_outs)
12901 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12903 if (spec->kctls.list)
12904 add_mixer(spec, spec->kctls.list);
12906 add_verb(spec, alc269_init_verbs);
12907 spec->num_mux_defs = 1;
12908 spec->input_mux = &spec->private_imux[0];
12909 /* set default input source */
12910 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12911 0, AC_VERB_SET_CONNECT_SEL,
12912 spec->input_mux->items[0].index);
12914 err = alc_auto_add_mic_boost(codec);
12918 if (!spec->cap_mixer && !spec->no_analog)
12919 set_capture_mixer(spec);
12924 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12925 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12926 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12929 /* init callback for auto-configuration model -- overriding the default init */
12930 static void alc269_auto_init(struct hda_codec *codec)
12932 struct alc_spec *spec = codec->spec;
12933 alc269_auto_init_multi_out(codec);
12934 alc269_auto_init_hp_out(codec);
12935 alc269_auto_init_analog_input(codec);
12936 if (spec->unsol_event)
12937 alc_inithook(codec);
12941 * configuration and preset
12943 static const char *alc269_models[ALC269_MODEL_LAST] = {
12944 [ALC269_BASIC] = "basic",
12945 [ALC269_QUANTA_FL1] = "quanta",
12946 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12947 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12948 [ALC269_FUJITSU] = "fujitsu",
12949 [ALC269_LIFEBOOK] = "lifebook"
12952 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12953 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12954 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12955 ALC269_ASUS_EEEPC_P703),
12956 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12957 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12958 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12959 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12960 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12961 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12962 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12963 ALC269_ASUS_EEEPC_P901),
12964 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12965 ALC269_ASUS_EEEPC_P901),
12966 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12967 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12968 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12972 static struct alc_config_preset alc269_presets[] = {
12974 .mixers = { alc269_base_mixer },
12975 .init_verbs = { alc269_init_verbs },
12976 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12977 .dac_nids = alc269_dac_nids,
12979 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12980 .channel_mode = alc269_modes,
12981 .input_mux = &alc269_capture_source,
12983 [ALC269_QUANTA_FL1] = {
12984 .mixers = { alc269_quanta_fl1_mixer },
12985 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12986 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12987 .dac_nids = alc269_dac_nids,
12989 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12990 .channel_mode = alc269_modes,
12991 .input_mux = &alc269_capture_source,
12992 .unsol_event = alc269_quanta_fl1_unsol_event,
12993 .init_hook = alc269_quanta_fl1_init_hook,
12995 [ALC269_ASUS_EEEPC_P703] = {
12996 .mixers = { alc269_eeepc_mixer },
12997 .cap_mixer = alc269_epc_capture_mixer,
12998 .init_verbs = { alc269_init_verbs,
12999 alc269_eeepc_amic_init_verbs },
13000 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13001 .dac_nids = alc269_dac_nids,
13003 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13004 .channel_mode = alc269_modes,
13005 .input_mux = &alc269_eeepc_amic_capture_source,
13006 .unsol_event = alc269_eeepc_amic_unsol_event,
13007 .init_hook = alc269_eeepc_amic_inithook,
13009 [ALC269_ASUS_EEEPC_P901] = {
13010 .mixers = { alc269_eeepc_mixer },
13011 .cap_mixer = alc269_epc_capture_mixer,
13012 .init_verbs = { alc269_init_verbs,
13013 alc269_eeepc_dmic_init_verbs },
13014 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13015 .dac_nids = alc269_dac_nids,
13017 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13018 .channel_mode = alc269_modes,
13019 .input_mux = &alc269_eeepc_dmic_capture_source,
13020 .unsol_event = alc269_eeepc_dmic_unsol_event,
13021 .init_hook = alc269_eeepc_dmic_inithook,
13023 [ALC269_FUJITSU] = {
13024 .mixers = { alc269_fujitsu_mixer },
13025 .cap_mixer = alc269_epc_capture_mixer,
13026 .init_verbs = { alc269_init_verbs,
13027 alc269_eeepc_dmic_init_verbs },
13028 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13029 .dac_nids = alc269_dac_nids,
13031 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13032 .channel_mode = alc269_modes,
13033 .input_mux = &alc269_eeepc_dmic_capture_source,
13034 .unsol_event = alc269_eeepc_dmic_unsol_event,
13035 .init_hook = alc269_eeepc_dmic_inithook,
13037 [ALC269_LIFEBOOK] = {
13038 .mixers = { alc269_lifebook_mixer },
13039 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13040 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13041 .dac_nids = alc269_dac_nids,
13043 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13044 .channel_mode = alc269_modes,
13045 .input_mux = &alc269_capture_source,
13046 .unsol_event = alc269_lifebook_unsol_event,
13047 .init_hook = alc269_lifebook_init_hook,
13051 static int patch_alc269(struct hda_codec *codec)
13053 struct alc_spec *spec;
13057 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13061 codec->spec = spec;
13063 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13065 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13069 if (board_config < 0) {
13070 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13071 "trying auto-probe from BIOS...\n", codec->chip_name);
13072 board_config = ALC269_AUTO;
13075 if (board_config == ALC269_AUTO) {
13076 /* automatic parse from the BIOS config */
13077 err = alc269_parse_auto_config(codec);
13083 "hda_codec: Cannot set up configuration "
13084 "from BIOS. Using base mode...\n");
13085 board_config = ALC269_BASIC;
13089 err = snd_hda_attach_beep_device(codec, 0x1);
13095 if (board_config != ALC269_AUTO)
13096 setup_preset(spec, &alc269_presets[board_config]);
13098 if (codec->subsystem_id == 0x17aa3bf8) {
13099 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13100 * fix the sample rate of analog I/O to 44.1kHz
13102 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13103 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13105 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13106 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13108 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13109 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13111 spec->adc_nids = alc269_adc_nids;
13112 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13113 spec->capsrc_nids = alc269_capsrc_nids;
13114 if (!spec->cap_mixer)
13115 set_capture_mixer(spec);
13116 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13118 codec->patch_ops = alc_patch_ops;
13119 if (board_config == ALC269_AUTO)
13120 spec->init_hook = alc269_auto_init;
13121 #ifdef CONFIG_SND_HDA_POWER_SAVE
13122 if (!spec->loopback.amplist)
13123 spec->loopback.amplist = alc269_loopbacks;
13125 codec->proc_widget_hook = print_realtek_coef;
13131 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13135 * set the path ways for 2 channel output
13136 * need to set the codec line out and mic 1 pin widgets to inputs
13138 static struct hda_verb alc861_threestack_ch2_init[] = {
13139 /* set pin widget 1Ah (line in) for input */
13140 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13141 /* set pin widget 18h (mic1/2) for input, for mic also enable
13144 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13146 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13148 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13149 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13155 * need to set the codec line out and mic 1 pin widgets to outputs
13157 static struct hda_verb alc861_threestack_ch6_init[] = {
13158 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13159 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13160 /* set pin widget 18h (mic1) for output (CLFE)*/
13161 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13163 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13164 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13166 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13168 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13169 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13174 static struct hda_channel_mode alc861_threestack_modes[2] = {
13175 { 2, alc861_threestack_ch2_init },
13176 { 6, alc861_threestack_ch6_init },
13178 /* Set mic1 as input and unmute the mixer */
13179 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13180 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13181 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13184 /* Set mic1 as output and mute mixer */
13185 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13186 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13187 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13191 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13192 { 2, alc861_uniwill_m31_ch2_init },
13193 { 4, alc861_uniwill_m31_ch4_init },
13196 /* Set mic1 and line-in as input and unmute the mixer */
13197 static struct hda_verb alc861_asus_ch2_init[] = {
13198 /* set pin widget 1Ah (line in) for input */
13199 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13200 /* set pin widget 18h (mic1/2) for input, for mic also enable
13203 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13205 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13207 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13208 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13212 /* Set mic1 nad line-in as output and mute mixer */
13213 static struct hda_verb alc861_asus_ch6_init[] = {
13214 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13215 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13216 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13217 /* set pin widget 18h (mic1) for output (CLFE)*/
13218 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13219 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13220 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13221 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13223 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13225 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13226 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13231 static struct hda_channel_mode alc861_asus_modes[2] = {
13232 { 2, alc861_asus_ch2_init },
13233 { 6, alc861_asus_ch6_init },
13238 static struct snd_kcontrol_new alc861_base_mixer[] = {
13239 /* output mixer control */
13240 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13241 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13242 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13243 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13244 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13246 /*Input mixer control */
13247 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13248 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13249 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13250 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13251 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13252 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13254 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13255 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13256 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13261 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13262 /* output mixer control */
13263 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13264 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13265 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13266 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13267 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13269 /* Input mixer control */
13270 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13271 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13272 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13273 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13274 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13275 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13277 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13278 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13279 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13282 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13283 .name = "Channel Mode",
13284 .info = alc_ch_mode_info,
13285 .get = alc_ch_mode_get,
13286 .put = alc_ch_mode_put,
13287 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13292 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13293 /* output mixer control */
13294 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13295 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13296 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13301 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13302 /* output mixer control */
13303 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13304 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13305 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13306 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13307 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13309 /* Input mixer control */
13310 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13311 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13312 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13313 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13314 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13315 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13316 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13317 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13318 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13319 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13323 .name = "Channel Mode",
13324 .info = alc_ch_mode_info,
13325 .get = alc_ch_mode_get,
13326 .put = alc_ch_mode_put,
13327 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13332 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13333 /* output mixer control */
13334 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13335 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13336 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13337 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13338 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13340 /* Input mixer control */
13341 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13342 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13343 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13344 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13345 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13346 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13348 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13349 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13353 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13354 .name = "Channel Mode",
13355 .info = alc_ch_mode_info,
13356 .get = alc_ch_mode_get,
13357 .put = alc_ch_mode_put,
13358 .private_value = ARRAY_SIZE(alc861_asus_modes),
13363 /* additional mixer */
13364 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13365 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13366 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13371 * generic initialization of ADC, input mixers and output mixers
13373 static struct hda_verb alc861_base_init_verbs[] = {
13375 * Unmute ADC0 and set the default input to mic-in
13377 /* port-A for surround (rear panel) */
13378 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13379 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13380 /* port-B for mic-in (rear panel) with vref */
13381 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13382 /* port-C for line-in (rear panel) */
13383 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13384 /* port-D for Front */
13385 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13386 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13387 /* port-E for HP out (front panel) */
13388 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13389 /* route front PCM to HP */
13390 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13391 /* port-F for mic-in (front panel) with vref */
13392 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13393 /* port-G for CLFE (rear panel) */
13394 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13395 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13396 /* port-H for side (rear panel) */
13397 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13398 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13400 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13401 /* route front mic to ADC1*/
13402 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13405 /* Unmute DAC0~3 & spdif out*/
13406 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13407 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13408 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13409 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13412 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13413 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13414 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13415 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13416 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13418 /* Unmute Stereo Mixer 15 */
13419 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13420 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13424 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13425 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13426 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13427 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13428 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13429 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13430 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13431 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13432 /* hp used DAC 3 (Front) */
13433 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13434 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13439 static struct hda_verb alc861_threestack_init_verbs[] = {
13441 * Unmute ADC0 and set the default input to mic-in
13443 /* port-A for surround (rear panel) */
13444 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13445 /* port-B for mic-in (rear panel) with vref */
13446 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13447 /* port-C for line-in (rear panel) */
13448 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13449 /* port-D for Front */
13450 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13451 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13452 /* port-E for HP out (front panel) */
13453 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13454 /* route front PCM to HP */
13455 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13456 /* port-F for mic-in (front panel) with vref */
13457 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13458 /* port-G for CLFE (rear panel) */
13459 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13460 /* port-H for side (rear panel) */
13461 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13463 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13464 /* route front mic to ADC1*/
13465 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13466 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13467 /* Unmute DAC0~3 & spdif out*/
13468 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13469 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13470 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13471 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13472 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13474 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13475 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13476 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13477 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13478 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13480 /* Unmute Stereo Mixer 15 */
13481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13482 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13483 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13484 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13486 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13487 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13488 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13490 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13491 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13492 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13493 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13494 /* hp used DAC 3 (Front) */
13495 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13496 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13500 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13502 * Unmute ADC0 and set the default input to mic-in
13504 /* port-A for surround (rear panel) */
13505 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13506 /* port-B for mic-in (rear panel) with vref */
13507 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13508 /* port-C for line-in (rear panel) */
13509 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13510 /* port-D for Front */
13511 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13512 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13513 /* port-E for HP out (front panel) */
13514 /* this has to be set to VREF80 */
13515 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13516 /* route front PCM to HP */
13517 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13518 /* port-F for mic-in (front panel) with vref */
13519 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13520 /* port-G for CLFE (rear panel) */
13521 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13522 /* port-H for side (rear panel) */
13523 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13525 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13526 /* route front mic to ADC1*/
13527 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13528 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13529 /* Unmute DAC0~3 & spdif out*/
13530 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13531 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13532 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13533 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13536 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13537 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13538 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13539 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13540 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13542 /* Unmute Stereo Mixer 15 */
13543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13544 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13548 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13549 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13550 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13551 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13552 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13554 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13556 /* hp used DAC 3 (Front) */
13557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13558 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13562 static struct hda_verb alc861_asus_init_verbs[] = {
13564 * Unmute ADC0 and set the default input to mic-in
13566 /* port-A for surround (rear panel)
13567 * according to codec#0 this is the HP jack
13569 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13570 /* route front PCM to HP */
13571 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13572 /* port-B for mic-in (rear panel) with vref */
13573 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13574 /* port-C for line-in (rear panel) */
13575 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13576 /* port-D for Front */
13577 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13578 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13579 /* port-E for HP out (front panel) */
13580 /* this has to be set to VREF80 */
13581 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13582 /* route front PCM to HP */
13583 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13584 /* port-F for mic-in (front panel) with vref */
13585 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13586 /* port-G for CLFE (rear panel) */
13587 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13588 /* port-H for side (rear panel) */
13589 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13591 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13592 /* route front mic to ADC1*/
13593 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13594 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13595 /* Unmute DAC0~3 & spdif out*/
13596 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13597 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13598 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13599 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13601 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13602 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13603 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13604 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13605 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13607 /* Unmute Stereo Mixer 15 */
13608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13613 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13614 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13615 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13616 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13617 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13618 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13619 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13620 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13621 /* hp used DAC 3 (Front) */
13622 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13627 /* additional init verbs for ASUS laptops */
13628 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13629 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13630 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13635 * generic initialization of ADC, input mixers and output mixers
13637 static struct hda_verb alc861_auto_init_verbs[] = {
13639 * Unmute ADC0 and set the default input to mic-in
13641 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13642 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13644 /* Unmute DAC0~3 & spdif out*/
13645 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13646 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13647 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13648 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13649 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13651 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13652 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13653 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13654 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13655 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13657 /* Unmute Stereo Mixer 15 */
13658 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13659 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13663 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13664 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13665 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13666 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13667 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13668 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13669 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13672 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13673 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13674 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13676 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13677 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13678 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13679 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13681 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13686 static struct hda_verb alc861_toshiba_init_verbs[] = {
13687 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13692 /* toggle speaker-output according to the hp-jack state */
13693 static void alc861_toshiba_automute(struct hda_codec *codec)
13695 unsigned int present;
13697 present = snd_hda_codec_read(codec, 0x0f, 0,
13698 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13699 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13700 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13701 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13702 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13705 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13708 if ((res >> 26) == ALC880_HP_EVENT)
13709 alc861_toshiba_automute(codec);
13712 /* pcm configuration: identiacal with ALC880 */
13713 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13714 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13715 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13716 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13719 #define ALC861_DIGOUT_NID 0x07
13721 static struct hda_channel_mode alc861_8ch_modes[1] = {
13725 static hda_nid_t alc861_dac_nids[4] = {
13726 /* front, surround, clfe, side */
13727 0x03, 0x06, 0x05, 0x04
13730 static hda_nid_t alc660_dac_nids[3] = {
13731 /* front, clfe, surround */
13735 static hda_nid_t alc861_adc_nids[1] = {
13740 static struct hda_input_mux alc861_capture_source = {
13744 { "Front Mic", 0x3 },
13751 /* fill in the dac_nids table from the parsed pin configuration */
13752 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13753 const struct auto_pin_cfg *cfg)
13758 spec->multiout.dac_nids = spec->private_dac_nids;
13759 for (i = 0; i < cfg->line_outs; i++) {
13760 nid = cfg->line_out_pins[i];
13762 if (i >= ARRAY_SIZE(alc861_dac_nids))
13764 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13767 spec->multiout.num_dacs = cfg->line_outs;
13771 /* add playback controls from the parsed DAC table */
13772 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13773 const struct auto_pin_cfg *cfg)
13776 static const char *chname[4] = {
13777 "Front", "Surround", NULL /*CLFE*/, "Side"
13782 for (i = 0; i < cfg->line_outs; i++) {
13783 nid = spec->multiout.dac_nids[i];
13788 err = add_control(spec, ALC_CTL_BIND_MUTE,
13789 "Center Playback Switch",
13790 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13794 err = add_control(spec, ALC_CTL_BIND_MUTE,
13795 "LFE Playback Switch",
13796 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13801 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13803 if (nid == alc861_dac_nids[idx])
13805 sprintf(name, "%s Playback Switch", chname[idx]);
13806 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13807 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13816 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13824 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13826 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13827 "Headphone Playback Switch",
13828 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13831 spec->multiout.hp_nid = nid;
13836 /* create playback/capture controls for input pins */
13837 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13838 const struct auto_pin_cfg *cfg)
13840 struct hda_input_mux *imux = &spec->private_imux[0];
13841 int i, err, idx, idx1;
13843 for (i = 0; i < AUTO_PIN_LAST; i++) {
13844 switch (cfg->input_pins[i]) {
13847 idx = 2; /* Line In */
13851 idx = 2; /* Line In */
13855 idx = 1; /* Mic In */
13859 idx = 1; /* Mic In */
13869 err = new_analog_input(spec, cfg->input_pins[i],
13870 auto_pin_cfg_labels[i], idx, 0x15);
13874 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13875 imux->items[imux->num_items].index = idx1;
13881 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13883 int pin_type, int dac_idx)
13885 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13887 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13891 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13893 struct alc_spec *spec = codec->spec;
13896 for (i = 0; i < spec->autocfg.line_outs; i++) {
13897 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13898 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13900 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13901 spec->multiout.dac_nids[i]);
13905 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13907 struct alc_spec *spec = codec->spec;
13910 pin = spec->autocfg.hp_pins[0];
13911 if (pin) /* connect to front */
13912 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13913 spec->multiout.dac_nids[0]);
13914 pin = spec->autocfg.speaker_pins[0];
13916 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13919 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13921 struct alc_spec *spec = codec->spec;
13924 for (i = 0; i < AUTO_PIN_LAST; i++) {
13925 hda_nid_t nid = spec->autocfg.input_pins[i];
13926 if (nid >= 0x0c && nid <= 0x11)
13927 alc_set_input_pin(codec, nid, i);
13931 /* parse the BIOS configuration and set up the alc_spec */
13932 /* return 1 if successful, 0 if the proper config is not found,
13933 * or a negative error code
13935 static int alc861_parse_auto_config(struct hda_codec *codec)
13937 struct alc_spec *spec = codec->spec;
13939 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13941 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13945 if (!spec->autocfg.line_outs)
13946 return 0; /* can't find valid BIOS pin config */
13948 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13951 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13954 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13957 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13961 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13963 if (spec->autocfg.dig_outs)
13964 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13966 if (spec->kctls.list)
13967 add_mixer(spec, spec->kctls.list);
13969 add_verb(spec, alc861_auto_init_verbs);
13971 spec->num_mux_defs = 1;
13972 spec->input_mux = &spec->private_imux[0];
13974 spec->adc_nids = alc861_adc_nids;
13975 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13976 set_capture_mixer(spec);
13978 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
13983 /* additional initialization for auto-configuration model */
13984 static void alc861_auto_init(struct hda_codec *codec)
13986 struct alc_spec *spec = codec->spec;
13987 alc861_auto_init_multi_out(codec);
13988 alc861_auto_init_hp_out(codec);
13989 alc861_auto_init_analog_input(codec);
13990 if (spec->unsol_event)
13991 alc_inithook(codec);
13994 #ifdef CONFIG_SND_HDA_POWER_SAVE
13995 static struct hda_amp_list alc861_loopbacks[] = {
13996 { 0x15, HDA_INPUT, 0 },
13997 { 0x15, HDA_INPUT, 1 },
13998 { 0x15, HDA_INPUT, 2 },
13999 { 0x15, HDA_INPUT, 3 },
14006 * configuration and preset
14008 static const char *alc861_models[ALC861_MODEL_LAST] = {
14009 [ALC861_3ST] = "3stack",
14010 [ALC660_3ST] = "3stack-660",
14011 [ALC861_3ST_DIG] = "3stack-dig",
14012 [ALC861_6ST_DIG] = "6stack-dig",
14013 [ALC861_UNIWILL_M31] = "uniwill-m31",
14014 [ALC861_TOSHIBA] = "toshiba",
14015 [ALC861_ASUS] = "asus",
14016 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14017 [ALC861_AUTO] = "auto",
14020 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14021 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14022 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14023 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14024 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14025 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14026 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14027 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14028 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14029 * Any other models that need this preset?
14031 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14032 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14033 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14034 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14035 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14036 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14037 /* FIXME: the below seems conflict */
14038 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14039 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14040 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14044 static struct alc_config_preset alc861_presets[] = {
14046 .mixers = { alc861_3ST_mixer },
14047 .init_verbs = { alc861_threestack_init_verbs },
14048 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14049 .dac_nids = alc861_dac_nids,
14050 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14051 .channel_mode = alc861_threestack_modes,
14053 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14054 .adc_nids = alc861_adc_nids,
14055 .input_mux = &alc861_capture_source,
14057 [ALC861_3ST_DIG] = {
14058 .mixers = { alc861_base_mixer },
14059 .init_verbs = { alc861_threestack_init_verbs },
14060 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14061 .dac_nids = alc861_dac_nids,
14062 .dig_out_nid = ALC861_DIGOUT_NID,
14063 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14064 .channel_mode = alc861_threestack_modes,
14066 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14067 .adc_nids = alc861_adc_nids,
14068 .input_mux = &alc861_capture_source,
14070 [ALC861_6ST_DIG] = {
14071 .mixers = { alc861_base_mixer },
14072 .init_verbs = { alc861_base_init_verbs },
14073 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14074 .dac_nids = alc861_dac_nids,
14075 .dig_out_nid = ALC861_DIGOUT_NID,
14076 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14077 .channel_mode = alc861_8ch_modes,
14078 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14079 .adc_nids = alc861_adc_nids,
14080 .input_mux = &alc861_capture_source,
14083 .mixers = { alc861_3ST_mixer },
14084 .init_verbs = { alc861_threestack_init_verbs },
14085 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14086 .dac_nids = alc660_dac_nids,
14087 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14088 .channel_mode = alc861_threestack_modes,
14090 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14091 .adc_nids = alc861_adc_nids,
14092 .input_mux = &alc861_capture_source,
14094 [ALC861_UNIWILL_M31] = {
14095 .mixers = { alc861_uniwill_m31_mixer },
14096 .init_verbs = { alc861_uniwill_m31_init_verbs },
14097 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14098 .dac_nids = alc861_dac_nids,
14099 .dig_out_nid = ALC861_DIGOUT_NID,
14100 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14101 .channel_mode = alc861_uniwill_m31_modes,
14103 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14104 .adc_nids = alc861_adc_nids,
14105 .input_mux = &alc861_capture_source,
14107 [ALC861_TOSHIBA] = {
14108 .mixers = { alc861_toshiba_mixer },
14109 .init_verbs = { alc861_base_init_verbs,
14110 alc861_toshiba_init_verbs },
14111 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14112 .dac_nids = alc861_dac_nids,
14113 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14114 .channel_mode = alc883_3ST_2ch_modes,
14115 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14116 .adc_nids = alc861_adc_nids,
14117 .input_mux = &alc861_capture_source,
14118 .unsol_event = alc861_toshiba_unsol_event,
14119 .init_hook = alc861_toshiba_automute,
14122 .mixers = { alc861_asus_mixer },
14123 .init_verbs = { alc861_asus_init_verbs },
14124 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14125 .dac_nids = alc861_dac_nids,
14126 .dig_out_nid = ALC861_DIGOUT_NID,
14127 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14128 .channel_mode = alc861_asus_modes,
14131 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14132 .adc_nids = alc861_adc_nids,
14133 .input_mux = &alc861_capture_source,
14135 [ALC861_ASUS_LAPTOP] = {
14136 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14137 .init_verbs = { alc861_asus_init_verbs,
14138 alc861_asus_laptop_init_verbs },
14139 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14140 .dac_nids = alc861_dac_nids,
14141 .dig_out_nid = ALC861_DIGOUT_NID,
14142 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14143 .channel_mode = alc883_3ST_2ch_modes,
14145 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14146 .adc_nids = alc861_adc_nids,
14147 .input_mux = &alc861_capture_source,
14152 static int patch_alc861(struct hda_codec *codec)
14154 struct alc_spec *spec;
14158 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14162 codec->spec = spec;
14164 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14168 if (board_config < 0) {
14169 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14170 "trying auto-probe from BIOS...\n", codec->chip_name);
14171 board_config = ALC861_AUTO;
14174 if (board_config == ALC861_AUTO) {
14175 /* automatic parse from the BIOS config */
14176 err = alc861_parse_auto_config(codec);
14182 "hda_codec: Cannot set up configuration "
14183 "from BIOS. Using base mode...\n");
14184 board_config = ALC861_3ST_DIG;
14188 err = snd_hda_attach_beep_device(codec, 0x23);
14194 if (board_config != ALC861_AUTO)
14195 setup_preset(spec, &alc861_presets[board_config]);
14197 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14198 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14200 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14201 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14203 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14205 spec->vmaster_nid = 0x03;
14207 codec->patch_ops = alc_patch_ops;
14208 if (board_config == ALC861_AUTO)
14209 spec->init_hook = alc861_auto_init;
14210 #ifdef CONFIG_SND_HDA_POWER_SAVE
14211 if (!spec->loopback.amplist)
14212 spec->loopback.amplist = alc861_loopbacks;
14214 codec->proc_widget_hook = print_realtek_coef;
14220 * ALC861-VD support
14224 * In addition, an independent DAC
14226 #define ALC861VD_DIGOUT_NID 0x06
14228 static hda_nid_t alc861vd_dac_nids[4] = {
14229 /* front, surr, clfe, side surr */
14230 0x02, 0x03, 0x04, 0x05
14233 /* dac_nids for ALC660vd are in a different order - according to
14234 * Realtek's driver.
14235 * This should probably tesult in a different mixer for 6stack models
14236 * of ALC660vd codecs, but for now there is only 3stack mixer
14237 * - and it is the same as in 861vd.
14238 * adc_nids in ALC660vd are (is) the same as in 861vd
14240 static hda_nid_t alc660vd_dac_nids[3] = {
14241 /* front, rear, clfe, rear_surr */
14245 static hda_nid_t alc861vd_adc_nids[1] = {
14250 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14253 /* FIXME: should be a matrix-type input source selection */
14254 static struct hda_input_mux alc861vd_capture_source = {
14258 { "Front Mic", 0x1 },
14264 static struct hda_input_mux alc861vd_dallas_capture_source = {
14267 { "Ext Mic", 0x0 },
14268 { "Int Mic", 0x1 },
14272 static struct hda_input_mux alc861vd_hp_capture_source = {
14275 { "Front Mic", 0x0 },
14276 { "ATAPI Mic", 0x1 },
14283 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14290 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14291 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14292 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14293 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14294 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14301 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14302 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14303 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14304 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14305 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14309 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14310 { 6, alc861vd_6stack_ch6_init },
14311 { 8, alc861vd_6stack_ch8_init },
14314 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14316 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14317 .name = "Channel Mode",
14318 .info = alc_ch_mode_info,
14319 .get = alc_ch_mode_get,
14320 .put = alc_ch_mode_put,
14325 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14326 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14328 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14329 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14330 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14332 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14333 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14335 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14337 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14339 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14340 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14342 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14343 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14347 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14348 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14349 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14351 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14352 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14353 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14355 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14356 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14358 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14359 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14364 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14365 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14366 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14368 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14370 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14371 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14372 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14374 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14375 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14376 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14378 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14379 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14381 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14382 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14387 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14388 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14389 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14390 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14392 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14394 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14395 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14396 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14398 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14399 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14400 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14403 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14408 /* Pin assignment: Speaker=0x14, HP = 0x15,
14409 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14411 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14412 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14413 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14414 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14415 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14416 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14417 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14418 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14419 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14420 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14421 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14425 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14426 * Front Mic=0x18, ATAPI Mic = 0x19,
14428 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14429 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14430 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14431 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14432 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14433 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14434 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14435 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14436 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14442 * generic initialization of ADC, input mixers and output mixers
14444 static struct hda_verb alc861vd_volume_init_verbs[] = {
14446 * Unmute ADC0 and set the default input to mic-in
14448 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14449 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14451 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14452 * the analog-loopback mixer widget
14454 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14459 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14461 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14462 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14468 * Set up output mixers (0x02 - 0x05)
14470 /* set vol=0 to output mixers */
14471 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14472 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14473 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14474 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14476 /* set up input amps for analog loopback */
14477 /* Amp Indices: DAC = 0, mixer = 1 */
14478 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14479 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14480 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14482 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14483 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14484 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14491 * 3-stack pin configuration:
14492 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14494 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14496 * Set pin mode and muting
14498 /* set front pin widgets 0x14 for output */
14499 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14500 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14501 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14503 /* Mic (rear) pin: input vref at 80% */
14504 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14505 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14506 /* Front Mic pin: input vref at 80% */
14507 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14508 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14509 /* Line In pin: input */
14510 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14511 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14512 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14513 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14514 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14515 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14516 /* CD pin widget for input */
14517 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14523 * 6-stack pin configuration:
14525 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14527 * Set pin mode and muting
14529 /* set front pin widgets 0x14 for output */
14530 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14532 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14534 /* Rear Pin: output 1 (0x0d) */
14535 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14536 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14537 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14538 /* CLFE Pin: output 2 (0x0e) */
14539 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14540 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14541 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14542 /* Side Pin: output 3 (0x0f) */
14543 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14544 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14545 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14547 /* Mic (rear) pin: input vref at 80% */
14548 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14549 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14550 /* Front Mic pin: input vref at 80% */
14551 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14552 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14553 /* Line In pin: input */
14554 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14555 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14556 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14557 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14558 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14559 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14560 /* CD pin widget for input */
14561 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14566 static struct hda_verb alc861vd_eapd_verbs[] = {
14567 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14571 static struct hda_verb alc660vd_eapd_verbs[] = {
14572 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14573 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14577 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14581 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14582 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14586 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14588 unsigned int present;
14589 unsigned char bits;
14591 present = snd_hda_codec_read(codec, 0x18, 0,
14592 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14593 bits = present ? HDA_AMP_MUTE : 0;
14594 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14595 HDA_AMP_MUTE, bits);
14598 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14600 struct alc_spec *spec = codec->spec;
14602 spec->autocfg.hp_pins[0] = 0x1b;
14603 spec->autocfg.speaker_pins[0] = 0x14;
14604 alc_automute_amp(codec);
14605 alc861vd_lenovo_mic_automute(codec);
14608 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14611 switch (res >> 26) {
14612 case ALC880_MIC_EVENT:
14613 alc861vd_lenovo_mic_automute(codec);
14616 alc_automute_amp_unsol_event(codec, res);
14621 static struct hda_verb alc861vd_dallas_verbs[] = {
14622 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14623 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14624 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14625 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14627 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14628 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14630 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14631 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14632 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14633 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14634 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14636 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14637 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14638 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14640 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14641 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14642 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14643 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14645 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14646 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14647 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14648 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14649 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14650 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14651 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14652 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14654 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14655 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14656 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14657 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14660 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14661 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14666 /* toggle speaker-output according to the hp-jack state */
14667 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14669 struct alc_spec *spec = codec->spec;
14671 spec->autocfg.hp_pins[0] = 0x15;
14672 spec->autocfg.speaker_pins[0] = 0x14;
14673 alc_automute_amp(codec);
14676 #ifdef CONFIG_SND_HDA_POWER_SAVE
14677 #define alc861vd_loopbacks alc880_loopbacks
14680 /* pcm configuration: identiacal with ALC880 */
14681 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14682 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14683 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14684 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14687 * configuration and preset
14689 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14690 [ALC660VD_3ST] = "3stack-660",
14691 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14692 [ALC660VD_ASUS_V1S] = "asus-v1s",
14693 [ALC861VD_3ST] = "3stack",
14694 [ALC861VD_3ST_DIG] = "3stack-digout",
14695 [ALC861VD_6ST_DIG] = "6stack-digout",
14696 [ALC861VD_LENOVO] = "lenovo",
14697 [ALC861VD_DALLAS] = "dallas",
14698 [ALC861VD_HP] = "hp",
14699 [ALC861VD_AUTO] = "auto",
14702 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14703 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14704 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14705 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14706 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14707 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14708 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14709 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14710 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14711 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14712 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14713 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14714 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14715 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14716 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14717 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14721 static struct alc_config_preset alc861vd_presets[] = {
14723 .mixers = { alc861vd_3st_mixer },
14724 .init_verbs = { alc861vd_volume_init_verbs,
14725 alc861vd_3stack_init_verbs },
14726 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14727 .dac_nids = alc660vd_dac_nids,
14728 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14729 .channel_mode = alc861vd_3stack_2ch_modes,
14730 .input_mux = &alc861vd_capture_source,
14732 [ALC660VD_3ST_DIG] = {
14733 .mixers = { alc861vd_3st_mixer },
14734 .init_verbs = { alc861vd_volume_init_verbs,
14735 alc861vd_3stack_init_verbs },
14736 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14737 .dac_nids = alc660vd_dac_nids,
14738 .dig_out_nid = ALC861VD_DIGOUT_NID,
14739 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14740 .channel_mode = alc861vd_3stack_2ch_modes,
14741 .input_mux = &alc861vd_capture_source,
14744 .mixers = { alc861vd_3st_mixer },
14745 .init_verbs = { alc861vd_volume_init_verbs,
14746 alc861vd_3stack_init_verbs },
14747 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14748 .dac_nids = alc861vd_dac_nids,
14749 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14750 .channel_mode = alc861vd_3stack_2ch_modes,
14751 .input_mux = &alc861vd_capture_source,
14753 [ALC861VD_3ST_DIG] = {
14754 .mixers = { alc861vd_3st_mixer },
14755 .init_verbs = { alc861vd_volume_init_verbs,
14756 alc861vd_3stack_init_verbs },
14757 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14758 .dac_nids = alc861vd_dac_nids,
14759 .dig_out_nid = ALC861VD_DIGOUT_NID,
14760 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14761 .channel_mode = alc861vd_3stack_2ch_modes,
14762 .input_mux = &alc861vd_capture_source,
14764 [ALC861VD_6ST_DIG] = {
14765 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14766 .init_verbs = { alc861vd_volume_init_verbs,
14767 alc861vd_6stack_init_verbs },
14768 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14769 .dac_nids = alc861vd_dac_nids,
14770 .dig_out_nid = ALC861VD_DIGOUT_NID,
14771 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14772 .channel_mode = alc861vd_6stack_modes,
14773 .input_mux = &alc861vd_capture_source,
14775 [ALC861VD_LENOVO] = {
14776 .mixers = { alc861vd_lenovo_mixer },
14777 .init_verbs = { alc861vd_volume_init_verbs,
14778 alc861vd_3stack_init_verbs,
14779 alc861vd_eapd_verbs,
14780 alc861vd_lenovo_unsol_verbs },
14781 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14782 .dac_nids = alc660vd_dac_nids,
14783 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14784 .channel_mode = alc861vd_3stack_2ch_modes,
14785 .input_mux = &alc861vd_capture_source,
14786 .unsol_event = alc861vd_lenovo_unsol_event,
14787 .init_hook = alc861vd_lenovo_init_hook,
14789 [ALC861VD_DALLAS] = {
14790 .mixers = { alc861vd_dallas_mixer },
14791 .init_verbs = { alc861vd_dallas_verbs },
14792 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14793 .dac_nids = alc861vd_dac_nids,
14794 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14795 .channel_mode = alc861vd_3stack_2ch_modes,
14796 .input_mux = &alc861vd_dallas_capture_source,
14797 .unsol_event = alc_automute_amp_unsol_event,
14798 .init_hook = alc861vd_dallas_init_hook,
14801 .mixers = { alc861vd_hp_mixer },
14802 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14803 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14804 .dac_nids = alc861vd_dac_nids,
14805 .dig_out_nid = ALC861VD_DIGOUT_NID,
14806 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14807 .channel_mode = alc861vd_3stack_2ch_modes,
14808 .input_mux = &alc861vd_hp_capture_source,
14809 .unsol_event = alc_automute_amp_unsol_event,
14810 .init_hook = alc861vd_dallas_init_hook,
14812 [ALC660VD_ASUS_V1S] = {
14813 .mixers = { alc861vd_lenovo_mixer },
14814 .init_verbs = { alc861vd_volume_init_verbs,
14815 alc861vd_3stack_init_verbs,
14816 alc861vd_eapd_verbs,
14817 alc861vd_lenovo_unsol_verbs },
14818 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14819 .dac_nids = alc660vd_dac_nids,
14820 .dig_out_nid = ALC861VD_DIGOUT_NID,
14821 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14822 .channel_mode = alc861vd_3stack_2ch_modes,
14823 .input_mux = &alc861vd_capture_source,
14824 .unsol_event = alc861vd_lenovo_unsol_event,
14825 .init_hook = alc861vd_lenovo_init_hook,
14830 * BIOS auto configuration
14832 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14833 hda_nid_t nid, int pin_type, int dac_idx)
14835 alc_set_pin_output(codec, nid, pin_type);
14838 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14840 struct alc_spec *spec = codec->spec;
14843 for (i = 0; i <= HDA_SIDE; i++) {
14844 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14845 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14847 alc861vd_auto_set_output_and_unmute(codec, nid,
14853 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14855 struct alc_spec *spec = codec->spec;
14858 pin = spec->autocfg.hp_pins[0];
14859 if (pin) /* connect to front and use dac 0 */
14860 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14861 pin = spec->autocfg.speaker_pins[0];
14863 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14866 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14867 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14869 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14871 struct alc_spec *spec = codec->spec;
14874 for (i = 0; i < AUTO_PIN_LAST; i++) {
14875 hda_nid_t nid = spec->autocfg.input_pins[i];
14876 if (alc861vd_is_input_pin(nid)) {
14877 alc_set_input_pin(codec, nid, i);
14878 if (nid != ALC861VD_PIN_CD_NID &&
14879 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14880 snd_hda_codec_write(codec, nid, 0,
14881 AC_VERB_SET_AMP_GAIN_MUTE,
14887 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14889 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14890 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14892 /* add playback controls from the parsed DAC table */
14893 /* Based on ALC880 version. But ALC861VD has separate,
14894 * different NIDs for mute/unmute switch and volume control */
14895 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14896 const struct auto_pin_cfg *cfg)
14899 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14900 hda_nid_t nid_v, nid_s;
14903 for (i = 0; i < cfg->line_outs; i++) {
14904 if (!spec->multiout.dac_nids[i])
14906 nid_v = alc861vd_idx_to_mixer_vol(
14908 spec->multiout.dac_nids[i]));
14909 nid_s = alc861vd_idx_to_mixer_switch(
14911 spec->multiout.dac_nids[i]));
14915 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14916 "Center Playback Volume",
14917 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14921 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14922 "LFE Playback Volume",
14923 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14927 err = add_control(spec, ALC_CTL_BIND_MUTE,
14928 "Center Playback Switch",
14929 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14933 err = add_control(spec, ALC_CTL_BIND_MUTE,
14934 "LFE Playback Switch",
14935 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14940 sprintf(name, "%s Playback Volume", chname[i]);
14941 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14942 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14946 sprintf(name, "%s Playback Switch", chname[i]);
14947 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14948 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14957 /* add playback controls for speaker and HP outputs */
14958 /* Based on ALC880 version. But ALC861VD has separate,
14959 * different NIDs for mute/unmute switch and volume control */
14960 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14961 hda_nid_t pin, const char *pfx)
14963 hda_nid_t nid_v, nid_s;
14970 if (alc880_is_fixed_pin(pin)) {
14971 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14972 /* specify the DAC as the extra output */
14973 if (!spec->multiout.hp_nid)
14974 spec->multiout.hp_nid = nid_v;
14976 spec->multiout.extra_out_nid[0] = nid_v;
14977 /* control HP volume/switch on the output mixer amp */
14978 nid_v = alc861vd_idx_to_mixer_vol(
14979 alc880_fixed_pin_idx(pin));
14980 nid_s = alc861vd_idx_to_mixer_switch(
14981 alc880_fixed_pin_idx(pin));
14983 sprintf(name, "%s Playback Volume", pfx);
14984 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14985 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14988 sprintf(name, "%s Playback Switch", pfx);
14989 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14990 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14993 } else if (alc880_is_multi_pin(pin)) {
14994 /* set manual connection */
14995 /* we have only a switch on HP-out PIN */
14996 sprintf(name, "%s Playback Switch", pfx);
14997 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14998 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15005 /* parse the BIOS configuration and set up the alc_spec
15006 * return 1 if successful, 0 if the proper config is not found,
15007 * or a negative error code
15008 * Based on ALC880 version - had to change it to override
15009 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15010 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15012 struct alc_spec *spec = codec->spec;
15014 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15016 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15020 if (!spec->autocfg.line_outs)
15021 return 0; /* can't find valid BIOS pin config */
15023 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15026 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15029 err = alc861vd_auto_create_extra_out(spec,
15030 spec->autocfg.speaker_pins[0],
15034 err = alc861vd_auto_create_extra_out(spec,
15035 spec->autocfg.hp_pins[0],
15039 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15043 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15045 if (spec->autocfg.dig_outs)
15046 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15048 if (spec->kctls.list)
15049 add_mixer(spec, spec->kctls.list);
15051 add_verb(spec, alc861vd_volume_init_verbs);
15053 spec->num_mux_defs = 1;
15054 spec->input_mux = &spec->private_imux[0];
15056 err = alc_auto_add_mic_boost(codec);
15060 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15065 /* additional initialization for auto-configuration model */
15066 static void alc861vd_auto_init(struct hda_codec *codec)
15068 struct alc_spec *spec = codec->spec;
15069 alc861vd_auto_init_multi_out(codec);
15070 alc861vd_auto_init_hp_out(codec);
15071 alc861vd_auto_init_analog_input(codec);
15072 alc861vd_auto_init_input_src(codec);
15073 if (spec->unsol_event)
15074 alc_inithook(codec);
15077 static int patch_alc861vd(struct hda_codec *codec)
15079 struct alc_spec *spec;
15080 int err, board_config;
15082 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15086 codec->spec = spec;
15088 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15092 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15093 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15094 "trying auto-probe from BIOS...\n", codec->chip_name);
15095 board_config = ALC861VD_AUTO;
15098 if (board_config == ALC861VD_AUTO) {
15099 /* automatic parse from the BIOS config */
15100 err = alc861vd_parse_auto_config(codec);
15106 "hda_codec: Cannot set up configuration "
15107 "from BIOS. Using base mode...\n");
15108 board_config = ALC861VD_3ST;
15112 err = snd_hda_attach_beep_device(codec, 0x23);
15118 if (board_config != ALC861VD_AUTO)
15119 setup_preset(spec, &alc861vd_presets[board_config]);
15121 if (codec->vendor_id == 0x10ec0660) {
15122 /* always turn on EAPD */
15123 add_verb(spec, alc660vd_eapd_verbs);
15126 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15127 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15129 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15130 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15132 spec->adc_nids = alc861vd_adc_nids;
15133 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15134 spec->capsrc_nids = alc861vd_capsrc_nids;
15135 spec->capture_style = CAPT_MIX;
15137 set_capture_mixer(spec);
15138 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15140 spec->vmaster_nid = 0x02;
15142 codec->patch_ops = alc_patch_ops;
15144 if (board_config == ALC861VD_AUTO)
15145 spec->init_hook = alc861vd_auto_init;
15146 #ifdef CONFIG_SND_HDA_POWER_SAVE
15147 if (!spec->loopback.amplist)
15148 spec->loopback.amplist = alc861vd_loopbacks;
15150 codec->proc_widget_hook = print_realtek_coef;
15158 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15159 * configuration. Each pin widget can choose any input DACs and a mixer.
15160 * Each ADC is connected from a mixer of all inputs. This makes possible
15161 * 6-channel independent captures.
15163 * In addition, an independent DAC for the multi-playback (not used in this
15166 #define ALC662_DIGOUT_NID 0x06
15167 #define ALC662_DIGIN_NID 0x0a
15169 static hda_nid_t alc662_dac_nids[4] = {
15170 /* front, rear, clfe, rear_surr */
15174 static hda_nid_t alc272_dac_nids[2] = {
15178 static hda_nid_t alc662_adc_nids[1] = {
15183 static hda_nid_t alc272_adc_nids[1] = {
15188 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15189 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15193 /* FIXME: should be a matrix-type input source selection */
15194 static struct hda_input_mux alc662_capture_source = {
15198 { "Front Mic", 0x1 },
15204 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15212 static struct hda_input_mux alc662_eeepc_capture_source = {
15220 static struct hda_input_mux alc663_capture_source = {
15224 { "Front Mic", 0x1 },
15229 static struct hda_input_mux alc663_m51va_capture_source = {
15232 { "Ext-Mic", 0x0 },
15237 #if 1 /* set to 0 for testing other input sources below */
15238 static struct hda_input_mux alc272_nc10_capture_source = {
15241 { "Autoselect Mic", 0x0 },
15242 { "Internal Mic", 0x1 },
15246 static struct hda_input_mux alc272_nc10_capture_source = {
15249 { "Autoselect Mic", 0x0 },
15250 { "Internal Mic", 0x1 },
15251 { "In-0x02", 0x2 },
15252 { "In-0x03", 0x3 },
15253 { "In-0x04", 0x4 },
15254 { "In-0x05", 0x5 },
15255 { "In-0x06", 0x6 },
15256 { "In-0x07", 0x7 },
15257 { "In-0x08", 0x8 },
15258 { "In-0x09", 0x9 },
15259 { "In-0x0a", 0x0a },
15260 { "In-0x0b", 0x0b },
15261 { "In-0x0c", 0x0c },
15262 { "In-0x0d", 0x0d },
15263 { "In-0x0e", 0x0e },
15264 { "In-0x0f", 0x0f },
15272 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15279 static struct hda_verb alc662_3ST_ch2_init[] = {
15280 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15281 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15282 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15283 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15290 static struct hda_verb alc662_3ST_ch6_init[] = {
15291 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15292 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15293 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15294 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15295 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15296 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15300 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15301 { 2, alc662_3ST_ch2_init },
15302 { 6, alc662_3ST_ch6_init },
15308 static struct hda_verb alc662_sixstack_ch6_init[] = {
15309 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15310 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15311 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15318 static struct hda_verb alc662_sixstack_ch8_init[] = {
15319 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15320 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15321 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15325 static struct hda_channel_mode alc662_5stack_modes[2] = {
15326 { 2, alc662_sixstack_ch6_init },
15327 { 6, alc662_sixstack_ch8_init },
15330 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15331 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15334 static struct snd_kcontrol_new alc662_base_mixer[] = {
15335 /* output mixer control */
15336 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15337 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15338 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15339 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15340 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15341 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15342 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15343 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15344 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15346 /*Input mixer control */
15347 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15348 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15349 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15350 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15351 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15352 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15353 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15354 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15358 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15359 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15360 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15362 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15363 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15364 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15365 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15366 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15367 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15368 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15369 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15373 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15374 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15375 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15376 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15377 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15378 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15379 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15380 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15381 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15389 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15390 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15394 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15395 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15396 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15397 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15398 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15400 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15401 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15407 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15408 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15409 ALC262_HIPPO_MASTER_SWITCH,
15411 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15412 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15413 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15415 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15416 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15417 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15421 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15422 ALC262_HIPPO_MASTER_SWITCH,
15423 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15424 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15425 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15426 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15427 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15435 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15436 .ops = &snd_hda_bind_vol,
15438 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15439 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15444 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15445 .ops = &snd_hda_bind_sw,
15447 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15448 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15453 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15454 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15455 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15461 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15462 .ops = &snd_hda_bind_sw,
15464 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15465 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15466 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15471 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15472 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15473 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15474 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15475 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15476 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15477 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15482 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15483 .ops = &snd_hda_bind_sw,
15485 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15486 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15487 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15492 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15493 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15494 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15496 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15497 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15498 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15502 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15503 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15504 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15508 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15509 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15513 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15514 .ops = &snd_hda_bind_vol,
15516 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15517 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15522 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15523 .ops = &snd_hda_bind_sw,
15525 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15526 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15531 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15532 HDA_BIND_VOL("Master Playback Volume",
15533 &alc663_asus_two_bind_master_vol),
15534 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15535 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15536 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15538 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15542 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15543 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15544 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15545 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15546 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15552 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15553 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15554 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15555 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15556 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15557 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15559 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15560 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15561 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15562 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15566 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15567 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15568 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15569 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15571 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15572 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15573 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15574 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15575 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15576 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15580 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15583 .name = "Channel Mode",
15584 .info = alc_ch_mode_info,
15585 .get = alc_ch_mode_get,
15586 .put = alc_ch_mode_put,
15591 static struct hda_verb alc662_init_verbs[] = {
15592 /* ADC: mute amp left and right */
15593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15594 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15595 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15597 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15598 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15599 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15605 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15607 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15608 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15610 /* Front Pin: output 0 (0x0c) */
15611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15612 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15614 /* Rear Pin: output 1 (0x0d) */
15615 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15616 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15618 /* CLFE Pin: output 2 (0x0e) */
15619 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15620 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15622 /* Mic (rear) pin: input vref at 80% */
15623 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15624 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15625 /* Front Mic pin: input vref at 80% */
15626 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15627 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15628 /* Line In pin: input */
15629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15631 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15634 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15635 /* CD pin widget for input */
15636 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15638 /* FIXME: use matrix-type input source selection */
15639 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15641 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15642 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15644 /* always trun on EAPD */
15645 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15646 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15651 static struct hda_verb alc662_sue_init_verbs[] = {
15652 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15653 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15657 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15658 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15659 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15663 /* Set Unsolicited Event*/
15664 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15665 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15666 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15671 * generic initialization of ADC, input mixers and output mixers
15673 static struct hda_verb alc662_auto_init_verbs[] = {
15675 * Unmute ADC and set the default input to mic-in
15677 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15680 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15682 * Note: PASD motherboards uses the Line In 2 as the input for front
15683 * panel mic (mic 2)
15685 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15693 * Set up output mixers (0x0c - 0x0f)
15695 /* set vol=0 to output mixers */
15696 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15697 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15698 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15700 /* set up input amps for analog loopback */
15701 /* Amp Indices: DAC = 0, mixer = 1 */
15702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15704 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15707 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15710 /* FIXME: use matrix-type input source selection */
15711 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15713 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15714 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15718 /* additional verbs for ALC663 */
15719 static struct hda_verb alc663_auto_init_verbs[] = {
15720 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15721 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15725 static struct hda_verb alc663_m51va_init_verbs[] = {
15726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15727 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15728 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15729 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15730 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15732 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15733 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15734 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15738 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15739 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15740 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15741 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15742 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15743 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15744 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15745 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15749 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15750 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15751 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15752 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15753 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15754 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15756 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15757 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15761 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15766 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15767 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15768 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15772 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15773 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15774 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15775 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15776 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15777 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15778 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15779 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15780 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15782 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15783 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15784 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15788 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15789 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15790 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15791 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15792 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15793 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15794 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15795 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15796 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15797 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15798 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15799 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15800 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15804 static struct hda_verb alc663_g71v_init_verbs[] = {
15805 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15806 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15807 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15809 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15810 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15811 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15813 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15814 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15815 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15819 static struct hda_verb alc663_g50v_init_verbs[] = {
15820 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15821 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15822 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15824 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15825 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15829 static struct hda_verb alc662_ecs_init_verbs[] = {
15830 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15831 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15832 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15833 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15837 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15838 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15839 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15840 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15841 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15842 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15843 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15844 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15845 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15847 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15848 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15852 static struct hda_verb alc272_dell_init_verbs[] = {
15853 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15854 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15855 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15856 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15857 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15858 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15859 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15860 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15861 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15862 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15863 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15867 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15868 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15869 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15873 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15874 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15875 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15879 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15881 unsigned int present;
15882 unsigned char bits;
15884 present = snd_hda_codec_read(codec, 0x14, 0,
15885 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15886 bits = present ? HDA_AMP_MUTE : 0;
15887 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15888 HDA_AMP_MUTE, bits);
15891 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15893 unsigned int present;
15894 unsigned char bits;
15896 present = snd_hda_codec_read(codec, 0x1b, 0,
15897 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15898 bits = present ? HDA_AMP_MUTE : 0;
15899 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15900 HDA_AMP_MUTE, bits);
15901 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15902 HDA_AMP_MUTE, bits);
15905 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15908 if ((res >> 26) == ALC880_HP_EVENT)
15909 alc662_lenovo_101e_all_automute(codec);
15910 if ((res >> 26) == ALC880_FRONT_EVENT)
15911 alc662_lenovo_101e_ispeaker_automute(codec);
15914 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15916 unsigned int present;
15918 present = snd_hda_codec_read(codec, 0x18, 0,
15919 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15920 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15921 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15922 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15923 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15924 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15925 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15926 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15927 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15930 /* unsolicited event for HP jack sensing */
15931 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15934 if ((res >> 26) == ALC880_MIC_EVENT)
15935 alc662_eeepc_mic_automute(codec);
15937 alc262_hippo_unsol_event(codec, res);
15940 static void alc662_eeepc_inithook(struct hda_codec *codec)
15942 alc262_hippo1_init_hook(codec);
15943 alc662_eeepc_mic_automute(codec);
15946 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15948 struct alc_spec *spec = codec->spec;
15950 spec->autocfg.hp_pins[0] = 0x14;
15951 spec->autocfg.speaker_pins[0] = 0x1b;
15952 alc262_hippo_master_update(codec);
15955 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15957 unsigned int present;
15958 unsigned char bits;
15960 present = snd_hda_codec_read(codec, 0x21, 0,
15961 AC_VERB_GET_PIN_SENSE, 0)
15962 & AC_PINSENSE_PRESENCE;
15963 bits = present ? HDA_AMP_MUTE : 0;
15964 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15965 AMP_IN_MUTE(0), bits);
15966 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15967 AMP_IN_MUTE(0), bits);
15970 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15972 unsigned int present;
15973 unsigned char bits;
15975 present = snd_hda_codec_read(codec, 0x21, 0,
15976 AC_VERB_GET_PIN_SENSE, 0)
15977 & AC_PINSENSE_PRESENCE;
15978 bits = present ? HDA_AMP_MUTE : 0;
15979 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15980 AMP_IN_MUTE(0), bits);
15981 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15982 AMP_IN_MUTE(0), bits);
15983 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15984 AMP_IN_MUTE(0), bits);
15985 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15986 AMP_IN_MUTE(0), bits);
15989 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15991 unsigned int present;
15992 unsigned char bits;
15994 present = snd_hda_codec_read(codec, 0x15, 0,
15995 AC_VERB_GET_PIN_SENSE, 0)
15996 & AC_PINSENSE_PRESENCE;
15997 bits = present ? HDA_AMP_MUTE : 0;
15998 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15999 AMP_IN_MUTE(0), bits);
16000 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16001 AMP_IN_MUTE(0), bits);
16002 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16003 AMP_IN_MUTE(0), bits);
16004 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16005 AMP_IN_MUTE(0), bits);
16008 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16010 unsigned int present;
16011 unsigned char bits;
16013 present = snd_hda_codec_read(codec, 0x1b, 0,
16014 AC_VERB_GET_PIN_SENSE, 0)
16015 & AC_PINSENSE_PRESENCE;
16016 bits = present ? 0 : PIN_OUT;
16017 snd_hda_codec_write(codec, 0x14, 0,
16018 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16021 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16023 unsigned int present1, present2;
16025 present1 = snd_hda_codec_read(codec, 0x21, 0,
16026 AC_VERB_GET_PIN_SENSE, 0)
16027 & AC_PINSENSE_PRESENCE;
16028 present2 = snd_hda_codec_read(codec, 0x15, 0,
16029 AC_VERB_GET_PIN_SENSE, 0)
16030 & AC_PINSENSE_PRESENCE;
16032 if (present1 || present2) {
16033 snd_hda_codec_write_cache(codec, 0x14, 0,
16034 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16036 snd_hda_codec_write_cache(codec, 0x14, 0,
16037 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16041 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16043 unsigned int present1, present2;
16045 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16046 AC_VERB_GET_PIN_SENSE, 0)
16047 & AC_PINSENSE_PRESENCE;
16048 present2 = snd_hda_codec_read(codec, 0x15, 0,
16049 AC_VERB_GET_PIN_SENSE, 0)
16050 & AC_PINSENSE_PRESENCE;
16052 if (present1 || present2) {
16053 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16054 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16055 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16056 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16058 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16059 AMP_IN_MUTE(0), 0);
16060 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16061 AMP_IN_MUTE(0), 0);
16065 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16067 unsigned int present;
16069 present = snd_hda_codec_read(codec, 0x18, 0,
16070 AC_VERB_GET_PIN_SENSE, 0)
16071 & AC_PINSENSE_PRESENCE;
16072 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16073 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16074 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16075 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16076 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16077 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16078 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16079 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16082 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16085 switch (res >> 26) {
16086 case ALC880_HP_EVENT:
16087 alc663_m51va_speaker_automute(codec);
16089 case ALC880_MIC_EVENT:
16090 alc663_m51va_mic_automute(codec);
16095 static void alc663_m51va_inithook(struct hda_codec *codec)
16097 alc663_m51va_speaker_automute(codec);
16098 alc663_m51va_mic_automute(codec);
16101 /* ***************** Mode1 ******************************/
16102 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16105 switch (res >> 26) {
16106 case ALC880_HP_EVENT:
16107 alc663_m51va_speaker_automute(codec);
16109 case ALC880_MIC_EVENT:
16110 alc662_eeepc_mic_automute(codec);
16115 static void alc663_mode1_inithook(struct hda_codec *codec)
16117 alc663_m51va_speaker_automute(codec);
16118 alc662_eeepc_mic_automute(codec);
16120 /* ***************** Mode2 ******************************/
16121 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16124 switch (res >> 26) {
16125 case ALC880_HP_EVENT:
16126 alc662_f5z_speaker_automute(codec);
16128 case ALC880_MIC_EVENT:
16129 alc662_eeepc_mic_automute(codec);
16134 static void alc662_mode2_inithook(struct hda_codec *codec)
16136 alc662_f5z_speaker_automute(codec);
16137 alc662_eeepc_mic_automute(codec);
16139 /* ***************** Mode3 ******************************/
16140 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16143 switch (res >> 26) {
16144 case ALC880_HP_EVENT:
16145 alc663_two_hp_m1_speaker_automute(codec);
16147 case ALC880_MIC_EVENT:
16148 alc662_eeepc_mic_automute(codec);
16153 static void alc663_mode3_inithook(struct hda_codec *codec)
16155 alc663_two_hp_m1_speaker_automute(codec);
16156 alc662_eeepc_mic_automute(codec);
16158 /* ***************** Mode4 ******************************/
16159 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16162 switch (res >> 26) {
16163 case ALC880_HP_EVENT:
16164 alc663_21jd_two_speaker_automute(codec);
16166 case ALC880_MIC_EVENT:
16167 alc662_eeepc_mic_automute(codec);
16172 static void alc663_mode4_inithook(struct hda_codec *codec)
16174 alc663_21jd_two_speaker_automute(codec);
16175 alc662_eeepc_mic_automute(codec);
16177 /* ***************** Mode5 ******************************/
16178 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16181 switch (res >> 26) {
16182 case ALC880_HP_EVENT:
16183 alc663_15jd_two_speaker_automute(codec);
16185 case ALC880_MIC_EVENT:
16186 alc662_eeepc_mic_automute(codec);
16191 static void alc663_mode5_inithook(struct hda_codec *codec)
16193 alc663_15jd_two_speaker_automute(codec);
16194 alc662_eeepc_mic_automute(codec);
16196 /* ***************** Mode6 ******************************/
16197 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16200 switch (res >> 26) {
16201 case ALC880_HP_EVENT:
16202 alc663_two_hp_m2_speaker_automute(codec);
16204 case ALC880_MIC_EVENT:
16205 alc662_eeepc_mic_automute(codec);
16210 static void alc663_mode6_inithook(struct hda_codec *codec)
16212 alc663_two_hp_m2_speaker_automute(codec);
16213 alc662_eeepc_mic_automute(codec);
16216 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16218 unsigned int present;
16219 unsigned char bits;
16221 present = snd_hda_codec_read(codec, 0x21, 0,
16222 AC_VERB_GET_PIN_SENSE, 0)
16223 & AC_PINSENSE_PRESENCE;
16224 bits = present ? HDA_AMP_MUTE : 0;
16225 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16226 HDA_AMP_MUTE, bits);
16227 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16228 HDA_AMP_MUTE, bits);
16231 static void alc663_g71v_front_automute(struct hda_codec *codec)
16233 unsigned int present;
16234 unsigned char bits;
16236 present = snd_hda_codec_read(codec, 0x15, 0,
16237 AC_VERB_GET_PIN_SENSE, 0)
16238 & AC_PINSENSE_PRESENCE;
16239 bits = present ? HDA_AMP_MUTE : 0;
16240 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16241 HDA_AMP_MUTE, bits);
16244 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16247 switch (res >> 26) {
16248 case ALC880_HP_EVENT:
16249 alc663_g71v_hp_automute(codec);
16251 case ALC880_FRONT_EVENT:
16252 alc663_g71v_front_automute(codec);
16254 case ALC880_MIC_EVENT:
16255 alc662_eeepc_mic_automute(codec);
16260 static void alc663_g71v_inithook(struct hda_codec *codec)
16262 alc663_g71v_front_automute(codec);
16263 alc663_g71v_hp_automute(codec);
16264 alc662_eeepc_mic_automute(codec);
16267 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16270 switch (res >> 26) {
16271 case ALC880_HP_EVENT:
16272 alc663_m51va_speaker_automute(codec);
16274 case ALC880_MIC_EVENT:
16275 alc662_eeepc_mic_automute(codec);
16280 static void alc663_g50v_inithook(struct hda_codec *codec)
16282 alc663_m51va_speaker_automute(codec);
16283 alc662_eeepc_mic_automute(codec);
16286 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16287 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16288 ALC262_HIPPO_MASTER_SWITCH,
16290 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16291 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16292 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16294 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16295 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16296 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16300 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16301 /* Master Playback automatically created from Speaker and Headphone */
16302 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16303 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16304 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16305 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16307 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16308 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16309 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16311 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16312 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16313 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16317 #ifdef CONFIG_SND_HDA_POWER_SAVE
16318 #define alc662_loopbacks alc880_loopbacks
16322 /* pcm configuration: identiacal with ALC880 */
16323 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16324 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16325 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16326 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16329 * configuration and preset
16331 static const char *alc662_models[ALC662_MODEL_LAST] = {
16332 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16333 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16334 [ALC662_3ST_6ch] = "3stack-6ch",
16335 [ALC662_5ST_DIG] = "6stack-dig",
16336 [ALC662_LENOVO_101E] = "lenovo-101e",
16337 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16338 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16339 [ALC662_ECS] = "ecs",
16340 [ALC663_ASUS_M51VA] = "m51va",
16341 [ALC663_ASUS_G71V] = "g71v",
16342 [ALC663_ASUS_H13] = "h13",
16343 [ALC663_ASUS_G50V] = "g50v",
16344 [ALC663_ASUS_MODE1] = "asus-mode1",
16345 [ALC662_ASUS_MODE2] = "asus-mode2",
16346 [ALC663_ASUS_MODE3] = "asus-mode3",
16347 [ALC663_ASUS_MODE4] = "asus-mode4",
16348 [ALC663_ASUS_MODE5] = "asus-mode5",
16349 [ALC663_ASUS_MODE6] = "asus-mode6",
16350 [ALC272_DELL] = "dell",
16351 [ALC272_DELL_ZM1] = "dell-zm1",
16352 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16353 [ALC662_AUTO] = "auto",
16356 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16357 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16358 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16359 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16360 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16361 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16362 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16363 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16364 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16365 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16366 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16367 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16368 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16369 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16370 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16371 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16372 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16373 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16374 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16375 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16376 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16377 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16378 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16379 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16380 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16381 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16382 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16383 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16384 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16385 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16386 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16387 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16388 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16389 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16390 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16391 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16392 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16393 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16394 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16395 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16396 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16397 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16398 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16399 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16400 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16401 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16402 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16403 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16404 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16405 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16406 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16407 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16408 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16409 ALC662_3ST_6ch_DIG),
16410 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16411 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16412 ALC662_3ST_6ch_DIG),
16413 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16414 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16415 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16416 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16417 ALC662_3ST_6ch_DIG),
16418 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16423 static struct alc_config_preset alc662_presets[] = {
16424 [ALC662_3ST_2ch_DIG] = {
16425 .mixers = { alc662_3ST_2ch_mixer },
16426 .init_verbs = { alc662_init_verbs },
16427 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16428 .dac_nids = alc662_dac_nids,
16429 .dig_out_nid = ALC662_DIGOUT_NID,
16430 .dig_in_nid = ALC662_DIGIN_NID,
16431 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16432 .channel_mode = alc662_3ST_2ch_modes,
16433 .input_mux = &alc662_capture_source,
16435 [ALC662_3ST_6ch_DIG] = {
16436 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16437 .init_verbs = { alc662_init_verbs },
16438 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16439 .dac_nids = alc662_dac_nids,
16440 .dig_out_nid = ALC662_DIGOUT_NID,
16441 .dig_in_nid = ALC662_DIGIN_NID,
16442 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16443 .channel_mode = alc662_3ST_6ch_modes,
16445 .input_mux = &alc662_capture_source,
16447 [ALC662_3ST_6ch] = {
16448 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16449 .init_verbs = { alc662_init_verbs },
16450 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16451 .dac_nids = alc662_dac_nids,
16452 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16453 .channel_mode = alc662_3ST_6ch_modes,
16455 .input_mux = &alc662_capture_source,
16457 [ALC662_5ST_DIG] = {
16458 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16459 .init_verbs = { alc662_init_verbs },
16460 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16461 .dac_nids = alc662_dac_nids,
16462 .dig_out_nid = ALC662_DIGOUT_NID,
16463 .dig_in_nid = ALC662_DIGIN_NID,
16464 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16465 .channel_mode = alc662_5stack_modes,
16466 .input_mux = &alc662_capture_source,
16468 [ALC662_LENOVO_101E] = {
16469 .mixers = { alc662_lenovo_101e_mixer },
16470 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16471 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16472 .dac_nids = alc662_dac_nids,
16473 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16474 .channel_mode = alc662_3ST_2ch_modes,
16475 .input_mux = &alc662_lenovo_101e_capture_source,
16476 .unsol_event = alc662_lenovo_101e_unsol_event,
16477 .init_hook = alc662_lenovo_101e_all_automute,
16479 [ALC662_ASUS_EEEPC_P701] = {
16480 .mixers = { alc662_eeepc_p701_mixer },
16481 .init_verbs = { alc662_init_verbs,
16482 alc662_eeepc_sue_init_verbs },
16483 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16484 .dac_nids = alc662_dac_nids,
16485 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16486 .channel_mode = alc662_3ST_2ch_modes,
16487 .input_mux = &alc662_eeepc_capture_source,
16488 .unsol_event = alc662_eeepc_unsol_event,
16489 .init_hook = alc662_eeepc_inithook,
16491 [ALC662_ASUS_EEEPC_EP20] = {
16492 .mixers = { alc662_eeepc_ep20_mixer,
16493 alc662_chmode_mixer },
16494 .init_verbs = { alc662_init_verbs,
16495 alc662_eeepc_ep20_sue_init_verbs },
16496 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16497 .dac_nids = alc662_dac_nids,
16498 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16499 .channel_mode = alc662_3ST_6ch_modes,
16500 .input_mux = &alc662_lenovo_101e_capture_source,
16501 .unsol_event = alc662_eeepc_unsol_event,
16502 .init_hook = alc662_eeepc_ep20_inithook,
16505 .mixers = { alc662_ecs_mixer },
16506 .init_verbs = { alc662_init_verbs,
16507 alc662_ecs_init_verbs },
16508 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16509 .dac_nids = alc662_dac_nids,
16510 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16511 .channel_mode = alc662_3ST_2ch_modes,
16512 .input_mux = &alc662_eeepc_capture_source,
16513 .unsol_event = alc662_eeepc_unsol_event,
16514 .init_hook = alc662_eeepc_inithook,
16516 [ALC663_ASUS_M51VA] = {
16517 .mixers = { alc663_m51va_mixer },
16518 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16519 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16520 .dac_nids = alc662_dac_nids,
16521 .dig_out_nid = ALC662_DIGOUT_NID,
16522 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16523 .channel_mode = alc662_3ST_2ch_modes,
16524 .input_mux = &alc663_m51va_capture_source,
16525 .unsol_event = alc663_m51va_unsol_event,
16526 .init_hook = alc663_m51va_inithook,
16528 [ALC663_ASUS_G71V] = {
16529 .mixers = { alc663_g71v_mixer },
16530 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16531 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16532 .dac_nids = alc662_dac_nids,
16533 .dig_out_nid = ALC662_DIGOUT_NID,
16534 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16535 .channel_mode = alc662_3ST_2ch_modes,
16536 .input_mux = &alc662_eeepc_capture_source,
16537 .unsol_event = alc663_g71v_unsol_event,
16538 .init_hook = alc663_g71v_inithook,
16540 [ALC663_ASUS_H13] = {
16541 .mixers = { alc663_m51va_mixer },
16542 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16543 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16544 .dac_nids = alc662_dac_nids,
16545 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16546 .channel_mode = alc662_3ST_2ch_modes,
16547 .input_mux = &alc663_m51va_capture_source,
16548 .unsol_event = alc663_m51va_unsol_event,
16549 .init_hook = alc663_m51va_inithook,
16551 [ALC663_ASUS_G50V] = {
16552 .mixers = { alc663_g50v_mixer },
16553 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16554 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16555 .dac_nids = alc662_dac_nids,
16556 .dig_out_nid = ALC662_DIGOUT_NID,
16557 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16558 .channel_mode = alc662_3ST_6ch_modes,
16559 .input_mux = &alc663_capture_source,
16560 .unsol_event = alc663_g50v_unsol_event,
16561 .init_hook = alc663_g50v_inithook,
16563 [ALC663_ASUS_MODE1] = {
16564 .mixers = { alc663_m51va_mixer },
16565 .cap_mixer = alc662_auto_capture_mixer,
16566 .init_verbs = { alc662_init_verbs,
16567 alc663_21jd_amic_init_verbs },
16568 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16570 .dac_nids = alc662_dac_nids,
16571 .dig_out_nid = ALC662_DIGOUT_NID,
16572 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16573 .channel_mode = alc662_3ST_2ch_modes,
16574 .input_mux = &alc662_eeepc_capture_source,
16575 .unsol_event = alc663_mode1_unsol_event,
16576 .init_hook = alc663_mode1_inithook,
16578 [ALC662_ASUS_MODE2] = {
16579 .mixers = { alc662_1bjd_mixer },
16580 .cap_mixer = alc662_auto_capture_mixer,
16581 .init_verbs = { alc662_init_verbs,
16582 alc662_1bjd_amic_init_verbs },
16583 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16584 .dac_nids = alc662_dac_nids,
16585 .dig_out_nid = ALC662_DIGOUT_NID,
16586 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16587 .channel_mode = alc662_3ST_2ch_modes,
16588 .input_mux = &alc662_eeepc_capture_source,
16589 .unsol_event = alc662_mode2_unsol_event,
16590 .init_hook = alc662_mode2_inithook,
16592 [ALC663_ASUS_MODE3] = {
16593 .mixers = { alc663_two_hp_m1_mixer },
16594 .cap_mixer = alc662_auto_capture_mixer,
16595 .init_verbs = { alc662_init_verbs,
16596 alc663_two_hp_amic_m1_init_verbs },
16597 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16599 .dac_nids = alc662_dac_nids,
16600 .dig_out_nid = ALC662_DIGOUT_NID,
16601 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16602 .channel_mode = alc662_3ST_2ch_modes,
16603 .input_mux = &alc662_eeepc_capture_source,
16604 .unsol_event = alc663_mode3_unsol_event,
16605 .init_hook = alc663_mode3_inithook,
16607 [ALC663_ASUS_MODE4] = {
16608 .mixers = { alc663_asus_21jd_clfe_mixer },
16609 .cap_mixer = alc662_auto_capture_mixer,
16610 .init_verbs = { alc662_init_verbs,
16611 alc663_21jd_amic_init_verbs},
16612 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16614 .dac_nids = alc662_dac_nids,
16615 .dig_out_nid = ALC662_DIGOUT_NID,
16616 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16617 .channel_mode = alc662_3ST_2ch_modes,
16618 .input_mux = &alc662_eeepc_capture_source,
16619 .unsol_event = alc663_mode4_unsol_event,
16620 .init_hook = alc663_mode4_inithook,
16622 [ALC663_ASUS_MODE5] = {
16623 .mixers = { alc663_asus_15jd_clfe_mixer },
16624 .cap_mixer = alc662_auto_capture_mixer,
16625 .init_verbs = { alc662_init_verbs,
16626 alc663_15jd_amic_init_verbs },
16627 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16629 .dac_nids = alc662_dac_nids,
16630 .dig_out_nid = ALC662_DIGOUT_NID,
16631 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16632 .channel_mode = alc662_3ST_2ch_modes,
16633 .input_mux = &alc662_eeepc_capture_source,
16634 .unsol_event = alc663_mode5_unsol_event,
16635 .init_hook = alc663_mode5_inithook,
16637 [ALC663_ASUS_MODE6] = {
16638 .mixers = { alc663_two_hp_m2_mixer },
16639 .cap_mixer = alc662_auto_capture_mixer,
16640 .init_verbs = { alc662_init_verbs,
16641 alc663_two_hp_amic_m2_init_verbs },
16642 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16644 .dac_nids = alc662_dac_nids,
16645 .dig_out_nid = ALC662_DIGOUT_NID,
16646 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16647 .channel_mode = alc662_3ST_2ch_modes,
16648 .input_mux = &alc662_eeepc_capture_source,
16649 .unsol_event = alc663_mode6_unsol_event,
16650 .init_hook = alc663_mode6_inithook,
16653 .mixers = { alc663_m51va_mixer },
16654 .cap_mixer = alc272_auto_capture_mixer,
16655 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16656 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16657 .dac_nids = alc662_dac_nids,
16658 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16659 .adc_nids = alc272_adc_nids,
16660 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16661 .capsrc_nids = alc272_capsrc_nids,
16662 .channel_mode = alc662_3ST_2ch_modes,
16663 .input_mux = &alc663_m51va_capture_source,
16664 .unsol_event = alc663_m51va_unsol_event,
16665 .init_hook = alc663_m51va_inithook,
16667 [ALC272_DELL_ZM1] = {
16668 .mixers = { alc663_m51va_mixer },
16669 .cap_mixer = alc662_auto_capture_mixer,
16670 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16671 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16672 .dac_nids = alc662_dac_nids,
16673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16674 .adc_nids = alc662_adc_nids,
16675 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16676 .capsrc_nids = alc662_capsrc_nids,
16677 .channel_mode = alc662_3ST_2ch_modes,
16678 .input_mux = &alc663_m51va_capture_source,
16679 .unsol_event = alc663_m51va_unsol_event,
16680 .init_hook = alc663_m51va_inithook,
16682 [ALC272_SAMSUNG_NC10] = {
16683 .mixers = { alc272_nc10_mixer },
16684 .init_verbs = { alc662_init_verbs,
16685 alc663_21jd_amic_init_verbs },
16686 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16687 .dac_nids = alc272_dac_nids,
16688 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16689 .channel_mode = alc662_3ST_2ch_modes,
16690 .input_mux = &alc272_nc10_capture_source,
16691 .unsol_event = alc663_mode4_unsol_event,
16692 .init_hook = alc663_mode4_inithook,
16698 * BIOS auto configuration
16701 /* add playback controls from the parsed DAC table */
16702 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16703 const struct auto_pin_cfg *cfg)
16706 static const char *chname[4] = {
16707 "Front", "Surround", NULL /*CLFE*/, "Side"
16712 for (i = 0; i < cfg->line_outs; i++) {
16713 if (!spec->multiout.dac_nids[i])
16715 nid = alc880_idx_to_dac(i);
16718 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16719 "Center Playback Volume",
16720 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16724 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16725 "LFE Playback Volume",
16726 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16730 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16731 "Center Playback Switch",
16732 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16736 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16737 "LFE Playback Switch",
16738 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16743 sprintf(name, "%s Playback Volume", chname[i]);
16744 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16745 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16749 sprintf(name, "%s Playback Switch", chname[i]);
16750 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16751 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16760 /* add playback controls for speaker and HP outputs */
16761 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16772 /* ALC663 has a mono output pin on 0x17 */
16773 sprintf(name, "%s Playback Switch", pfx);
16774 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16775 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16779 if (alc880_is_fixed_pin(pin)) {
16780 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16781 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16782 /* specify the DAC as the extra output */
16783 if (!spec->multiout.hp_nid)
16784 spec->multiout.hp_nid = nid;
16786 spec->multiout.extra_out_nid[0] = nid;
16787 /* control HP volume/switch on the output mixer amp */
16788 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16789 sprintf(name, "%s Playback Volume", pfx);
16790 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16791 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16794 sprintf(name, "%s Playback Switch", pfx);
16795 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16796 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16799 } else if (alc880_is_multi_pin(pin)) {
16800 /* set manual connection */
16801 /* we have only a switch on HP-out PIN */
16802 sprintf(name, "%s Playback Switch", pfx);
16803 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16804 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16811 /* return the index of the src widget from the connection list of the nid.
16812 * return -1 if not found
16814 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16817 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16820 conns = snd_hda_get_connections(codec, nid, conn_list,
16821 ARRAY_SIZE(conn_list));
16824 for (i = 0; i < conns; i++)
16825 if (conn_list[i] == src)
16830 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16832 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16833 return (pincap & AC_PINCAP_IN) != 0;
16836 /* create playback/capture controls for input pins */
16837 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16838 const struct auto_pin_cfg *cfg)
16840 struct alc_spec *spec = codec->spec;
16841 struct hda_input_mux *imux = &spec->private_imux[0];
16844 for (i = 0; i < AUTO_PIN_LAST; i++) {
16845 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16846 idx = alc662_input_pin_idx(codec, 0x0b,
16847 cfg->input_pins[i]);
16849 err = new_analog_input(spec, cfg->input_pins[i],
16850 auto_pin_cfg_labels[i],
16855 idx = alc662_input_pin_idx(codec, 0x22,
16856 cfg->input_pins[i]);
16858 imux->items[imux->num_items].label =
16859 auto_pin_cfg_labels[i];
16860 imux->items[imux->num_items].index = idx;
16868 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16869 hda_nid_t nid, int pin_type,
16872 alc_set_pin_output(codec, nid, pin_type);
16873 /* need the manual connection? */
16874 if (alc880_is_multi_pin(nid)) {
16875 struct alc_spec *spec = codec->spec;
16876 int idx = alc880_multi_pin_idx(nid);
16877 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16878 AC_VERB_SET_CONNECT_SEL,
16879 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16883 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16885 struct alc_spec *spec = codec->spec;
16888 for (i = 0; i <= HDA_SIDE; i++) {
16889 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16890 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16892 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16897 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16899 struct alc_spec *spec = codec->spec;
16902 pin = spec->autocfg.hp_pins[0];
16903 if (pin) /* connect to front */
16905 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16906 pin = spec->autocfg.speaker_pins[0];
16908 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16911 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16913 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16915 struct alc_spec *spec = codec->spec;
16918 for (i = 0; i < AUTO_PIN_LAST; i++) {
16919 hda_nid_t nid = spec->autocfg.input_pins[i];
16920 if (alc662_is_input_pin(codec, nid)) {
16921 alc_set_input_pin(codec, nid, i);
16922 if (nid != ALC662_PIN_CD_NID &&
16923 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16924 snd_hda_codec_write(codec, nid, 0,
16925 AC_VERB_SET_AMP_GAIN_MUTE,
16931 #define alc662_auto_init_input_src alc882_auto_init_input_src
16933 static int alc662_parse_auto_config(struct hda_codec *codec)
16935 struct alc_spec *spec = codec->spec;
16937 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16939 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16943 if (!spec->autocfg.line_outs)
16944 return 0; /* can't find valid BIOS pin config */
16946 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16949 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16952 err = alc662_auto_create_extra_out(spec,
16953 spec->autocfg.speaker_pins[0],
16957 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16961 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
16965 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16967 if (spec->autocfg.dig_outs)
16968 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16970 if (spec->kctls.list)
16971 add_mixer(spec, spec->kctls.list);
16973 spec->num_mux_defs = 1;
16974 spec->input_mux = &spec->private_imux[0];
16976 add_verb(spec, alc662_auto_init_verbs);
16977 if (codec->vendor_id == 0x10ec0663)
16978 add_verb(spec, alc663_auto_init_verbs);
16980 err = alc_auto_add_mic_boost(codec);
16984 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
16989 /* additional initialization for auto-configuration model */
16990 static void alc662_auto_init(struct hda_codec *codec)
16992 struct alc_spec *spec = codec->spec;
16993 alc662_auto_init_multi_out(codec);
16994 alc662_auto_init_hp_out(codec);
16995 alc662_auto_init_analog_input(codec);
16996 alc662_auto_init_input_src(codec);
16997 if (spec->unsol_event)
16998 alc_inithook(codec);
17001 static int patch_alc662(struct hda_codec *codec)
17003 struct alc_spec *spec;
17004 int err, board_config;
17006 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17010 codec->spec = spec;
17012 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17014 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17017 if (board_config < 0) {
17018 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17019 "trying auto-probe from BIOS...\n", codec->chip_name);
17020 board_config = ALC662_AUTO;
17023 if (board_config == ALC662_AUTO) {
17024 /* automatic parse from the BIOS config */
17025 err = alc662_parse_auto_config(codec);
17031 "hda_codec: Cannot set up configuration "
17032 "from BIOS. Using base mode...\n");
17033 board_config = ALC662_3ST_2ch_DIG;
17037 err = snd_hda_attach_beep_device(codec, 0x1);
17043 if (board_config != ALC662_AUTO)
17044 setup_preset(spec, &alc662_presets[board_config]);
17046 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17047 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17049 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17050 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17052 spec->adc_nids = alc662_adc_nids;
17053 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17054 spec->capsrc_nids = alc662_capsrc_nids;
17055 spec->capture_style = CAPT_MIX;
17057 if (!spec->cap_mixer)
17058 set_capture_mixer(spec);
17059 if (codec->vendor_id == 0x10ec0662)
17060 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17062 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17064 spec->vmaster_nid = 0x02;
17066 codec->patch_ops = alc_patch_ops;
17067 if (board_config == ALC662_AUTO)
17068 spec->init_hook = alc662_auto_init;
17069 #ifdef CONFIG_SND_HDA_POWER_SAVE
17070 if (!spec->loopback.amplist)
17071 spec->loopback.amplist = alc662_loopbacks;
17073 codec->proc_widget_hook = print_realtek_coef;
17081 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17082 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17083 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17084 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17085 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17086 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17087 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17088 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17089 .patch = patch_alc861 },
17090 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17091 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17092 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17093 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17094 .patch = patch_alc883 },
17095 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17096 .patch = patch_alc662 },
17097 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17098 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17099 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17100 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17101 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17102 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17103 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17104 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17105 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17106 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17107 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17108 .patch = patch_alc883 },
17109 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17110 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17111 {} /* terminator */
17114 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17116 MODULE_LICENSE("GPL");
17117 MODULE_DESCRIPTION("Realtek HD-audio codec");
17119 static struct hda_codec_preset_list realtek_list = {
17120 .preset = snd_hda_preset_realtek,
17121 .owner = THIS_MODULE,
17124 static int __init patch_realtek_init(void)
17126 return snd_hda_add_codec_preset(&realtek_list);
17129 static void __exit patch_realtek_exit(void)
17131 snd_hda_delete_codec_preset(&realtek_list);
17134 module_init(patch_realtek_init)
17135 module_exit(patch_realtek_exit)