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)
792 else if (pincap & AC_PINCAP_VREF_50)
794 else if (pincap & AC_PINCAP_VREF_100)
796 else if (pincap & AC_PINCAP_VREF_GRD)
799 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
804 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
806 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
808 spec->mixers[spec->num_mixers++] = mix;
811 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
813 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
815 spec->init_verbs[spec->num_init_verbs++] = verb;
818 #ifdef CONFIG_PROC_FS
822 static void print_realtek_coef(struct snd_info_buffer *buffer,
823 struct hda_codec *codec, hda_nid_t nid)
829 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
830 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
831 coeff = snd_hda_codec_read(codec, nid, 0,
832 AC_VERB_GET_COEF_INDEX, 0);
833 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
836 #define print_realtek_coef NULL
840 * set up from the preset table
842 static void setup_preset(struct alc_spec *spec,
843 const struct alc_config_preset *preset)
847 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
848 add_mixer(spec, preset->mixers[i]);
849 spec->cap_mixer = preset->cap_mixer;
850 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
852 add_verb(spec, preset->init_verbs[i]);
854 spec->channel_mode = preset->channel_mode;
855 spec->num_channel_mode = preset->num_channel_mode;
856 spec->need_dac_fix = preset->need_dac_fix;
858 spec->multiout.max_channels = spec->channel_mode[0].channels;
860 spec->multiout.num_dacs = preset->num_dacs;
861 spec->multiout.dac_nids = preset->dac_nids;
862 spec->multiout.dig_out_nid = preset->dig_out_nid;
863 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
864 spec->multiout.hp_nid = preset->hp_nid;
866 spec->num_mux_defs = preset->num_mux_defs;
867 if (!spec->num_mux_defs)
868 spec->num_mux_defs = 1;
869 spec->input_mux = preset->input_mux;
871 spec->num_adc_nids = preset->num_adc_nids;
872 spec->adc_nids = preset->adc_nids;
873 spec->capsrc_nids = preset->capsrc_nids;
874 spec->dig_in_nid = preset->dig_in_nid;
876 spec->unsol_event = preset->unsol_event;
877 spec->init_hook = preset->init_hook;
878 #ifdef CONFIG_SND_HDA_POWER_SAVE
879 spec->loopback.amplist = preset->loopbacks;
883 /* Enable GPIO mask and set output */
884 static struct hda_verb alc_gpio1_init_verbs[] = {
885 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
886 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
887 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
891 static struct hda_verb alc_gpio2_init_verbs[] = {
892 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
893 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
894 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
898 static struct hda_verb alc_gpio3_init_verbs[] = {
899 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
900 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
901 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
906 * Fix hardware PLL issue
907 * On some codecs, the analog PLL gating control must be off while
908 * the default value is 1.
910 static void alc_fix_pll(struct hda_codec *codec)
912 struct alc_spec *spec = codec->spec;
917 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
919 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
920 AC_VERB_GET_PROC_COEF, 0);
921 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
923 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
924 val & ~(1 << spec->pll_coef_bit));
927 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
928 unsigned int coef_idx, unsigned int coef_bit)
930 struct alc_spec *spec = codec->spec;
932 spec->pll_coef_idx = coef_idx;
933 spec->pll_coef_bit = coef_bit;
937 static void alc_automute_pin(struct hda_codec *codec)
939 struct alc_spec *spec = codec->spec;
940 unsigned int present;
941 unsigned int nid = spec->autocfg.hp_pins[0];
944 /* need to execute and sync at first */
945 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
946 present = snd_hda_codec_read(codec, nid, 0,
947 AC_VERB_GET_PIN_SENSE, 0);
948 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
949 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
950 nid = spec->autocfg.speaker_pins[i];
953 snd_hda_codec_write(codec, nid, 0,
954 AC_VERB_SET_PIN_WIDGET_CONTROL,
955 spec->jack_present ? 0 : PIN_OUT);
959 #if 0 /* it's broken in some acses -- temporarily disabled */
960 static void alc_mic_automute(struct hda_codec *codec)
962 struct alc_spec *spec = codec->spec;
963 unsigned int present;
964 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
965 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
966 unsigned int mix_nid = spec->capsrc_nids[0];
967 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
969 capsrc_idx_mic = mic_nid - 0x18;
970 capsrc_idx_fmic = fmic_nid - 0x18;
971 present = snd_hda_codec_read(codec, mic_nid, 0,
972 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
973 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
974 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
975 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
976 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
977 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
978 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
981 #define alc_mic_automute(codec) do {} while(0) /* NOP */
982 #endif /* disabled */
984 /* unsolicited event for HP jack sensing */
985 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
987 if (codec->vendor_id == 0x10ec0880)
992 case ALC880_HP_EVENT:
993 alc_automute_pin(codec);
995 case ALC880_MIC_EVENT:
996 alc_mic_automute(codec);
1001 static void alc_inithook(struct hda_codec *codec)
1003 alc_automute_pin(codec);
1004 alc_mic_automute(codec);
1007 /* additional initialization for ALC888 variants */
1008 static void alc888_coef_init(struct hda_codec *codec)
1012 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1013 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1014 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1015 if ((tmp & 0xf0) == 0x20)
1017 snd_hda_codec_read(codec, 0x20, 0,
1018 AC_VERB_SET_PROC_COEF, 0x830);
1021 snd_hda_codec_read(codec, 0x20, 0,
1022 AC_VERB_SET_PROC_COEF, 0x3030);
1025 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1030 case ALC_INIT_GPIO1:
1031 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1033 case ALC_INIT_GPIO2:
1034 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1036 case ALC_INIT_GPIO3:
1037 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1039 case ALC_INIT_DEFAULT:
1040 switch (codec->vendor_id) {
1042 snd_hda_codec_write(codec, 0x0f, 0,
1043 AC_VERB_SET_EAPD_BTLENABLE, 2);
1044 snd_hda_codec_write(codec, 0x10, 0,
1045 AC_VERB_SET_EAPD_BTLENABLE, 2);
1057 snd_hda_codec_write(codec, 0x14, 0,
1058 AC_VERB_SET_EAPD_BTLENABLE, 2);
1059 snd_hda_codec_write(codec, 0x15, 0,
1060 AC_VERB_SET_EAPD_BTLENABLE, 2);
1063 switch (codec->vendor_id) {
1065 snd_hda_codec_write(codec, 0x1a, 0,
1066 AC_VERB_SET_COEF_INDEX, 7);
1067 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1068 AC_VERB_GET_PROC_COEF, 0);
1069 snd_hda_codec_write(codec, 0x1a, 0,
1070 AC_VERB_SET_COEF_INDEX, 7);
1071 snd_hda_codec_write(codec, 0x1a, 0,
1072 AC_VERB_SET_PROC_COEF,
1082 snd_hda_codec_write(codec, 0x20, 0,
1083 AC_VERB_SET_COEF_INDEX, 7);
1084 tmp = snd_hda_codec_read(codec, 0x20, 0,
1085 AC_VERB_GET_PROC_COEF, 0);
1086 snd_hda_codec_write(codec, 0x20, 0,
1087 AC_VERB_SET_COEF_INDEX, 7);
1088 snd_hda_codec_write(codec, 0x20, 0,
1089 AC_VERB_SET_PROC_COEF,
1093 alc888_coef_init(codec);
1097 snd_hda_codec_write(codec, 0x20, 0,
1098 AC_VERB_SET_COEF_INDEX, 7);
1099 tmp = snd_hda_codec_read(codec, 0x20, 0,
1100 AC_VERB_GET_PROC_COEF, 0);
1101 snd_hda_codec_write(codec, 0x20, 0,
1102 AC_VERB_SET_COEF_INDEX, 7);
1103 snd_hda_codec_write(codec, 0x20, 0,
1104 AC_VERB_SET_PROC_COEF,
1112 static void alc_init_auto_hp(struct hda_codec *codec)
1114 struct alc_spec *spec = codec->spec;
1116 if (!spec->autocfg.hp_pins[0])
1119 if (!spec->autocfg.speaker_pins[0]) {
1120 if (spec->autocfg.line_out_pins[0] &&
1121 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1122 spec->autocfg.speaker_pins[0] =
1123 spec->autocfg.line_out_pins[0];
1128 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1129 spec->autocfg.hp_pins[0]);
1130 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1131 AC_VERB_SET_UNSOLICITED_ENABLE,
1132 AC_USRSP_EN | ALC880_HP_EVENT);
1133 spec->unsol_event = alc_sku_unsol_event;
1136 /* check subsystem ID and set up device-specific initialization;
1137 * return 1 if initialized, 0 if invalid SSID
1139 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1140 * 31 ~ 16 : Manufacture ID
1142 * 7 ~ 0 : Assembly ID
1143 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1145 static int alc_subsystem_id(struct hda_codec *codec,
1146 hda_nid_t porta, hda_nid_t porte,
1149 unsigned int ass, tmp, i;
1151 struct alc_spec *spec = codec->spec;
1153 ass = codec->subsystem_id & 0xffff;
1154 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1157 /* invalid SSID, check the special NID pin defcfg instead */
1159 * 31~30 : port conetcivity
1162 * 19~16 : Check sum (15:1)
1167 if (codec->vendor_id == 0x10ec0260)
1169 ass = snd_hda_codec_get_pincfg(codec, nid);
1170 snd_printd("realtek: No valid SSID, "
1171 "checking pincfg 0x%08x for NID 0x%x\n",
1173 if (!(ass & 1) && !(ass & 0x100000))
1175 if ((ass >> 30) != 1) /* no physical connection */
1180 for (i = 1; i < 16; i++) {
1184 if (((ass >> 16) & 0xf) != tmp)
1187 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1188 ass & 0xffff, codec->vendor_id);
1192 * 2 : 0 --> Desktop, 1 --> Laptop
1193 * 3~5 : External Amplifier control
1196 tmp = (ass & 0x38) >> 3; /* external Amp control */
1199 spec->init_amp = ALC_INIT_GPIO1;
1202 spec->init_amp = ALC_INIT_GPIO2;
1205 spec->init_amp = ALC_INIT_GPIO3;
1208 spec->init_amp = ALC_INIT_DEFAULT;
1212 /* is laptop or Desktop and enable the function "Mute internal speaker
1213 * when the external headphone out jack is plugged"
1215 if (!(ass & 0x8000))
1218 * 10~8 : Jack location
1219 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1221 * 15 : 1 --> enable the function "Mute internal speaker
1222 * when the external headphone out jack is plugged"
1224 if (!spec->autocfg.hp_pins[0]) {
1225 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1227 spec->autocfg.hp_pins[0] = porta;
1229 spec->autocfg.hp_pins[0] = porte;
1231 spec->autocfg.hp_pins[0] = portd;
1236 alc_init_auto_hp(codec);
1240 static void alc_ssid_check(struct hda_codec *codec,
1241 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1243 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1244 struct alc_spec *spec = codec->spec;
1245 snd_printd("realtek: "
1246 "Enable default setup for auto mode as fallback\n");
1247 spec->init_amp = ALC_INIT_DEFAULT;
1248 alc_init_auto_hp(codec);
1253 * Fix-up pin default configurations
1261 static void alc_fix_pincfg(struct hda_codec *codec,
1262 const struct snd_pci_quirk *quirk,
1263 const struct alc_pincfg **pinfix)
1265 const struct alc_pincfg *cfg;
1267 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1271 cfg = pinfix[quirk->value];
1272 for (; cfg->nid; cfg++)
1273 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1283 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1284 /* Mic-in jack as mic in */
1285 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1286 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1287 /* Line-in jack as Line in */
1288 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1289 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1290 /* Line-Out as Front */
1291 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1298 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1299 /* Mic-in jack as mic in */
1300 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1301 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1302 /* Line-in jack as Surround */
1303 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1304 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1305 /* Line-Out as Front */
1306 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1313 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1314 /* Mic-in jack as CLFE */
1315 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1316 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1317 /* Line-in jack as Surround */
1318 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1319 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1320 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1321 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1328 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1329 /* Mic-in jack as CLFE */
1330 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1331 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1332 /* Line-in jack as Surround */
1333 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1334 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1335 /* Line-Out as Side */
1336 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1340 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1341 { 2, alc888_4ST_ch2_intel_init },
1342 { 4, alc888_4ST_ch4_intel_init },
1343 { 6, alc888_4ST_ch6_intel_init },
1344 { 8, alc888_4ST_ch8_intel_init },
1348 * ALC888 Fujitsu Siemens Amillo xa3530
1351 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1352 /* Front Mic: set to PIN_IN (empty by default) */
1353 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1354 /* Connect Internal HP to Front */
1355 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1356 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1357 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1358 /* Connect Bass HP to Front */
1359 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1362 /* Connect Line-Out side jack (SPDIF) to Side */
1363 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1364 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1365 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1366 /* Connect Mic jack to CLFE */
1367 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1368 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1370 /* Connect Line-in jack to Surround */
1371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1372 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1373 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1374 /* Connect HP out jack to Front */
1375 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1377 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1378 /* Enable unsolicited event for HP jack and Line-out jack */
1379 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1380 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1384 static void alc_automute_amp(struct hda_codec *codec)
1386 struct alc_spec *spec = codec->spec;
1387 unsigned int val, mute;
1391 spec->jack_present = 0;
1392 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1393 nid = spec->autocfg.hp_pins[i];
1396 val = snd_hda_codec_read(codec, nid, 0,
1397 AC_VERB_GET_PIN_SENSE, 0);
1398 if (val & AC_PINSENSE_PRESENCE) {
1399 spec->jack_present = 1;
1404 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1405 /* Toggle internal speakers muting */
1406 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1407 nid = spec->autocfg.speaker_pins[i];
1410 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1411 HDA_AMP_MUTE, mute);
1415 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1418 if (codec->vendor_id == 0x10ec0880)
1422 if (res == ALC880_HP_EVENT)
1423 alc_automute_amp(codec);
1426 static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1428 struct alc_spec *spec = codec->spec;
1430 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1431 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1432 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1433 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1434 alc_automute_amp(codec);
1438 * ALC888 Acer Aspire 4930G model
1441 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1442 /* Front Mic: set to PIN_IN (empty by default) */
1443 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1444 /* Unselect Front Mic by default in input mixer 3 */
1445 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1446 /* Enable unsolicited event for HP jack */
1447 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1448 /* Connect Internal HP to front */
1449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1450 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1451 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1452 /* Connect HP out to front */
1453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1459 static struct hda_input_mux alc888_2_capture_sources[2] = {
1460 /* Front mic only available on one ADC */
1467 { "Front Mic", 0xb },
1480 static struct snd_kcontrol_new alc888_base_mixer[] = {
1481 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1482 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1483 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1484 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1485 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1487 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1488 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1489 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1490 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1491 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1492 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1493 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1494 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1495 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1496 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1497 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1498 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1502 static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1504 struct alc_spec *spec = codec->spec;
1506 spec->autocfg.hp_pins[0] = 0x15;
1507 spec->autocfg.speaker_pins[0] = 0x14;
1508 alc_automute_amp(codec);
1512 * ALC880 3-stack model
1514 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1515 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1516 * F-Mic = 0x1b, HP = 0x19
1519 static hda_nid_t alc880_dac_nids[4] = {
1520 /* front, rear, clfe, rear_surr */
1521 0x02, 0x05, 0x04, 0x03
1524 static hda_nid_t alc880_adc_nids[3] = {
1529 /* The datasheet says the node 0x07 is connected from inputs,
1530 * but it shows zero connection in the real implementation on some devices.
1531 * Note: this is a 915GAV bug, fixed on 915GLV
1533 static hda_nid_t alc880_adc_nids_alt[2] = {
1538 #define ALC880_DIGOUT_NID 0x06
1539 #define ALC880_DIGIN_NID 0x0a
1541 static struct hda_input_mux alc880_capture_source = {
1545 { "Front Mic", 0x3 },
1551 /* channel source setting (2/6 channel selection for 3-stack) */
1553 static struct hda_verb alc880_threestack_ch2_init[] = {
1554 /* set line-in to input, mute it */
1555 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1556 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1557 /* set mic-in to input vref 80%, mute it */
1558 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1559 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1564 static struct hda_verb alc880_threestack_ch6_init[] = {
1565 /* set line-in to output, unmute it */
1566 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1567 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1568 /* set mic-in to output, unmute it */
1569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1574 static struct hda_channel_mode alc880_threestack_modes[2] = {
1575 { 2, alc880_threestack_ch2_init },
1576 { 6, alc880_threestack_ch6_init },
1579 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1580 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1581 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1582 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1583 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1584 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1585 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1586 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1587 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1588 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1589 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1590 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1591 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1592 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1594 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1595 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1599 .name = "Channel Mode",
1600 .info = alc_ch_mode_info,
1601 .get = alc_ch_mode_get,
1602 .put = alc_ch_mode_put,
1607 /* capture mixer elements */
1608 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1609 struct snd_ctl_elem_info *uinfo)
1611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1612 struct alc_spec *spec = codec->spec;
1615 mutex_lock(&codec->control_mutex);
1616 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1618 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1619 mutex_unlock(&codec->control_mutex);
1623 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1624 unsigned int size, unsigned int __user *tlv)
1626 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1627 struct alc_spec *spec = codec->spec;
1630 mutex_lock(&codec->control_mutex);
1631 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1633 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1634 mutex_unlock(&codec->control_mutex);
1638 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1639 struct snd_ctl_elem_value *ucontrol);
1641 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_value *ucontrol,
1645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1646 struct alc_spec *spec = codec->spec;
1647 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1650 mutex_lock(&codec->control_mutex);
1651 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1653 err = func(kcontrol, ucontrol);
1654 mutex_unlock(&codec->control_mutex);
1658 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol)
1661 return alc_cap_getput_caller(kcontrol, ucontrol,
1662 snd_hda_mixer_amp_volume_get);
1665 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1666 struct snd_ctl_elem_value *ucontrol)
1668 return alc_cap_getput_caller(kcontrol, ucontrol,
1669 snd_hda_mixer_amp_volume_put);
1672 /* capture mixer elements */
1673 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1675 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1676 struct snd_ctl_elem_value *ucontrol)
1678 return alc_cap_getput_caller(kcontrol, ucontrol,
1679 snd_hda_mixer_amp_switch_get);
1682 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1683 struct snd_ctl_elem_value *ucontrol)
1685 return alc_cap_getput_caller(kcontrol, ucontrol,
1686 snd_hda_mixer_amp_switch_put);
1689 #define _DEFINE_CAPMIX(num) \
1691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1692 .name = "Capture Switch", \
1693 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1695 .info = alc_cap_sw_info, \
1696 .get = alc_cap_sw_get, \
1697 .put = alc_cap_sw_put, \
1700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1701 .name = "Capture Volume", \
1702 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1703 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1704 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1706 .info = alc_cap_vol_info, \
1707 .get = alc_cap_vol_get, \
1708 .put = alc_cap_vol_put, \
1709 .tlv = { .c = alc_cap_vol_tlv }, \
1712 #define _DEFINE_CAPSRC(num) \
1714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1715 /* .name = "Capture Source", */ \
1716 .name = "Input Source", \
1718 .info = alc_mux_enum_info, \
1719 .get = alc_mux_enum_get, \
1720 .put = alc_mux_enum_put, \
1723 #define DEFINE_CAPMIX(num) \
1724 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1725 _DEFINE_CAPMIX(num), \
1726 _DEFINE_CAPSRC(num), \
1730 #define DEFINE_CAPMIX_NOSRC(num) \
1731 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1732 _DEFINE_CAPMIX(num), \
1736 /* up to three ADCs */
1740 DEFINE_CAPMIX_NOSRC(1);
1741 DEFINE_CAPMIX_NOSRC(2);
1742 DEFINE_CAPMIX_NOSRC(3);
1745 * ALC880 5-stack model
1747 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1749 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1750 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1753 /* additional mixers to alc880_three_stack_mixer */
1754 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1755 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1756 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1760 /* channel source setting (6/8 channel selection for 5-stack) */
1762 static struct hda_verb alc880_fivestack_ch6_init[] = {
1763 /* set line-in to input, mute it */
1764 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1765 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1770 static struct hda_verb alc880_fivestack_ch8_init[] = {
1771 /* set line-in to output, unmute it */
1772 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1773 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1777 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1778 { 6, alc880_fivestack_ch6_init },
1779 { 8, alc880_fivestack_ch8_init },
1784 * ALC880 6-stack model
1786 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1787 * Side = 0x05 (0x0f)
1788 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1789 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1792 static hda_nid_t alc880_6st_dac_nids[4] = {
1793 /* front, rear, clfe, rear_surr */
1794 0x02, 0x03, 0x04, 0x05
1797 static struct hda_input_mux alc880_6stack_capture_source = {
1801 { "Front Mic", 0x1 },
1807 /* fixed 8-channels */
1808 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1812 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1813 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1814 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1815 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1816 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1817 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1818 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1819 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1820 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1821 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1822 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1823 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1824 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1825 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1826 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1827 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1828 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1829 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1830 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1833 .name = "Channel Mode",
1834 .info = alc_ch_mode_info,
1835 .get = alc_ch_mode_get,
1836 .put = alc_ch_mode_put,
1845 * W810 has rear IO for:
1848 * Center/LFE (DAC 04)
1851 * The system also has a pair of internal speakers, and a headphone jack.
1852 * These are both connected to Line2 on the codec, hence to DAC 02.
1854 * There is a variable resistor to control the speaker or headphone
1855 * volume. This is a hardware-only device without a software API.
1857 * Plugging headphones in will disable the internal speakers. This is
1858 * implemented in hardware, not via the driver using jack sense. In
1859 * a similar fashion, plugging into the rear socket marked "front" will
1860 * disable both the speakers and headphones.
1862 * For input, there's a microphone jack, and an "audio in" jack.
1863 * These may not do anything useful with this driver yet, because I
1864 * haven't setup any initialization verbs for these yet...
1867 static hda_nid_t alc880_w810_dac_nids[3] = {
1868 /* front, rear/surround, clfe */
1872 /* fixed 6 channels */
1873 static struct hda_channel_mode alc880_w810_modes[1] = {
1877 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1878 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1880 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1881 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1882 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1883 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1884 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1885 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1886 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1887 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1895 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1896 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1900 static hda_nid_t alc880_z71v_dac_nids[1] = {
1903 #define ALC880_Z71V_HP_DAC 0x03
1905 /* fixed 2 channels */
1906 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1910 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1911 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1912 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1913 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1914 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1915 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1916 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1924 * ALC880 F1734 model
1926 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1927 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1930 static hda_nid_t alc880_f1734_dac_nids[1] = {
1933 #define ALC880_F1734_HP_DAC 0x02
1935 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1936 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1937 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1938 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1939 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1942 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1943 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1947 static struct hda_input_mux alc880_f1734_capture_source = {
1959 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1960 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1961 * Mic = 0x18, Line = 0x1a
1964 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1965 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1967 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1968 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1969 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1970 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1971 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1972 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1973 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1974 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1975 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1976 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1977 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1984 .name = "Channel Mode",
1985 .info = alc_ch_mode_info,
1986 .get = alc_ch_mode_get,
1987 .put = alc_ch_mode_put,
1993 * ALC880 ASUS W1V model
1995 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1996 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1997 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2000 /* additional mixers to alc880_asus_mixer */
2001 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2002 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2003 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2008 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2009 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2010 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2012 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2013 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2014 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2015 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2016 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2017 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2022 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2023 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2024 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2025 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2026 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2027 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2028 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2029 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2030 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2031 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2032 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2034 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2035 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2036 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2037 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2038 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2041 .name = "Channel Mode",
2042 .info = alc_ch_mode_info,
2043 .get = alc_ch_mode_get,
2044 .put = alc_ch_mode_put,
2049 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2050 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2051 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2052 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2053 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2054 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2055 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2056 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2057 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2058 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2059 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2063 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2064 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2065 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2066 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2067 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2074 * virtual master controls
2078 * slave controls for virtual master
2080 static const char *alc_slave_vols[] = {
2081 "Front Playback Volume",
2082 "Surround Playback Volume",
2083 "Center Playback Volume",
2084 "LFE Playback Volume",
2085 "Side Playback Volume",
2086 "Headphone Playback Volume",
2087 "Speaker Playback Volume",
2088 "Mono Playback Volume",
2089 "Line-Out Playback Volume",
2090 "PCM Playback Volume",
2094 static const char *alc_slave_sws[] = {
2095 "Front Playback Switch",
2096 "Surround Playback Switch",
2097 "Center Playback Switch",
2098 "LFE Playback Switch",
2099 "Side Playback Switch",
2100 "Headphone Playback Switch",
2101 "Speaker Playback Switch",
2102 "Mono Playback Switch",
2103 "IEC958 Playback Switch",
2108 * build control elements
2111 static void alc_free_kctls(struct hda_codec *codec);
2113 /* additional beep mixers; the actual parameters are overwritten at build */
2114 static struct snd_kcontrol_new alc_beep_mixer[] = {
2115 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2116 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2120 static int alc_build_controls(struct hda_codec *codec)
2122 struct alc_spec *spec = codec->spec;
2126 for (i = 0; i < spec->num_mixers; i++) {
2127 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2131 if (spec->cap_mixer) {
2132 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2136 if (spec->multiout.dig_out_nid) {
2137 err = snd_hda_create_spdif_out_ctls(codec,
2138 spec->multiout.dig_out_nid);
2141 if (!spec->no_analog) {
2142 err = snd_hda_create_spdif_share_sw(codec,
2146 spec->multiout.share_spdif = 1;
2149 if (spec->dig_in_nid) {
2150 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2155 /* create beep controls if needed */
2156 if (spec->beep_amp) {
2157 struct snd_kcontrol_new *knew;
2158 for (knew = alc_beep_mixer; knew->name; knew++) {
2159 struct snd_kcontrol *kctl;
2160 kctl = snd_ctl_new1(knew, codec);
2163 kctl->private_value = spec->beep_amp;
2164 err = snd_hda_ctl_add(codec, kctl);
2170 /* if we have no master control, let's create it */
2171 if (!spec->no_analog &&
2172 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2173 unsigned int vmaster_tlv[4];
2174 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2175 HDA_OUTPUT, vmaster_tlv);
2176 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2177 vmaster_tlv, alc_slave_vols);
2181 if (!spec->no_analog &&
2182 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2183 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2184 NULL, alc_slave_sws);
2189 alc_free_kctls(codec); /* no longer needed */
2195 * initialize the codec volumes, etc
2199 * generic initialization of ADC, input mixers and output mixers
2201 static struct hda_verb alc880_volume_init_verbs[] = {
2203 * Unmute ADC0-2 and set the default input to mic-in
2205 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2206 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2207 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2209 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2210 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2212 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2214 * Note: PASD motherboards uses the Line In 2 as the input for front
2217 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2218 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2219 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2220 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2221 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2222 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2223 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2224 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2227 * Set up output mixers (0x0c - 0x0f)
2229 /* set vol=0 to output mixers */
2230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2231 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2234 /* set up input amps for analog loopback */
2235 /* Amp Indices: DAC = 0, mixer = 1 */
2236 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2237 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2238 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2239 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2240 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2241 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2242 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2243 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2249 * 3-stack pin configuration:
2250 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2252 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2254 * preset connection lists of input pins
2255 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2257 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2258 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2259 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2262 * Set pin mode and muting
2264 /* set front pin widgets 0x14 for output */
2265 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2266 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2267 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2269 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2270 /* Mic2 (as headphone out) for HP output */
2271 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2272 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2273 /* Line In pin widget for input */
2274 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2275 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2276 /* Line2 (as front mic) pin widget for input and vref at 80% */
2277 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2278 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2279 /* CD pin widget for input */
2280 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2286 * 5-stack pin configuration:
2287 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2288 * line-in/side = 0x1a, f-mic = 0x1b
2290 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2292 * preset connection lists of input pins
2293 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2295 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2296 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2299 * Set pin mode and muting
2301 /* set pin widgets 0x14-0x17 for output */
2302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2303 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2304 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2305 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2306 /* unmute pins for output (no gain on this amp) */
2307 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2309 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2312 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2313 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2314 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2315 /* Mic2 (as headphone out) for HP output */
2316 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2318 /* Line In pin widget for input */
2319 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2320 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2321 /* Line2 (as front mic) pin widget for input and vref at 80% */
2322 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2323 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2324 /* CD pin widget for input */
2325 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2331 * W810 pin configuration:
2332 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2334 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2335 /* hphone/speaker input selector: front DAC */
2336 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2341 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2342 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2343 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2345 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2346 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2352 * Z71V pin configuration:
2353 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2355 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2359 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2361 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2362 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2363 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2364 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2370 * 6-stack pin configuration:
2371 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2372 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2374 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2375 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2377 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2378 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2379 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2380 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2381 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2382 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2383 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2384 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2386 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2388 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2389 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2390 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2391 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2393 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2394 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2400 * Uniwill pin configuration:
2401 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2404 static struct hda_verb alc880_uniwill_init_verbs[] = {
2405 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2408 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2409 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2410 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2411 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2412 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2413 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2414 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2422 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2423 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2427 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2428 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2429 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2430 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2432 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2433 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2440 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2442 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2443 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2445 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2446 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2447 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2448 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2449 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2451 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2452 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2454 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2455 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2458 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2459 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2460 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2461 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2462 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2463 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2465 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2466 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2471 static struct hda_verb alc880_beep_init_verbs[] = {
2472 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2476 /* auto-toggle front mic */
2477 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2479 unsigned int present;
2482 present = snd_hda_codec_read(codec, 0x18, 0,
2483 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2484 bits = present ? HDA_AMP_MUTE : 0;
2485 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2488 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2490 struct alc_spec *spec = codec->spec;
2492 spec->autocfg.hp_pins[0] = 0x14;
2493 spec->autocfg.speaker_pins[0] = 0x15;
2494 spec->autocfg.speaker_pins[0] = 0x16;
2495 alc_automute_amp(codec);
2496 alc880_uniwill_mic_automute(codec);
2499 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2502 /* Looks like the unsol event is incompatible with the standard
2503 * definition. 4bit tag is placed at 28 bit!
2505 switch (res >> 28) {
2506 case ALC880_MIC_EVENT:
2507 alc880_uniwill_mic_automute(codec);
2510 alc_automute_amp_unsol_event(codec, res);
2515 static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2517 struct alc_spec *spec = codec->spec;
2519 spec->autocfg.hp_pins[0] = 0x14;
2520 spec->autocfg.speaker_pins[0] = 0x15;
2521 alc_automute_amp(codec);
2524 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2526 unsigned int present;
2528 present = snd_hda_codec_read(codec, 0x21, 0,
2529 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2530 present &= HDA_AMP_VOLMASK;
2531 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2532 HDA_AMP_VOLMASK, present);
2533 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2534 HDA_AMP_VOLMASK, present);
2537 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2540 /* Looks like the unsol event is incompatible with the standard
2541 * definition. 4bit tag is placed at 28 bit!
2543 if ((res >> 28) == ALC880_DCVOL_EVENT)
2544 alc880_uniwill_p53_dcvol_automute(codec);
2546 alc_automute_amp_unsol_event(codec, res);
2550 * F1734 pin configuration:
2551 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2553 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2554 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2555 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2556 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2557 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2558 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2562 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2565 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2567 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2568 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2569 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2570 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2571 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2572 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2573 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2575 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2576 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2582 * ASUS pin configuration:
2583 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2585 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2586 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2587 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2588 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2589 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2591 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2592 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2594 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2595 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2597 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2598 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2600 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2601 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2602 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2603 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2604 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2605 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2606 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2607 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2608 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2613 /* Enable GPIO mask and set output */
2614 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2615 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2617 /* Clevo m520g init */
2618 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2619 /* headphone output */
2620 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2622 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2623 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2625 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2626 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2628 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2629 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2630 /* Mic1 (rear panel) */
2631 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2633 /* Mic2 (front panel) */
2634 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2635 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2638 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2639 /* change to EAPD mode */
2640 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2641 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2646 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2647 /* change to EAPD mode */
2648 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2649 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2651 /* Headphone output */
2652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2654 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2655 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2657 /* Line In pin widget for input */
2658 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2659 /* CD pin widget for input */
2660 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2661 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2662 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2664 /* change to EAPD mode */
2665 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2666 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2672 * LG m1 express dual
2675 * Rear Line-In/Out (blue): 0x14
2676 * Build-in Mic-In: 0x15
2678 * HP-Out (green): 0x1b
2679 * Mic-In/Out (red): 0x19
2683 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2684 static hda_nid_t alc880_lg_dac_nids[3] = {
2688 /* seems analog CD is not working */
2689 static struct hda_input_mux alc880_lg_capture_source = {
2694 { "Internal Mic", 0x6 },
2698 /* 2,4,6 channel modes */
2699 static struct hda_verb alc880_lg_ch2_init[] = {
2700 /* set line-in and mic-in to input */
2701 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2702 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2706 static struct hda_verb alc880_lg_ch4_init[] = {
2707 /* set line-in to out and mic-in to input */
2708 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2709 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2713 static struct hda_verb alc880_lg_ch6_init[] = {
2714 /* set line-in and mic-in to output */
2715 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2716 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2720 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2721 { 2, alc880_lg_ch2_init },
2722 { 4, alc880_lg_ch4_init },
2723 { 6, alc880_lg_ch6_init },
2726 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2727 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2728 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2730 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2731 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2732 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2733 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2734 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2735 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2736 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2737 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2738 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2739 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2740 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2743 .name = "Channel Mode",
2744 .info = alc_ch_mode_info,
2745 .get = alc_ch_mode_get,
2746 .put = alc_ch_mode_put,
2751 static struct hda_verb alc880_lg_init_verbs[] = {
2752 /* set capture source to mic-in */
2753 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2754 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2756 /* mute all amp mixer inputs */
2757 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2758 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2759 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2760 /* line-in to input */
2761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2762 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2764 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2765 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2767 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2768 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2769 /* mic-in to input */
2770 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2771 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2774 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2775 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2776 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2778 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2782 /* toggle speaker-output according to the hp-jack state */
2783 static void alc880_lg_init_hook(struct hda_codec *codec)
2785 struct alc_spec *spec = codec->spec;
2787 spec->autocfg.hp_pins[0] = 0x1b;
2788 spec->autocfg.speaker_pins[0] = 0x17;
2789 alc_automute_amp(codec);
2798 * Built-in Mic-In: 0x19
2804 static struct hda_input_mux alc880_lg_lw_capture_source = {
2808 { "Internal Mic", 0x1 },
2813 #define alc880_lg_lw_modes alc880_threestack_modes
2815 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2816 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2817 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2818 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2819 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2820 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2821 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2822 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2823 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2824 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2825 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2828 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2829 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2832 .name = "Channel Mode",
2833 .info = alc_ch_mode_info,
2834 .get = alc_ch_mode_get,
2835 .put = alc_ch_mode_put,
2840 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2841 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2842 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2843 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2845 /* set capture source to mic-in */
2846 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2847 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2848 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2854 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2855 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2856 /* mic-in to input */
2857 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2858 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2860 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2861 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2863 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2867 /* toggle speaker-output according to the hp-jack state */
2868 static void alc880_lg_lw_init_hook(struct hda_codec *codec)
2870 struct alc_spec *spec = codec->spec;
2872 spec->autocfg.hp_pins[0] = 0x1b;
2873 spec->autocfg.speaker_pins[0] = 0x14;
2874 alc_automute_amp(codec);
2877 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2878 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2879 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2882 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2883 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2887 static struct hda_input_mux alc880_medion_rim_capture_source = {
2891 { "Internal Mic", 0x1 },
2895 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2896 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2898 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2901 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2902 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2903 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2904 /* Mic2 (as headphone out) for HP output */
2905 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2906 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2907 /* Internal Speaker */
2908 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2909 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2911 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2912 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2914 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2918 /* toggle speaker-output according to the hp-jack state */
2919 static void alc880_medion_rim_automute(struct hda_codec *codec)
2921 struct alc_spec *spec = codec->spec;
2922 alc_automute_amp(codec);
2924 if (spec->jack_present)
2925 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2927 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2930 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2933 /* Looks like the unsol event is incompatible with the standard
2934 * definition. 4bit tag is placed at 28 bit!
2936 if ((res >> 28) == ALC880_HP_EVENT)
2937 alc880_medion_rim_automute(codec);
2940 static void alc880_medion_rim_init_hook(struct hda_codec *codec)
2942 struct alc_spec *spec = codec->spec;
2944 spec->autocfg.hp_pins[0] = 0x14;
2945 spec->autocfg.speaker_pins[0] = 0x1b;
2946 alc880_medion_rim_automute(codec);
2949 #ifdef CONFIG_SND_HDA_POWER_SAVE
2950 static struct hda_amp_list alc880_loopbacks[] = {
2951 { 0x0b, HDA_INPUT, 0 },
2952 { 0x0b, HDA_INPUT, 1 },
2953 { 0x0b, HDA_INPUT, 2 },
2954 { 0x0b, HDA_INPUT, 3 },
2955 { 0x0b, HDA_INPUT, 4 },
2959 static struct hda_amp_list alc880_lg_loopbacks[] = {
2960 { 0x0b, HDA_INPUT, 1 },
2961 { 0x0b, HDA_INPUT, 6 },
2962 { 0x0b, HDA_INPUT, 7 },
2971 static int alc_init(struct hda_codec *codec)
2973 struct alc_spec *spec = codec->spec;
2977 alc_auto_init_amp(codec, spec->init_amp);
2979 for (i = 0; i < spec->num_init_verbs; i++)
2980 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2982 if (spec->init_hook)
2983 spec->init_hook(codec);
2988 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2990 struct alc_spec *spec = codec->spec;
2992 if (spec->unsol_event)
2993 spec->unsol_event(codec, res);
2996 #ifdef CONFIG_SND_HDA_POWER_SAVE
2997 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2999 struct alc_spec *spec = codec->spec;
3000 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3005 * Analog playback callbacks
3007 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3008 struct hda_codec *codec,
3009 struct snd_pcm_substream *substream)
3011 struct alc_spec *spec = codec->spec;
3012 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3016 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3017 struct hda_codec *codec,
3018 unsigned int stream_tag,
3019 unsigned int format,
3020 struct snd_pcm_substream *substream)
3022 struct alc_spec *spec = codec->spec;
3023 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3024 stream_tag, format, substream);
3027 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3028 struct hda_codec *codec,
3029 struct snd_pcm_substream *substream)
3031 struct alc_spec *spec = codec->spec;
3032 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3038 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3039 struct hda_codec *codec,
3040 struct snd_pcm_substream *substream)
3042 struct alc_spec *spec = codec->spec;
3043 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3046 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3047 struct hda_codec *codec,
3048 unsigned int stream_tag,
3049 unsigned int format,
3050 struct snd_pcm_substream *substream)
3052 struct alc_spec *spec = codec->spec;
3053 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3054 stream_tag, format, substream);
3057 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3058 struct hda_codec *codec,
3059 struct snd_pcm_substream *substream)
3061 struct alc_spec *spec = codec->spec;
3062 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3065 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3066 struct hda_codec *codec,
3067 struct snd_pcm_substream *substream)
3069 struct alc_spec *spec = codec->spec;
3070 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3076 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3077 struct hda_codec *codec,
3078 unsigned int stream_tag,
3079 unsigned int format,
3080 struct snd_pcm_substream *substream)
3082 struct alc_spec *spec = codec->spec;
3084 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3085 stream_tag, 0, format);
3089 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3090 struct hda_codec *codec,
3091 struct snd_pcm_substream *substream)
3093 struct alc_spec *spec = codec->spec;
3095 snd_hda_codec_cleanup_stream(codec,
3096 spec->adc_nids[substream->number + 1]);
3103 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3107 /* NID is set in alc_build_pcms */
3109 .open = alc880_playback_pcm_open,
3110 .prepare = alc880_playback_pcm_prepare,
3111 .cleanup = alc880_playback_pcm_cleanup
3115 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3119 /* NID is set in alc_build_pcms */
3122 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3126 /* NID is set in alc_build_pcms */
3129 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3130 .substreams = 2, /* can be overridden */
3133 /* NID is set in alc_build_pcms */
3135 .prepare = alc880_alt_capture_pcm_prepare,
3136 .cleanup = alc880_alt_capture_pcm_cleanup
3140 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3144 /* NID is set in alc_build_pcms */
3146 .open = alc880_dig_playback_pcm_open,
3147 .close = alc880_dig_playback_pcm_close,
3148 .prepare = alc880_dig_playback_pcm_prepare,
3149 .cleanup = alc880_dig_playback_pcm_cleanup
3153 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3157 /* NID is set in alc_build_pcms */
3160 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3161 static struct hda_pcm_stream alc_pcm_null_stream = {
3167 static int alc_build_pcms(struct hda_codec *codec)
3169 struct alc_spec *spec = codec->spec;
3170 struct hda_pcm *info = spec->pcm_rec;
3173 codec->num_pcms = 1;
3174 codec->pcm_info = info;
3176 if (spec->no_analog)
3179 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3180 "%s Analog", codec->chip_name);
3181 info->name = spec->stream_name_analog;
3183 if (spec->stream_analog_playback) {
3184 if (snd_BUG_ON(!spec->multiout.dac_nids))
3186 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3187 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3189 if (spec->stream_analog_capture) {
3190 if (snd_BUG_ON(!spec->adc_nids))
3192 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3193 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3196 if (spec->channel_mode) {
3197 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3198 for (i = 0; i < spec->num_channel_mode; i++) {
3199 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3200 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3206 /* SPDIF for stream index #1 */
3207 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3208 snprintf(spec->stream_name_digital,
3209 sizeof(spec->stream_name_digital),
3210 "%s Digital", codec->chip_name);
3211 codec->num_pcms = 2;
3212 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3213 info = spec->pcm_rec + 1;
3214 info->name = spec->stream_name_digital;
3215 if (spec->dig_out_type)
3216 info->pcm_type = spec->dig_out_type;
3218 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3219 if (spec->multiout.dig_out_nid &&
3220 spec->stream_digital_playback) {
3221 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3222 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3224 if (spec->dig_in_nid &&
3225 spec->stream_digital_capture) {
3226 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3227 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3229 /* FIXME: do we need this for all Realtek codec models? */
3230 codec->spdif_status_reset = 1;
3233 if (spec->no_analog)
3236 /* If the use of more than one ADC is requested for the current
3237 * model, configure a second analog capture-only PCM.
3239 /* Additional Analaog capture for index #2 */
3240 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3241 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3242 codec->num_pcms = 3;
3243 info = spec->pcm_rec + 2;
3244 info->name = spec->stream_name_analog;
3245 if (spec->alt_dac_nid) {
3246 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3247 *spec->stream_analog_alt_playback;
3248 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3251 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3252 alc_pcm_null_stream;
3253 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3255 if (spec->num_adc_nids > 1) {
3256 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3257 *spec->stream_analog_alt_capture;
3258 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3260 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3261 spec->num_adc_nids - 1;
3263 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3264 alc_pcm_null_stream;
3265 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3272 static void alc_free_kctls(struct hda_codec *codec)
3274 struct alc_spec *spec = codec->spec;
3276 if (spec->kctls.list) {
3277 struct snd_kcontrol_new *kctl = spec->kctls.list;
3279 for (i = 0; i < spec->kctls.used; i++)
3280 kfree(kctl[i].name);
3282 snd_array_free(&spec->kctls);
3285 static void alc_free(struct hda_codec *codec)
3287 struct alc_spec *spec = codec->spec;
3292 alc_free_kctls(codec);
3294 snd_hda_detach_beep_device(codec);
3297 #ifdef SND_HDA_NEEDS_RESUME
3298 static int alc_resume(struct hda_codec *codec)
3300 codec->patch_ops.init(codec);
3301 snd_hda_codec_resume_amp(codec);
3302 snd_hda_codec_resume_cache(codec);
3309 static struct hda_codec_ops alc_patch_ops = {
3310 .build_controls = alc_build_controls,
3311 .build_pcms = alc_build_pcms,
3314 .unsol_event = alc_unsol_event,
3315 #ifdef SND_HDA_NEEDS_RESUME
3316 .resume = alc_resume,
3318 #ifdef CONFIG_SND_HDA_POWER_SAVE
3319 .check_power_status = alc_check_power_status,
3325 * Test configuration for debugging
3327 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3330 #ifdef CONFIG_SND_DEBUG
3331 static hda_nid_t alc880_test_dac_nids[4] = {
3332 0x02, 0x03, 0x04, 0x05
3335 static struct hda_input_mux alc880_test_capture_source = {
3344 { "Surround", 0x6 },
3348 static struct hda_channel_mode alc880_test_modes[4] = {
3355 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3356 struct snd_ctl_elem_info *uinfo)
3358 static char *texts[] = {
3359 "N/A", "Line Out", "HP Out",
3360 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3362 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3364 uinfo->value.enumerated.items = 8;
3365 if (uinfo->value.enumerated.item >= 8)
3366 uinfo->value.enumerated.item = 7;
3367 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3371 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3372 struct snd_ctl_elem_value *ucontrol)
3374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3375 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3376 unsigned int pin_ctl, item = 0;
3378 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3379 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3380 if (pin_ctl & AC_PINCTL_OUT_EN) {
3381 if (pin_ctl & AC_PINCTL_HP_EN)
3385 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3386 switch (pin_ctl & AC_PINCTL_VREFEN) {
3387 case AC_PINCTL_VREF_HIZ: item = 3; break;
3388 case AC_PINCTL_VREF_50: item = 4; break;
3389 case AC_PINCTL_VREF_GRD: item = 5; break;
3390 case AC_PINCTL_VREF_80: item = 6; break;
3391 case AC_PINCTL_VREF_100: item = 7; break;
3394 ucontrol->value.enumerated.item[0] = item;
3398 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3399 struct snd_ctl_elem_value *ucontrol)
3401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3402 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3403 static unsigned int ctls[] = {
3404 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3405 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3406 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3407 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3408 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3409 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3411 unsigned int old_ctl, new_ctl;
3413 old_ctl = snd_hda_codec_read(codec, nid, 0,
3414 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3415 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3416 if (old_ctl != new_ctl) {
3418 snd_hda_codec_write_cache(codec, nid, 0,
3419 AC_VERB_SET_PIN_WIDGET_CONTROL,
3421 val = ucontrol->value.enumerated.item[0] >= 3 ?
3423 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3430 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3431 struct snd_ctl_elem_info *uinfo)
3433 static char *texts[] = {
3434 "Front", "Surround", "CLFE", "Side"
3436 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3438 uinfo->value.enumerated.items = 4;
3439 if (uinfo->value.enumerated.item >= 4)
3440 uinfo->value.enumerated.item = 3;
3441 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3445 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3446 struct snd_ctl_elem_value *ucontrol)
3448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3449 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3452 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3453 ucontrol->value.enumerated.item[0] = sel & 3;
3457 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3458 struct snd_ctl_elem_value *ucontrol)
3460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3461 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3464 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3465 if (ucontrol->value.enumerated.item[0] != sel) {
3466 sel = ucontrol->value.enumerated.item[0] & 3;
3467 snd_hda_codec_write_cache(codec, nid, 0,
3468 AC_VERB_SET_CONNECT_SEL, sel);
3474 #define PIN_CTL_TEST(xname,nid) { \
3475 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3477 .info = alc_test_pin_ctl_info, \
3478 .get = alc_test_pin_ctl_get, \
3479 .put = alc_test_pin_ctl_put, \
3480 .private_value = nid \
3483 #define PIN_SRC_TEST(xname,nid) { \
3484 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3486 .info = alc_test_pin_src_info, \
3487 .get = alc_test_pin_src_get, \
3488 .put = alc_test_pin_src_put, \
3489 .private_value = nid \
3492 static struct snd_kcontrol_new alc880_test_mixer[] = {
3493 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3494 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3495 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3496 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3497 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3498 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3499 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3500 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3501 PIN_CTL_TEST("Front Pin Mode", 0x14),
3502 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3503 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3504 PIN_CTL_TEST("Side Pin Mode", 0x17),
3505 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3506 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3507 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3508 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3509 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3510 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3511 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3512 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3513 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3514 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3515 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3516 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3517 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3518 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3519 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3520 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3521 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3522 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3525 .name = "Channel Mode",
3526 .info = alc_ch_mode_info,
3527 .get = alc_ch_mode_get,
3528 .put = alc_ch_mode_put,
3533 static struct hda_verb alc880_test_init_verbs[] = {
3534 /* Unmute inputs of 0x0c - 0x0f */
3535 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3538 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3539 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3540 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3541 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3542 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3543 /* Vol output for 0x0c-0x0f */
3544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3546 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3547 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3548 /* Set output pins 0x14-0x17 */
3549 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3550 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3551 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3552 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3553 /* Unmute output pins 0x14-0x17 */
3554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3556 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3557 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3558 /* Set input pins 0x18-0x1c */
3559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3563 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3564 /* Mute input pins 0x18-0x1b */
3565 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3567 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3568 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3571 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3573 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3574 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3575 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3576 /* Analog input/passthru */
3577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3578 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3589 static const char *alc880_models[ALC880_MODEL_LAST] = {
3590 [ALC880_3ST] = "3stack",
3591 [ALC880_TCL_S700] = "tcl",
3592 [ALC880_3ST_DIG] = "3stack-digout",
3593 [ALC880_CLEVO] = "clevo",
3594 [ALC880_5ST] = "5stack",
3595 [ALC880_5ST_DIG] = "5stack-digout",
3596 [ALC880_W810] = "w810",
3597 [ALC880_Z71V] = "z71v",
3598 [ALC880_6ST] = "6stack",
3599 [ALC880_6ST_DIG] = "6stack-digout",
3600 [ALC880_ASUS] = "asus",
3601 [ALC880_ASUS_W1V] = "asus-w1v",
3602 [ALC880_ASUS_DIG] = "asus-dig",
3603 [ALC880_ASUS_DIG2] = "asus-dig2",
3604 [ALC880_UNIWILL_DIG] = "uniwill",
3605 [ALC880_UNIWILL_P53] = "uniwill-p53",
3606 [ALC880_FUJITSU] = "fujitsu",
3607 [ALC880_F1734] = "F1734",
3609 [ALC880_LG_LW] = "lg-lw",
3610 [ALC880_MEDION_RIM] = "medion",
3611 #ifdef CONFIG_SND_DEBUG
3612 [ALC880_TEST] = "test",
3614 [ALC880_AUTO] = "auto",
3617 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3618 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3619 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3620 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3621 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3622 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3623 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3624 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3625 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3626 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3627 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3628 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3629 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3630 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3631 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3632 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3633 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3634 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3635 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3636 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3637 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3638 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3639 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3640 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3641 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3642 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3643 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3644 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3645 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3646 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3647 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3648 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3649 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3650 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3651 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3652 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3653 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3654 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3655 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3656 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3657 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3658 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3659 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3660 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3661 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3662 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3663 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3664 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3665 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3666 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3667 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3668 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3669 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3670 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3671 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3672 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3673 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3674 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3675 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3676 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3677 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3678 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3679 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3680 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3681 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3682 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3683 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3684 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3685 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3687 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3688 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3689 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3694 * ALC880 codec presets
3696 static struct alc_config_preset alc880_presets[] = {
3698 .mixers = { alc880_three_stack_mixer },
3699 .init_verbs = { alc880_volume_init_verbs,
3700 alc880_pin_3stack_init_verbs },
3701 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3702 .dac_nids = alc880_dac_nids,
3703 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3704 .channel_mode = alc880_threestack_modes,
3706 .input_mux = &alc880_capture_source,
3708 [ALC880_3ST_DIG] = {
3709 .mixers = { alc880_three_stack_mixer },
3710 .init_verbs = { alc880_volume_init_verbs,
3711 alc880_pin_3stack_init_verbs },
3712 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3713 .dac_nids = alc880_dac_nids,
3714 .dig_out_nid = ALC880_DIGOUT_NID,
3715 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3716 .channel_mode = alc880_threestack_modes,
3718 .input_mux = &alc880_capture_source,
3720 [ALC880_TCL_S700] = {
3721 .mixers = { alc880_tcl_s700_mixer },
3722 .init_verbs = { alc880_volume_init_verbs,
3723 alc880_pin_tcl_S700_init_verbs,
3724 alc880_gpio2_init_verbs },
3725 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3726 .dac_nids = alc880_dac_nids,
3727 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3728 .num_adc_nids = 1, /* single ADC */
3730 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3731 .channel_mode = alc880_2_jack_modes,
3732 .input_mux = &alc880_capture_source,
3735 .mixers = { alc880_three_stack_mixer,
3736 alc880_five_stack_mixer},
3737 .init_verbs = { alc880_volume_init_verbs,
3738 alc880_pin_5stack_init_verbs },
3739 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3740 .dac_nids = alc880_dac_nids,
3741 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3742 .channel_mode = alc880_fivestack_modes,
3743 .input_mux = &alc880_capture_source,
3745 [ALC880_5ST_DIG] = {
3746 .mixers = { alc880_three_stack_mixer,
3747 alc880_five_stack_mixer },
3748 .init_verbs = { alc880_volume_init_verbs,
3749 alc880_pin_5stack_init_verbs },
3750 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3751 .dac_nids = alc880_dac_nids,
3752 .dig_out_nid = ALC880_DIGOUT_NID,
3753 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3754 .channel_mode = alc880_fivestack_modes,
3755 .input_mux = &alc880_capture_source,
3758 .mixers = { alc880_six_stack_mixer },
3759 .init_verbs = { alc880_volume_init_verbs,
3760 alc880_pin_6stack_init_verbs },
3761 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3762 .dac_nids = alc880_6st_dac_nids,
3763 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3764 .channel_mode = alc880_sixstack_modes,
3765 .input_mux = &alc880_6stack_capture_source,
3767 [ALC880_6ST_DIG] = {
3768 .mixers = { alc880_six_stack_mixer },
3769 .init_verbs = { alc880_volume_init_verbs,
3770 alc880_pin_6stack_init_verbs },
3771 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3772 .dac_nids = alc880_6st_dac_nids,
3773 .dig_out_nid = ALC880_DIGOUT_NID,
3774 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3775 .channel_mode = alc880_sixstack_modes,
3776 .input_mux = &alc880_6stack_capture_source,
3779 .mixers = { alc880_w810_base_mixer },
3780 .init_verbs = { alc880_volume_init_verbs,
3781 alc880_pin_w810_init_verbs,
3782 alc880_gpio2_init_verbs },
3783 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3784 .dac_nids = alc880_w810_dac_nids,
3785 .dig_out_nid = ALC880_DIGOUT_NID,
3786 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3787 .channel_mode = alc880_w810_modes,
3788 .input_mux = &alc880_capture_source,
3791 .mixers = { alc880_z71v_mixer },
3792 .init_verbs = { alc880_volume_init_verbs,
3793 alc880_pin_z71v_init_verbs },
3794 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3795 .dac_nids = alc880_z71v_dac_nids,
3796 .dig_out_nid = ALC880_DIGOUT_NID,
3798 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3799 .channel_mode = alc880_2_jack_modes,
3800 .input_mux = &alc880_capture_source,
3803 .mixers = { alc880_f1734_mixer },
3804 .init_verbs = { alc880_volume_init_verbs,
3805 alc880_pin_f1734_init_verbs },
3806 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3807 .dac_nids = alc880_f1734_dac_nids,
3809 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3810 .channel_mode = alc880_2_jack_modes,
3811 .input_mux = &alc880_f1734_capture_source,
3812 .unsol_event = alc880_uniwill_p53_unsol_event,
3813 .init_hook = alc880_uniwill_p53_init_hook,
3816 .mixers = { alc880_asus_mixer },
3817 .init_verbs = { alc880_volume_init_verbs,
3818 alc880_pin_asus_init_verbs,
3819 alc880_gpio1_init_verbs },
3820 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3821 .dac_nids = alc880_asus_dac_nids,
3822 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3823 .channel_mode = alc880_asus_modes,
3825 .input_mux = &alc880_capture_source,
3827 [ALC880_ASUS_DIG] = {
3828 .mixers = { alc880_asus_mixer },
3829 .init_verbs = { alc880_volume_init_verbs,
3830 alc880_pin_asus_init_verbs,
3831 alc880_gpio1_init_verbs },
3832 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3833 .dac_nids = alc880_asus_dac_nids,
3834 .dig_out_nid = ALC880_DIGOUT_NID,
3835 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3836 .channel_mode = alc880_asus_modes,
3838 .input_mux = &alc880_capture_source,
3840 [ALC880_ASUS_DIG2] = {
3841 .mixers = { alc880_asus_mixer },
3842 .init_verbs = { alc880_volume_init_verbs,
3843 alc880_pin_asus_init_verbs,
3844 alc880_gpio2_init_verbs }, /* use GPIO2 */
3845 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3846 .dac_nids = alc880_asus_dac_nids,
3847 .dig_out_nid = ALC880_DIGOUT_NID,
3848 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3849 .channel_mode = alc880_asus_modes,
3851 .input_mux = &alc880_capture_source,
3853 [ALC880_ASUS_W1V] = {
3854 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3855 .init_verbs = { alc880_volume_init_verbs,
3856 alc880_pin_asus_init_verbs,
3857 alc880_gpio1_init_verbs },
3858 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3859 .dac_nids = alc880_asus_dac_nids,
3860 .dig_out_nid = ALC880_DIGOUT_NID,
3861 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3862 .channel_mode = alc880_asus_modes,
3864 .input_mux = &alc880_capture_source,
3866 [ALC880_UNIWILL_DIG] = {
3867 .mixers = { alc880_asus_mixer },
3868 .init_verbs = { alc880_volume_init_verbs,
3869 alc880_pin_asus_init_verbs },
3870 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3871 .dac_nids = alc880_asus_dac_nids,
3872 .dig_out_nid = ALC880_DIGOUT_NID,
3873 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3874 .channel_mode = alc880_asus_modes,
3876 .input_mux = &alc880_capture_source,
3878 [ALC880_UNIWILL] = {
3879 .mixers = { alc880_uniwill_mixer },
3880 .init_verbs = { alc880_volume_init_verbs,
3881 alc880_uniwill_init_verbs },
3882 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3883 .dac_nids = alc880_asus_dac_nids,
3884 .dig_out_nid = ALC880_DIGOUT_NID,
3885 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3886 .channel_mode = alc880_threestack_modes,
3888 .input_mux = &alc880_capture_source,
3889 .unsol_event = alc880_uniwill_unsol_event,
3890 .init_hook = alc880_uniwill_init_hook,
3892 [ALC880_UNIWILL_P53] = {
3893 .mixers = { alc880_uniwill_p53_mixer },
3894 .init_verbs = { alc880_volume_init_verbs,
3895 alc880_uniwill_p53_init_verbs },
3896 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3897 .dac_nids = alc880_asus_dac_nids,
3898 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3899 .channel_mode = alc880_threestack_modes,
3900 .input_mux = &alc880_capture_source,
3901 .unsol_event = alc880_uniwill_p53_unsol_event,
3902 .init_hook = alc880_uniwill_p53_init_hook,
3904 [ALC880_FUJITSU] = {
3905 .mixers = { alc880_fujitsu_mixer },
3906 .init_verbs = { alc880_volume_init_verbs,
3907 alc880_uniwill_p53_init_verbs,
3908 alc880_beep_init_verbs },
3909 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3910 .dac_nids = alc880_dac_nids,
3911 .dig_out_nid = ALC880_DIGOUT_NID,
3912 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3913 .channel_mode = alc880_2_jack_modes,
3914 .input_mux = &alc880_capture_source,
3915 .unsol_event = alc880_uniwill_p53_unsol_event,
3916 .init_hook = alc880_uniwill_p53_init_hook,
3919 .mixers = { alc880_three_stack_mixer },
3920 .init_verbs = { alc880_volume_init_verbs,
3921 alc880_pin_clevo_init_verbs },
3922 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3923 .dac_nids = alc880_dac_nids,
3925 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3926 .channel_mode = alc880_threestack_modes,
3928 .input_mux = &alc880_capture_source,
3931 .mixers = { alc880_lg_mixer },
3932 .init_verbs = { alc880_volume_init_verbs,
3933 alc880_lg_init_verbs },
3934 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3935 .dac_nids = alc880_lg_dac_nids,
3936 .dig_out_nid = ALC880_DIGOUT_NID,
3937 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3938 .channel_mode = alc880_lg_ch_modes,
3940 .input_mux = &alc880_lg_capture_source,
3941 .unsol_event = alc_automute_amp_unsol_event,
3942 .init_hook = alc880_lg_init_hook,
3943 #ifdef CONFIG_SND_HDA_POWER_SAVE
3944 .loopbacks = alc880_lg_loopbacks,
3948 .mixers = { alc880_lg_lw_mixer },
3949 .init_verbs = { alc880_volume_init_verbs,
3950 alc880_lg_lw_init_verbs },
3951 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3952 .dac_nids = alc880_dac_nids,
3953 .dig_out_nid = ALC880_DIGOUT_NID,
3954 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3955 .channel_mode = alc880_lg_lw_modes,
3956 .input_mux = &alc880_lg_lw_capture_source,
3957 .unsol_event = alc_automute_amp_unsol_event,
3958 .init_hook = alc880_lg_lw_init_hook,
3960 [ALC880_MEDION_RIM] = {
3961 .mixers = { alc880_medion_rim_mixer },
3962 .init_verbs = { alc880_volume_init_verbs,
3963 alc880_medion_rim_init_verbs,
3964 alc_gpio2_init_verbs },
3965 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3966 .dac_nids = alc880_dac_nids,
3967 .dig_out_nid = ALC880_DIGOUT_NID,
3968 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3969 .channel_mode = alc880_2_jack_modes,
3970 .input_mux = &alc880_medion_rim_capture_source,
3971 .unsol_event = alc880_medion_rim_unsol_event,
3972 .init_hook = alc880_medion_rim_init_hook,
3974 #ifdef CONFIG_SND_DEBUG
3976 .mixers = { alc880_test_mixer },
3977 .init_verbs = { alc880_test_init_verbs },
3978 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3979 .dac_nids = alc880_test_dac_nids,
3980 .dig_out_nid = ALC880_DIGOUT_NID,
3981 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3982 .channel_mode = alc880_test_modes,
3983 .input_mux = &alc880_test_capture_source,
3989 * Automatic parse of I/O pins from the BIOS configuration
3994 ALC_CTL_WIDGET_MUTE,
3997 static struct snd_kcontrol_new alc880_control_templates[] = {
3998 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3999 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4000 HDA_BIND_MUTE(NULL, 0, 0, 0),
4003 /* add dynamic controls */
4004 static int add_control(struct alc_spec *spec, int type, const char *name,
4007 struct snd_kcontrol_new *knew;
4009 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4010 knew = snd_array_new(&spec->kctls);
4013 *knew = alc880_control_templates[type];
4014 knew->name = kstrdup(name, GFP_KERNEL);
4017 knew->private_value = val;
4021 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4022 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4023 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4024 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4025 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4026 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4027 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4028 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4029 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4030 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4031 #define ALC880_PIN_CD_NID 0x1c
4033 /* fill in the dac_nids table from the parsed pin configuration */
4034 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4035 const struct auto_pin_cfg *cfg)
4041 memset(assigned, 0, sizeof(assigned));
4042 spec->multiout.dac_nids = spec->private_dac_nids;
4044 /* check the pins hardwired to audio widget */
4045 for (i = 0; i < cfg->line_outs; i++) {
4046 nid = cfg->line_out_pins[i];
4047 if (alc880_is_fixed_pin(nid)) {
4048 int idx = alc880_fixed_pin_idx(nid);
4049 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4053 /* left pins can be connect to any audio widget */
4054 for (i = 0; i < cfg->line_outs; i++) {
4055 nid = cfg->line_out_pins[i];
4056 if (alc880_is_fixed_pin(nid))
4058 /* search for an empty channel */
4059 for (j = 0; j < cfg->line_outs; j++) {
4061 spec->multiout.dac_nids[i] =
4062 alc880_idx_to_dac(j);
4068 spec->multiout.num_dacs = cfg->line_outs;
4072 /* add playback controls from the parsed DAC table */
4073 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4074 const struct auto_pin_cfg *cfg)
4077 static const char *chname[4] = {
4078 "Front", "Surround", NULL /*CLFE*/, "Side"
4083 for (i = 0; i < cfg->line_outs; i++) {
4084 if (!spec->multiout.dac_nids[i])
4086 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4089 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4090 "Center Playback Volume",
4091 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4095 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4096 "LFE Playback Volume",
4097 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4101 err = add_control(spec, ALC_CTL_BIND_MUTE,
4102 "Center Playback Switch",
4103 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4107 err = add_control(spec, ALC_CTL_BIND_MUTE,
4108 "LFE Playback Switch",
4109 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4114 sprintf(name, "%s Playback Volume", chname[i]);
4115 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4116 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4120 sprintf(name, "%s Playback Switch", chname[i]);
4121 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4122 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4131 /* add playback controls for speaker and HP outputs */
4132 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4142 if (alc880_is_fixed_pin(pin)) {
4143 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4144 /* specify the DAC as the extra output */
4145 if (!spec->multiout.hp_nid)
4146 spec->multiout.hp_nid = nid;
4148 spec->multiout.extra_out_nid[0] = nid;
4149 /* control HP volume/switch on the output mixer amp */
4150 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4151 sprintf(name, "%s Playback Volume", pfx);
4152 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4153 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4156 sprintf(name, "%s Playback Switch", pfx);
4157 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4158 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4161 } else if (alc880_is_multi_pin(pin)) {
4162 /* set manual connection */
4163 /* we have only a switch on HP-out PIN */
4164 sprintf(name, "%s Playback Switch", pfx);
4165 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4166 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4173 /* create input playback/capture controls for the given pin */
4174 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4175 const char *ctlname,
4176 int idx, hda_nid_t mix_nid)
4181 sprintf(name, "%s Playback Volume", ctlname);
4182 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4183 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4186 sprintf(name, "%s Playback Switch", ctlname);
4187 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4188 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4194 /* create playback/capture controls for input pins */
4195 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4196 const struct auto_pin_cfg *cfg)
4198 struct hda_input_mux *imux = &spec->private_imux[0];
4201 for (i = 0; i < AUTO_PIN_LAST; i++) {
4202 if (alc880_is_input_pin(cfg->input_pins[i])) {
4203 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4204 err = new_analog_input(spec, cfg->input_pins[i],
4205 auto_pin_cfg_labels[i],
4209 imux->items[imux->num_items].label =
4210 auto_pin_cfg_labels[i];
4211 imux->items[imux->num_items].index =
4212 alc880_input_pin_idx(cfg->input_pins[i]);
4219 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4220 unsigned int pin_type)
4222 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4225 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4229 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4230 hda_nid_t nid, int pin_type,
4233 alc_set_pin_output(codec, nid, pin_type);
4234 /* need the manual connection? */
4235 if (alc880_is_multi_pin(nid)) {
4236 struct alc_spec *spec = codec->spec;
4237 int idx = alc880_multi_pin_idx(nid);
4238 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4239 AC_VERB_SET_CONNECT_SEL,
4240 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4244 static int get_pin_type(int line_out_type)
4246 if (line_out_type == AUTO_PIN_HP_OUT)
4252 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4254 struct alc_spec *spec = codec->spec;
4257 for (i = 0; i < spec->autocfg.line_outs; i++) {
4258 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4259 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4260 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4264 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4266 struct alc_spec *spec = codec->spec;
4269 pin = spec->autocfg.speaker_pins[0];
4270 if (pin) /* connect to front */
4271 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4272 pin = spec->autocfg.hp_pins[0];
4273 if (pin) /* connect to front */
4274 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4277 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4279 struct alc_spec *spec = codec->spec;
4282 for (i = 0; i < AUTO_PIN_LAST; i++) {
4283 hda_nid_t nid = spec->autocfg.input_pins[i];
4284 if (alc880_is_input_pin(nid)) {
4285 alc_set_input_pin(codec, nid, i);
4286 if (nid != ALC880_PIN_CD_NID &&
4287 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4288 snd_hda_codec_write(codec, nid, 0,
4289 AC_VERB_SET_AMP_GAIN_MUTE,
4295 /* parse the BIOS configuration and set up the alc_spec */
4296 /* return 1 if successful, 0 if the proper config is not found,
4297 * or a negative error code
4299 static int alc880_parse_auto_config(struct hda_codec *codec)
4301 struct alc_spec *spec = codec->spec;
4303 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4305 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4309 if (!spec->autocfg.line_outs)
4310 return 0; /* can't find valid BIOS pin config */
4312 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4315 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4318 err = alc880_auto_create_extra_out(spec,
4319 spec->autocfg.speaker_pins[0],
4323 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4327 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4331 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4333 /* check multiple SPDIF-out (for recent codecs) */
4334 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4336 err = snd_hda_get_connections(codec,
4337 spec->autocfg.dig_out_pins[i],
4342 spec->multiout.dig_out_nid = dig_nid;
4344 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4345 spec->slave_dig_outs[i - 1] = dig_nid;
4346 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4350 if (spec->autocfg.dig_in_pin)
4351 spec->dig_in_nid = ALC880_DIGIN_NID;
4353 if (spec->kctls.list)
4354 add_mixer(spec, spec->kctls.list);
4356 add_verb(spec, alc880_volume_init_verbs);
4358 spec->num_mux_defs = 1;
4359 spec->input_mux = &spec->private_imux[0];
4361 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4366 /* additional initialization for auto-configuration model */
4367 static void alc880_auto_init(struct hda_codec *codec)
4369 struct alc_spec *spec = codec->spec;
4370 alc880_auto_init_multi_out(codec);
4371 alc880_auto_init_extra_out(codec);
4372 alc880_auto_init_analog_input(codec);
4373 if (spec->unsol_event)
4374 alc_inithook(codec);
4377 static void set_capture_mixer(struct alc_spec *spec)
4379 static struct snd_kcontrol_new *caps[2][3] = {
4380 { alc_capture_mixer_nosrc1,
4381 alc_capture_mixer_nosrc2,
4382 alc_capture_mixer_nosrc3 },
4383 { alc_capture_mixer1,
4385 alc_capture_mixer3 },
4387 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4389 if (spec->input_mux && spec->input_mux->num_items > 1)
4393 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4397 #define set_beep_amp(spec, nid, idx, dir) \
4398 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4401 * OK, here we have finally the patch for ALC880
4404 static int patch_alc880(struct hda_codec *codec)
4406 struct alc_spec *spec;
4410 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4416 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4419 if (board_config < 0) {
4420 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4421 "trying auto-probe from BIOS...\n", codec->chip_name);
4422 board_config = ALC880_AUTO;
4425 if (board_config == ALC880_AUTO) {
4426 /* automatic parse from the BIOS config */
4427 err = alc880_parse_auto_config(codec);
4433 "hda_codec: Cannot set up configuration "
4434 "from BIOS. Using 3-stack mode...\n");
4435 board_config = ALC880_3ST;
4439 err = snd_hda_attach_beep_device(codec, 0x1);
4445 if (board_config != ALC880_AUTO)
4446 setup_preset(spec, &alc880_presets[board_config]);
4448 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4449 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4450 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4452 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4453 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4455 if (!spec->adc_nids && spec->input_mux) {
4456 /* check whether NID 0x07 is valid */
4457 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4459 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4460 if (wcap != AC_WID_AUD_IN) {
4461 spec->adc_nids = alc880_adc_nids_alt;
4462 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4464 spec->adc_nids = alc880_adc_nids;
4465 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4468 set_capture_mixer(spec);
4469 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4471 spec->vmaster_nid = 0x0c;
4473 codec->patch_ops = alc_patch_ops;
4474 if (board_config == ALC880_AUTO)
4475 spec->init_hook = alc880_auto_init;
4476 #ifdef CONFIG_SND_HDA_POWER_SAVE
4477 if (!spec->loopback.amplist)
4478 spec->loopback.amplist = alc880_loopbacks;
4480 codec->proc_widget_hook = print_realtek_coef;
4490 static hda_nid_t alc260_dac_nids[1] = {
4495 static hda_nid_t alc260_adc_nids[1] = {
4500 static hda_nid_t alc260_adc_nids_alt[1] = {
4505 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4506 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4508 static hda_nid_t alc260_dual_adc_nids[2] = {
4513 #define ALC260_DIGOUT_NID 0x03
4514 #define ALC260_DIGIN_NID 0x06
4516 static struct hda_input_mux alc260_capture_source = {
4520 { "Front Mic", 0x1 },
4526 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4527 * headphone jack and the internal CD lines since these are the only pins at
4528 * which audio can appear. For flexibility, also allow the option of
4529 * recording the mixer output on the second ADC (ADC0 doesn't have a
4530 * connection to the mixer output).
4532 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4536 { "Mic/Line", 0x0 },
4538 { "Headphone", 0x2 },
4544 { "Mic/Line", 0x0 },
4546 { "Headphone", 0x2 },
4553 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4554 * the Fujitsu S702x, but jacks are marked differently.
4556 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4563 { "Headphone", 0x5 },
4572 { "Headphone", 0x6 },
4578 /* Maxdata Favorit 100XS */
4579 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4583 { "Line/Mic", 0x0 },
4590 { "Line/Mic", 0x0 },
4598 * This is just place-holder, so there's something for alc_build_pcms to look
4599 * at when it calculates the maximum number of channels. ALC260 has no mixer
4600 * element which allows changing the channel mode, so the verb list is
4603 static struct hda_channel_mode alc260_modes[1] = {
4608 /* Mixer combinations
4610 * basic: base_output + input + pc_beep + capture
4611 * HP: base_output + input + capture_alt
4612 * HP_3013: hp_3013 + input + capture
4613 * fujitsu: fujitsu + capture
4614 * acer: acer + capture
4617 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4618 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4619 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4620 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4621 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4622 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4623 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4627 static struct snd_kcontrol_new alc260_input_mixer[] = {
4628 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4629 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4630 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4631 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4633 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4635 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4639 /* update HP, line and mono out pins according to the master switch */
4640 static void alc260_hp_master_update(struct hda_codec *codec,
4641 hda_nid_t hp, hda_nid_t line,
4644 struct alc_spec *spec = codec->spec;
4645 unsigned int val = spec->master_sw ? PIN_HP : 0;
4646 /* change HP and line-out pins */
4647 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4649 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4651 /* mono (speaker) depending on the HP jack sense */
4652 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4653 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4657 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4658 struct snd_ctl_elem_value *ucontrol)
4660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4661 struct alc_spec *spec = codec->spec;
4662 *ucontrol->value.integer.value = spec->master_sw;
4666 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4667 struct snd_ctl_elem_value *ucontrol)
4669 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4670 struct alc_spec *spec = codec->spec;
4671 int val = !!*ucontrol->value.integer.value;
4672 hda_nid_t hp, line, mono;
4674 if (val == spec->master_sw)
4676 spec->master_sw = val;
4677 hp = (kcontrol->private_value >> 16) & 0xff;
4678 line = (kcontrol->private_value >> 8) & 0xff;
4679 mono = kcontrol->private_value & 0xff;
4680 alc260_hp_master_update(codec, hp, line, mono);
4684 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4687 .name = "Master Playback Switch",
4688 .info = snd_ctl_boolean_mono_info,
4689 .get = alc260_hp_master_sw_get,
4690 .put = alc260_hp_master_sw_put,
4691 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4693 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4694 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4696 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4697 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4699 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4703 static struct hda_verb alc260_hp_unsol_verbs[] = {
4704 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4708 static void alc260_hp_automute(struct hda_codec *codec)
4710 struct alc_spec *spec = codec->spec;
4711 unsigned int present;
4713 present = snd_hda_codec_read(codec, 0x10, 0,
4714 AC_VERB_GET_PIN_SENSE, 0);
4715 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4716 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4719 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4721 if ((res >> 26) == ALC880_HP_EVENT)
4722 alc260_hp_automute(codec);
4725 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4727 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4728 .name = "Master Playback Switch",
4729 .info = snd_ctl_boolean_mono_info,
4730 .get = alc260_hp_master_sw_get,
4731 .put = alc260_hp_master_sw_put,
4732 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4734 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4735 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4736 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4737 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4738 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4739 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4740 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4741 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4745 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4746 .ops = &snd_hda_bind_vol,
4748 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4749 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4750 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4755 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4756 .ops = &snd_hda_bind_sw,
4758 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4759 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4764 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4765 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4766 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4767 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4768 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4772 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4773 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4777 static void alc260_hp_3013_automute(struct hda_codec *codec)
4779 struct alc_spec *spec = codec->spec;
4780 unsigned int present;
4782 present = snd_hda_codec_read(codec, 0x15, 0,
4783 AC_VERB_GET_PIN_SENSE, 0);
4784 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4785 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4788 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4791 if ((res >> 26) == ALC880_HP_EVENT)
4792 alc260_hp_3013_automute(codec);
4795 static void alc260_hp_3012_automute(struct hda_codec *codec)
4797 unsigned int present, bits;
4799 present = snd_hda_codec_read(codec, 0x10, 0,
4800 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4802 bits = present ? 0 : PIN_OUT;
4803 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4805 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4807 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4811 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4814 if ((res >> 26) == ALC880_HP_EVENT)
4815 alc260_hp_3012_automute(codec);
4818 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4819 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4821 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4822 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4823 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4824 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4825 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4826 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4827 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4828 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4829 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4830 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4831 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4835 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4836 * versions of the ALC260 don't act on requests to enable mic bias from NID
4837 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4838 * datasheet doesn't mention this restriction. At this stage it's not clear
4839 * whether this behaviour is intentional or is a hardware bug in chip
4840 * revisions available in early 2006. Therefore for now allow the
4841 * "Headphone Jack Mode" control to span all choices, but if it turns out
4842 * that the lack of mic bias for this NID is intentional we could change the
4843 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4845 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4846 * don't appear to make the mic bias available from the "line" jack, even
4847 * though the NID used for this jack (0x14) can supply it. The theory is
4848 * that perhaps Acer have included blocking capacitors between the ALC260
4849 * and the output jack. If this turns out to be the case for all such
4850 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4851 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4853 * The C20x Tablet series have a mono internal speaker which is controlled
4854 * via the chip's Mono sum widget and pin complex, so include the necessary
4855 * controls for such models. On models without a "mono speaker" the control
4856 * won't do anything.
4858 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4859 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4860 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4861 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4862 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4864 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4866 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4867 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4869 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4870 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4871 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4872 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4873 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4877 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4879 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4880 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4881 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4882 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4883 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4884 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4885 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4889 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4890 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4892 static struct snd_kcontrol_new alc260_will_mixer[] = {
4893 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4894 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4896 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4897 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4898 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4899 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4900 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4901 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4902 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4906 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4907 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4909 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4910 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4911 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4912 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4913 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4914 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4915 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4916 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4917 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4918 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4919 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4924 * initialization verbs
4926 static struct hda_verb alc260_init_verbs[] = {
4927 /* Line In pin widget for input */
4928 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4929 /* CD pin widget for input */
4930 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4931 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4932 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4933 /* Mic2 (front panel) pin widget for input and vref at 80% */
4934 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4935 /* LINE-2 is used for line-out in rear */
4936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4937 /* select line-out */
4938 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4940 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4942 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4944 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4945 /* mute capture amp left and right */
4946 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4947 /* set connection select to line in (default select for this ADC) */
4948 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4949 /* mute capture amp left and right */
4950 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4951 /* set connection select to line in (default select for this ADC) */
4952 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4953 /* set vol=0 Line-Out mixer amp left and right */
4954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4955 /* unmute pin widget amp left and right (no gain on this amp) */
4956 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4957 /* set vol=0 HP mixer amp left and right */
4958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4959 /* unmute pin widget amp left and right (no gain on this amp) */
4960 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4961 /* set vol=0 Mono mixer amp left and right */
4962 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4963 /* unmute pin widget amp left and right (no gain on this amp) */
4964 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4965 /* unmute LINE-2 out pin */
4966 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4967 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4970 /* mute analog inputs */
4971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4972 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4976 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4977 /* mute Front out path */
4978 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4979 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4980 /* mute Headphone out path */
4981 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4982 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4983 /* mute Mono out path */
4984 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4985 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4989 #if 0 /* should be identical with alc260_init_verbs? */
4990 static struct hda_verb alc260_hp_init_verbs[] = {
4991 /* Headphone and output */
4992 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4994 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4995 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4996 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4997 /* Mic2 (front panel) pin widget for input and vref at 80% */
4998 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4999 /* Line In pin widget for input */
5000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5001 /* Line-2 pin widget for output */
5002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5003 /* CD pin widget for input */
5004 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5005 /* unmute amp left and right */
5006 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5007 /* set connection select to line in (default select for this ADC) */
5008 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5009 /* unmute Line-Out mixer amp left and right (volume = 0) */
5010 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5011 /* mute pin widget amp left and right (no gain on this amp) */
5012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5013 /* unmute HP mixer amp left and right (volume = 0) */
5014 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5015 /* mute pin widget amp left and right (no gain on this amp) */
5016 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5017 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5020 /* mute analog inputs */
5021 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5023 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5025 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5026 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5027 /* Unmute Front out path */
5028 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5029 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5030 /* Unmute Headphone out path */
5031 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5033 /* Unmute Mono out path */
5034 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5035 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5040 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5041 /* Line out and output */
5042 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5044 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5045 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5047 /* Mic2 (front panel) pin widget for input and vref at 80% */
5048 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5049 /* Line In pin widget for input */
5050 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5051 /* Headphone pin widget for output */
5052 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5053 /* CD pin widget for input */
5054 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5055 /* unmute amp left and right */
5056 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5057 /* set connection select to line in (default select for this ADC) */
5058 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5059 /* unmute Line-Out mixer amp left and right (volume = 0) */
5060 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5061 /* mute pin widget amp left and right (no gain on this amp) */
5062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5063 /* unmute HP mixer amp left and right (volume = 0) */
5064 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5065 /* mute pin widget amp left and right (no gain on this amp) */
5066 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5067 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5070 /* mute analog inputs */
5071 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5072 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5073 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5074 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5076 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5077 /* Unmute Front out path */
5078 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5079 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5080 /* Unmute Headphone out path */
5081 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5082 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5083 /* Unmute Mono out path */
5084 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5085 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5089 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5090 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5091 * audio = 0x16, internal speaker = 0x10.
5093 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5094 /* Disable all GPIOs */
5095 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5096 /* Internal speaker is connected to headphone pin */
5097 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5098 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5100 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5101 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5102 /* Ensure all other unused pins are disabled and muted. */
5103 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5104 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5105 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5106 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5107 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5108 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5110 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5112 /* Disable digital (SPDIF) pins */
5113 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5114 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5116 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5117 * when acting as an output.
5119 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5121 /* Start with output sum widgets muted and their output gains at min */
5122 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5125 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5128 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5129 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5130 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5132 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5133 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5134 /* Unmute Line1 pin widget output buffer since it starts as an output.
5135 * If the pin mode is changed by the user the pin mode control will
5136 * take care of enabling the pin's input/output buffers as needed.
5137 * Therefore there's no need to enable the input buffer at this
5140 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5141 /* Unmute input buffer of pin widget used for Line-in (no equiv
5144 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5146 /* Mute capture amp left and right */
5147 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5148 /* Set ADC connection select to match default mixer setting - line
5151 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5153 /* Do the same for the second ADC: mute capture input amp and
5154 * set ADC connection to line in (on mic1 pin)
5156 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5157 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5159 /* Mute all inputs to mixer widget (even unconnected ones) */
5160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5162 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5163 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5172 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5173 * similar laptops (adapted from Fujitsu init verbs).
5175 static struct hda_verb alc260_acer_init_verbs[] = {
5176 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5177 * the headphone jack. Turn this on and rely on the standard mute
5178 * methods whenever the user wants to turn these outputs off.
5180 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5181 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5182 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5183 /* Internal speaker/Headphone jack is connected to Line-out pin */
5184 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5185 /* Internal microphone/Mic jack is connected to Mic1 pin */
5186 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5187 /* Line In jack is connected to Line1 pin */
5188 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5189 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5190 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5191 /* Ensure all other unused pins are disabled and muted. */
5192 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5193 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5194 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5195 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5196 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5197 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5198 /* Disable digital (SPDIF) pins */
5199 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5200 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5202 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5203 * bus when acting as outputs.
5205 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5206 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5208 /* Start with output sum widgets muted and their output gains at min */
5209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5210 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5211 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5212 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5213 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5214 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5215 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5216 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5217 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5219 /* Unmute Line-out pin widget amp left and right
5220 * (no equiv mixer ctrl)
5222 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5223 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5224 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5225 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5226 * inputs. If the pin mode is changed by the user the pin mode control
5227 * will take care of enabling the pin's input/output buffers as needed.
5228 * Therefore there's no need to enable the input buffer at this
5231 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5234 /* Mute capture amp left and right */
5235 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5236 /* Set ADC connection select to match default mixer setting - mic
5239 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5241 /* Do similar with the second ADC: mute capture input amp and
5242 * set ADC connection to mic to match ALSA's default state.
5244 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5245 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5247 /* Mute all inputs to mixer widget (even unconnected ones) */
5248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5251 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5253 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5260 /* Initialisation sequence for Maxdata Favorit 100XS
5261 * (adapted from Acer init verbs).
5263 static struct hda_verb alc260_favorit100_init_verbs[] = {
5264 /* GPIO 0 enables the output jack.
5265 * Turn this on and rely on the standard mute
5266 * methods whenever the user wants to turn these outputs off.
5268 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5269 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5270 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5271 /* Line/Mic input jack is connected to Mic1 pin */
5272 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5273 /* Ensure all other unused pins are disabled and muted. */
5274 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5275 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5276 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5277 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5278 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5279 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5280 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5284 /* Disable digital (SPDIF) pins */
5285 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5286 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5288 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5289 * bus when acting as outputs.
5291 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5292 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5294 /* Start with output sum widgets muted and their output gains at min */
5295 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5296 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5297 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5298 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5299 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5300 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5301 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5302 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5303 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5305 /* Unmute Line-out pin widget amp left and right
5306 * (no equiv mixer ctrl)
5308 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5309 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5310 * inputs. If the pin mode is changed by the user the pin mode control
5311 * will take care of enabling the pin's input/output buffers as needed.
5312 * Therefore there's no need to enable the input buffer at this
5315 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5317 /* Mute capture amp left and right */
5318 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5319 /* Set ADC connection select to match default mixer setting - mic
5322 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5324 /* Do similar with the second ADC: mute capture input amp and
5325 * set ADC connection to mic to match ALSA's default state.
5327 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5328 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5330 /* Mute all inputs to mixer widget (even unconnected ones) */
5331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5335 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5336 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5337 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5338 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5343 static struct hda_verb alc260_will_verbs[] = {
5344 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5345 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5346 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5347 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5348 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5349 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5353 static struct hda_verb alc260_replacer_672v_verbs[] = {
5354 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5355 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5356 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5358 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5359 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5360 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5362 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5366 /* toggle speaker-output according to the hp-jack state */
5367 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5369 unsigned int present;
5371 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5372 present = snd_hda_codec_read(codec, 0x0f, 0,
5373 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5375 snd_hda_codec_write_cache(codec, 0x01, 0,
5376 AC_VERB_SET_GPIO_DATA, 1);
5377 snd_hda_codec_write_cache(codec, 0x0f, 0,
5378 AC_VERB_SET_PIN_WIDGET_CONTROL,
5381 snd_hda_codec_write_cache(codec, 0x01, 0,
5382 AC_VERB_SET_GPIO_DATA, 0);
5383 snd_hda_codec_write_cache(codec, 0x0f, 0,
5384 AC_VERB_SET_PIN_WIDGET_CONTROL,
5389 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5392 if ((res >> 26) == ALC880_HP_EVENT)
5393 alc260_replacer_672v_automute(codec);
5396 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5397 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5398 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5399 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5400 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5401 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5402 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5403 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5404 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5405 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5406 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5410 /* Test configuration for debugging, modelled after the ALC880 test
5413 #ifdef CONFIG_SND_DEBUG
5414 static hda_nid_t alc260_test_dac_nids[1] = {
5417 static hda_nid_t alc260_test_adc_nids[2] = {
5420 /* For testing the ALC260, each input MUX needs its own definition since
5421 * the signal assignments are different. This assumes that the first ADC
5424 static struct hda_input_mux alc260_test_capture_sources[2] = {
5428 { "MIC1 pin", 0x0 },
5429 { "MIC2 pin", 0x1 },
5430 { "LINE1 pin", 0x2 },
5431 { "LINE2 pin", 0x3 },
5433 { "LINE-OUT pin", 0x5 },
5434 { "HP-OUT pin", 0x6 },
5440 { "MIC1 pin", 0x0 },
5441 { "MIC2 pin", 0x1 },
5442 { "LINE1 pin", 0x2 },
5443 { "LINE2 pin", 0x3 },
5446 { "LINE-OUT pin", 0x6 },
5447 { "HP-OUT pin", 0x7 },
5451 static struct snd_kcontrol_new alc260_test_mixer[] = {
5452 /* Output driver widgets */
5453 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5454 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5455 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5456 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5457 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5458 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5460 /* Modes for retasking pin widgets
5461 * Note: the ALC260 doesn't seem to act on requests to enable mic
5462 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5463 * mention this restriction. At this stage it's not clear whether
5464 * this behaviour is intentional or is a hardware bug in chip
5465 * revisions available at least up until early 2006. Therefore for
5466 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5467 * choices, but if it turns out that the lack of mic bias for these
5468 * NIDs is intentional we could change their modes from
5469 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5471 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5472 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5473 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5474 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5475 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5476 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5478 /* Loopback mixer controls */
5479 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5480 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5481 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5482 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5483 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5484 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5485 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5486 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5487 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5488 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5489 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5490 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5491 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5492 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5494 /* Controls for GPIO pins, assuming they are configured as outputs */
5495 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5496 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5497 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5498 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5500 /* Switches to allow the digital IO pins to be enabled. The datasheet
5501 * is ambigious as to which NID is which; testing on laptops which
5502 * make this output available should provide clarification.
5504 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5505 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5507 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5508 * this output to turn on an external amplifier.
5510 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5511 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5515 static struct hda_verb alc260_test_init_verbs[] = {
5516 /* Enable all GPIOs as outputs with an initial value of 0 */
5517 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5518 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5519 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5521 /* Enable retasking pins as output, initially without power amp */
5522 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5523 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5526 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5527 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5529 /* Disable digital (SPDIF) pins initially, but users can enable
5530 * them via a mixer switch. In the case of SPDIF-out, this initverb
5531 * payload also sets the generation to 0, output to be in "consumer"
5532 * PCM format, copyright asserted, no pre-emphasis and no validity
5535 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5536 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5538 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5539 * OUT1 sum bus when acting as an output.
5541 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5542 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5543 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5544 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5546 /* Start with output sum widgets muted and their output gains at min */
5547 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5548 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5549 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5551 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5552 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5553 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5554 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5555 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5557 /* Unmute retasking pin widget output buffers since the default
5558 * state appears to be output. As the pin mode is changed by the
5559 * user the pin mode control will take care of enabling the pin's
5560 * input/output buffers as needed.
5562 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5563 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5565 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5566 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5567 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5568 /* Also unmute the mono-out pin widget */
5569 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5571 /* Mute capture amp left and right */
5572 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5573 /* Set ADC connection select to match default mixer setting (mic1
5576 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5578 /* Do the same for the second ADC: mute capture input amp and
5579 * set ADC connection to mic1 pin
5581 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5582 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5584 /* Mute all inputs to mixer widget (even unconnected ones) */
5585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5589 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5598 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5599 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5601 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5602 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5605 * for BIOS auto-configuration
5608 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5609 const char *pfx, int *vol_bits)
5612 unsigned long vol_val, sw_val;
5616 if (nid >= 0x0f && nid < 0x11) {
5617 nid_vol = nid - 0x7;
5618 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5619 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5620 } else if (nid == 0x11) {
5621 nid_vol = nid - 0x7;
5622 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5623 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5624 } else if (nid >= 0x12 && nid <= 0x15) {
5626 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5627 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5631 if (!(*vol_bits & (1 << nid_vol))) {
5632 /* first control for the volume widget */
5633 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5634 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5637 *vol_bits |= (1 << nid_vol);
5639 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5640 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5646 /* add playback controls from the parsed DAC table */
5647 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5648 const struct auto_pin_cfg *cfg)
5654 spec->multiout.num_dacs = 1;
5655 spec->multiout.dac_nids = spec->private_dac_nids;
5656 spec->multiout.dac_nids[0] = 0x02;
5658 nid = cfg->line_out_pins[0];
5660 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5665 nid = cfg->speaker_pins[0];
5667 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5672 nid = cfg->hp_pins[0];
5674 err = alc260_add_playback_controls(spec, nid, "Headphone",
5682 /* create playback/capture controls for input pins */
5683 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5684 const struct auto_pin_cfg *cfg)
5686 struct hda_input_mux *imux = &spec->private_imux[0];
5689 for (i = 0; i < AUTO_PIN_LAST; i++) {
5690 if (cfg->input_pins[i] >= 0x12) {
5691 idx = cfg->input_pins[i] - 0x12;
5692 err = new_analog_input(spec, cfg->input_pins[i],
5693 auto_pin_cfg_labels[i], idx,
5697 imux->items[imux->num_items].label =
5698 auto_pin_cfg_labels[i];
5699 imux->items[imux->num_items].index = idx;
5702 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5703 idx = cfg->input_pins[i] - 0x09;
5704 err = new_analog_input(spec, cfg->input_pins[i],
5705 auto_pin_cfg_labels[i], idx,
5709 imux->items[imux->num_items].label =
5710 auto_pin_cfg_labels[i];
5711 imux->items[imux->num_items].index = idx;
5718 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5719 hda_nid_t nid, int pin_type,
5722 alc_set_pin_output(codec, nid, pin_type);
5723 /* need the manual connection? */
5725 int idx = nid - 0x12;
5726 snd_hda_codec_write(codec, idx + 0x0b, 0,
5727 AC_VERB_SET_CONNECT_SEL, sel_idx);
5731 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5733 struct alc_spec *spec = codec->spec;
5736 nid = spec->autocfg.line_out_pins[0];
5738 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5739 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5742 nid = spec->autocfg.speaker_pins[0];
5744 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5746 nid = spec->autocfg.hp_pins[0];
5748 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5751 #define ALC260_PIN_CD_NID 0x16
5752 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5754 struct alc_spec *spec = codec->spec;
5757 for (i = 0; i < AUTO_PIN_LAST; i++) {
5758 hda_nid_t nid = spec->autocfg.input_pins[i];
5760 alc_set_input_pin(codec, nid, i);
5761 if (nid != ALC260_PIN_CD_NID &&
5762 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5763 snd_hda_codec_write(codec, nid, 0,
5764 AC_VERB_SET_AMP_GAIN_MUTE,
5771 * generic initialization of ADC, input mixers and output mixers
5773 static struct hda_verb alc260_volume_init_verbs[] = {
5775 * Unmute ADC0-1 and set the default input to mic-in
5777 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5778 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5779 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5780 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5782 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5784 * Note: PASD motherboards uses the Line In 2 as the input for
5785 * front panel mic (mic 2)
5787 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5788 /* mute analog inputs */
5789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5796 * Set up output mixers (0x08 - 0x0a)
5798 /* set vol=0 to output mixers */
5799 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5800 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5801 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5802 /* set up input amps for analog loopback */
5803 /* Amp Indices: DAC = 0, mixer = 1 */
5804 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5805 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5806 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5807 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5808 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5809 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5814 static int alc260_parse_auto_config(struct hda_codec *codec)
5816 struct alc_spec *spec = codec->spec;
5818 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5820 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5824 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5827 if (!spec->kctls.list)
5828 return 0; /* can't find valid BIOS pin config */
5829 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5833 spec->multiout.max_channels = 2;
5835 if (spec->autocfg.dig_outs)
5836 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5837 if (spec->kctls.list)
5838 add_mixer(spec, spec->kctls.list);
5840 add_verb(spec, alc260_volume_init_verbs);
5842 spec->num_mux_defs = 1;
5843 spec->input_mux = &spec->private_imux[0];
5845 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5850 /* additional initialization for auto-configuration model */
5851 static void alc260_auto_init(struct hda_codec *codec)
5853 struct alc_spec *spec = codec->spec;
5854 alc260_auto_init_multi_out(codec);
5855 alc260_auto_init_analog_input(codec);
5856 if (spec->unsol_event)
5857 alc_inithook(codec);
5860 #ifdef CONFIG_SND_HDA_POWER_SAVE
5861 static struct hda_amp_list alc260_loopbacks[] = {
5862 { 0x07, HDA_INPUT, 0 },
5863 { 0x07, HDA_INPUT, 1 },
5864 { 0x07, HDA_INPUT, 2 },
5865 { 0x07, HDA_INPUT, 3 },
5866 { 0x07, HDA_INPUT, 4 },
5872 * ALC260 configurations
5874 static const char *alc260_models[ALC260_MODEL_LAST] = {
5875 [ALC260_BASIC] = "basic",
5877 [ALC260_HP_3013] = "hp-3013",
5878 [ALC260_HP_DC7600] = "hp-dc7600",
5879 [ALC260_FUJITSU_S702X] = "fujitsu",
5880 [ALC260_ACER] = "acer",
5881 [ALC260_WILL] = "will",
5882 [ALC260_REPLACER_672V] = "replacer",
5883 [ALC260_FAVORIT100] = "favorit100",
5884 #ifdef CONFIG_SND_DEBUG
5885 [ALC260_TEST] = "test",
5887 [ALC260_AUTO] = "auto",
5890 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5891 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5892 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5893 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5894 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5895 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5896 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5897 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5898 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5899 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5900 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5901 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5902 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5903 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5904 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5905 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5906 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5907 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5908 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5909 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5913 static struct alc_config_preset alc260_presets[] = {
5915 .mixers = { alc260_base_output_mixer,
5916 alc260_input_mixer },
5917 .init_verbs = { alc260_init_verbs },
5918 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5919 .dac_nids = alc260_dac_nids,
5920 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5921 .adc_nids = alc260_adc_nids,
5922 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5923 .channel_mode = alc260_modes,
5924 .input_mux = &alc260_capture_source,
5927 .mixers = { alc260_hp_output_mixer,
5928 alc260_input_mixer },
5929 .init_verbs = { alc260_init_verbs,
5930 alc260_hp_unsol_verbs },
5931 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5932 .dac_nids = alc260_dac_nids,
5933 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5934 .adc_nids = alc260_adc_nids_alt,
5935 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5936 .channel_mode = alc260_modes,
5937 .input_mux = &alc260_capture_source,
5938 .unsol_event = alc260_hp_unsol_event,
5939 .init_hook = alc260_hp_automute,
5941 [ALC260_HP_DC7600] = {
5942 .mixers = { alc260_hp_dc7600_mixer,
5943 alc260_input_mixer },
5944 .init_verbs = { alc260_init_verbs,
5945 alc260_hp_dc7600_verbs },
5946 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5947 .dac_nids = alc260_dac_nids,
5948 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5949 .adc_nids = alc260_adc_nids_alt,
5950 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5951 .channel_mode = alc260_modes,
5952 .input_mux = &alc260_capture_source,
5953 .unsol_event = alc260_hp_3012_unsol_event,
5954 .init_hook = alc260_hp_3012_automute,
5956 [ALC260_HP_3013] = {
5957 .mixers = { alc260_hp_3013_mixer,
5958 alc260_input_mixer },
5959 .init_verbs = { alc260_hp_3013_init_verbs,
5960 alc260_hp_3013_unsol_verbs },
5961 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5962 .dac_nids = alc260_dac_nids,
5963 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5964 .adc_nids = alc260_adc_nids_alt,
5965 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5966 .channel_mode = alc260_modes,
5967 .input_mux = &alc260_capture_source,
5968 .unsol_event = alc260_hp_3013_unsol_event,
5969 .init_hook = alc260_hp_3013_automute,
5971 [ALC260_FUJITSU_S702X] = {
5972 .mixers = { alc260_fujitsu_mixer },
5973 .init_verbs = { alc260_fujitsu_init_verbs },
5974 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5975 .dac_nids = alc260_dac_nids,
5976 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5977 .adc_nids = alc260_dual_adc_nids,
5978 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5979 .channel_mode = alc260_modes,
5980 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5981 .input_mux = alc260_fujitsu_capture_sources,
5984 .mixers = { alc260_acer_mixer },
5985 .init_verbs = { alc260_acer_init_verbs },
5986 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5987 .dac_nids = alc260_dac_nids,
5988 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5989 .adc_nids = alc260_dual_adc_nids,
5990 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5991 .channel_mode = alc260_modes,
5992 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5993 .input_mux = alc260_acer_capture_sources,
5995 [ALC260_FAVORIT100] = {
5996 .mixers = { alc260_favorit100_mixer },
5997 .init_verbs = { alc260_favorit100_init_verbs },
5998 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5999 .dac_nids = alc260_dac_nids,
6000 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6001 .adc_nids = alc260_dual_adc_nids,
6002 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6003 .channel_mode = alc260_modes,
6004 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6005 .input_mux = alc260_favorit100_capture_sources,
6008 .mixers = { alc260_will_mixer },
6009 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6010 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6011 .dac_nids = alc260_dac_nids,
6012 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6013 .adc_nids = alc260_adc_nids,
6014 .dig_out_nid = ALC260_DIGOUT_NID,
6015 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6016 .channel_mode = alc260_modes,
6017 .input_mux = &alc260_capture_source,
6019 [ALC260_REPLACER_672V] = {
6020 .mixers = { alc260_replacer_672v_mixer },
6021 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6022 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6023 .dac_nids = alc260_dac_nids,
6024 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6025 .adc_nids = alc260_adc_nids,
6026 .dig_out_nid = ALC260_DIGOUT_NID,
6027 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6028 .channel_mode = alc260_modes,
6029 .input_mux = &alc260_capture_source,
6030 .unsol_event = alc260_replacer_672v_unsol_event,
6031 .init_hook = alc260_replacer_672v_automute,
6033 #ifdef CONFIG_SND_DEBUG
6035 .mixers = { alc260_test_mixer },
6036 .init_verbs = { alc260_test_init_verbs },
6037 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6038 .dac_nids = alc260_test_dac_nids,
6039 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6040 .adc_nids = alc260_test_adc_nids,
6041 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6042 .channel_mode = alc260_modes,
6043 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6044 .input_mux = alc260_test_capture_sources,
6049 static int patch_alc260(struct hda_codec *codec)
6051 struct alc_spec *spec;
6052 int err, board_config;
6054 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6060 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6063 if (board_config < 0) {
6064 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6065 "trying auto-probe from BIOS...\n",
6067 board_config = ALC260_AUTO;
6070 if (board_config == ALC260_AUTO) {
6071 /* automatic parse from the BIOS config */
6072 err = alc260_parse_auto_config(codec);
6078 "hda_codec: Cannot set up configuration "
6079 "from BIOS. Using base mode...\n");
6080 board_config = ALC260_BASIC;
6084 err = snd_hda_attach_beep_device(codec, 0x1);
6090 if (board_config != ALC260_AUTO)
6091 setup_preset(spec, &alc260_presets[board_config]);
6093 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6094 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6096 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6097 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6099 if (!spec->adc_nids && spec->input_mux) {
6100 /* check whether NID 0x04 is valid */
6101 unsigned int wcap = get_wcaps(codec, 0x04);
6102 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6104 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6105 spec->adc_nids = alc260_adc_nids_alt;
6106 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6108 spec->adc_nids = alc260_adc_nids;
6109 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6112 set_capture_mixer(spec);
6113 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6115 spec->vmaster_nid = 0x08;
6117 codec->patch_ops = alc_patch_ops;
6118 if (board_config == ALC260_AUTO)
6119 spec->init_hook = alc260_auto_init;
6120 #ifdef CONFIG_SND_HDA_POWER_SAVE
6121 if (!spec->loopback.amplist)
6122 spec->loopback.amplist = alc260_loopbacks;
6124 codec->proc_widget_hook = print_realtek_coef;
6133 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6134 * configuration. Each pin widget can choose any input DACs and a mixer.
6135 * Each ADC is connected from a mixer of all inputs. This makes possible
6136 * 6-channel independent captures.
6138 * In addition, an independent DAC for the multi-playback (not used in this
6141 #define ALC882_DIGOUT_NID 0x06
6142 #define ALC882_DIGIN_NID 0x0a
6144 static struct hda_channel_mode alc882_ch_modes[1] = {
6148 static hda_nid_t alc882_dac_nids[4] = {
6149 /* front, rear, clfe, rear_surr */
6150 0x02, 0x03, 0x04, 0x05
6153 /* identical with ALC880 */
6154 #define alc882_adc_nids alc880_adc_nids
6155 #define alc882_adc_nids_alt alc880_adc_nids_alt
6157 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6158 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6161 /* FIXME: should be a matrix-type input source selection */
6163 static struct hda_input_mux alc882_capture_source = {
6167 { "Front Mic", 0x1 },
6173 static struct hda_input_mux mb5_capture_source = {
6185 static struct hda_verb alc882_3ST_ch2_init[] = {
6186 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6187 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6188 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6189 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6196 static struct hda_verb alc882_3ST_ch6_init[] = {
6197 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6198 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6199 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6200 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6201 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6202 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6206 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6207 { 2, alc882_3ST_ch2_init },
6208 { 6, alc882_3ST_ch6_init },
6214 static struct hda_verb alc882_sixstack_ch6_init[] = {
6215 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6216 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6217 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6218 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6225 static struct hda_verb alc882_sixstack_ch8_init[] = {
6226 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6227 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6228 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6229 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6233 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6234 { 6, alc882_sixstack_ch6_init },
6235 { 8, alc882_sixstack_ch8_init },
6239 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6245 static struct hda_verb alc885_mbp_ch2_init[] = {
6246 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6247 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6248 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6255 static struct hda_verb alc885_mbp_ch6_init[] = {
6256 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6257 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6258 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6259 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6260 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6264 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6265 { 2, alc885_mbp_ch2_init },
6266 { 6, alc885_mbp_ch6_init },
6270 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6271 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6273 static struct snd_kcontrol_new alc882_base_mixer[] = {
6274 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6275 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6276 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6277 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6278 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6279 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6280 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6281 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6282 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6283 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6285 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6286 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6287 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6288 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6289 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6290 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6291 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6292 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6293 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6294 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6298 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6299 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6300 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6301 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6302 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6303 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6304 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6306 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6307 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6308 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6312 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6313 HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6314 HDA_BIND_MUTE ("Front Playback Switch", 0x0d, 0x02, HDA_INPUT),
6315 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6316 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
6317 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6318 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6320 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6321 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6322 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6325 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6326 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6327 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6328 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6329 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6330 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6331 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6332 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6333 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6334 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6338 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6339 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6340 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6341 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6342 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6343 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6344 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6345 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6348 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6349 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6350 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6351 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6355 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6356 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6358 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6359 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6360 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6362 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6363 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6364 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6365 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6366 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6367 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6368 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6369 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6370 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6371 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6375 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6376 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6377 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6378 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6379 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6380 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6381 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6382 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6383 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6384 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6385 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6389 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6392 .name = "Channel Mode",
6393 .info = alc_ch_mode_info,
6394 .get = alc_ch_mode_get,
6395 .put = alc_ch_mode_put,
6400 static struct hda_verb alc882_init_verbs[] = {
6401 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6406 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6407 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6408 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6410 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6412 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6414 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6415 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6418 /* Front Pin: output 0 (0x0c) */
6419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6420 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6421 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6422 /* Rear Pin: output 1 (0x0d) */
6423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6425 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6426 /* CLFE Pin: output 2 (0x0e) */
6427 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6428 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6429 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6430 /* Side Pin: output 3 (0x0f) */
6431 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6432 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6433 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6434 /* Mic (rear) pin: input vref at 80% */
6435 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6436 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6437 /* Front Mic pin: input vref at 80% */
6438 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6439 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6440 /* Line In pin: input */
6441 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6442 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6443 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6444 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6445 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6446 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6447 /* CD pin widget for input */
6448 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6450 /* FIXME: use matrix-type input source selection */
6451 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6452 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6458 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6467 /* ADC1: mute amp left and right */
6468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6469 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6470 /* ADC2: mute amp left and right */
6471 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6472 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6473 /* ADC3: mute amp left and right */
6474 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6475 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6480 static struct hda_verb alc882_eapd_verbs[] = {
6481 /* change to EAPD mode */
6482 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6483 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6488 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6489 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6490 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6492 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6493 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6494 /* FIXME: this looks suspicious...
6495 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6496 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6501 static struct hda_verb alc882_macpro_init_verbs[] = {
6502 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6506 /* Front Pin: output 0 (0x0c) */
6507 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6508 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6509 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6510 /* Front Mic pin: input vref at 80% */
6511 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6513 /* Speaker: output */
6514 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6515 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6516 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6517 /* Headphone output (output 0 - 0x0c) */
6518 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6519 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6520 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6522 /* FIXME: use matrix-type input source selection */
6523 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6524 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6526 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6528 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6533 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6539 /* ADC1: mute amp left and right */
6540 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6541 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6542 /* ADC2: mute amp left and right */
6543 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6544 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6545 /* ADC3: mute amp left and right */
6546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6547 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6553 static struct hda_verb alc885_mb5_init_verbs[] = {
6555 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6556 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6557 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6559 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6562 /* Front Pin: output 0 (0x0d) */
6563 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6564 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6565 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},
6566 /* HP Pin: output 0 (0x0c) */
6567 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6568 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6569 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6570 /* Front Mic pin: input vref at 80% */
6571 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6572 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6574 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6579 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6580 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6584 /* Macbook Pro rev3 */
6585 static struct hda_verb alc885_mbp3_init_verbs[] = {
6586 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6591 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6592 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6593 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6594 /* Front Pin: output 0 (0x0c) */
6595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6597 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6598 /* HP Pin: output 0 (0x0d) */
6599 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6600 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6602 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6603 /* Mic (rear) pin: input vref at 80% */
6604 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6605 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6606 /* Front Mic pin: input vref at 80% */
6607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6608 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6609 /* Line In pin: use output 1 when in LineOut mode */
6610 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6611 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6612 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6614 /* FIXME: use matrix-type input source selection */
6615 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6616 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6617 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6618 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6619 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6620 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6622 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6623 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6624 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6625 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6627 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6629 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6630 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6631 /* ADC1: mute amp left and right */
6632 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6633 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6634 /* ADC2: mute amp left and right */
6635 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6636 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6637 /* ADC3: mute amp left and right */
6638 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6639 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6644 /* iMac 24 mixer. */
6645 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6646 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6647 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6651 /* iMac 24 init verbs. */
6652 static struct hda_verb alc885_imac24_init_verbs[] = {
6653 /* Internal speakers: output 0 (0x0c) */
6654 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6655 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6656 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6657 /* Internal speakers: output 0 (0x0c) */
6658 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6659 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6660 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6661 /* Headphone: output 0 (0x0c) */
6662 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6663 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6664 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6666 /* Front Mic: input vref at 80% */
6667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6672 /* Toggle speaker-output according to the hp-jack state */
6673 static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
6675 struct alc_spec *spec = codec->spec;
6677 spec->autocfg.hp_pins[0] = 0x14;
6678 spec->autocfg.speaker_pins[0] = 0x18;
6679 spec->autocfg.speaker_pins[1] = 0x1a;
6680 alc_automute_amp(codec);
6683 static void alc885_mbp3_init_hook(struct hda_codec *codec)
6685 struct alc_spec *spec = codec->spec;
6687 spec->autocfg.hp_pins[0] = 0x15;
6688 spec->autocfg.speaker_pins[0] = 0x14;
6689 alc_automute_amp(codec);
6693 static struct hda_verb alc882_targa_verbs[] = {
6694 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6698 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6700 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6701 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6702 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6704 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6705 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6706 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6707 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6711 /* toggle speaker-output according to the hp-jack state */
6712 static void alc882_targa_automute(struct hda_codec *codec)
6714 struct alc_spec *spec = codec->spec;
6715 alc_automute_amp(codec);
6716 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6717 spec->jack_present ? 1 : 3);
6720 static void alc882_targa_init_hook(struct hda_codec *codec)
6722 struct alc_spec *spec = codec->spec;
6724 spec->autocfg.hp_pins[0] = 0x14;
6725 spec->autocfg.speaker_pins[0] = 0x1b;
6726 alc882_targa_automute(codec);
6729 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6731 if ((res >> 26) == ALC880_HP_EVENT)
6732 alc882_targa_automute(codec);
6735 static struct hda_verb alc882_asus_a7j_verbs[] = {
6736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6739 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6741 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6743 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6744 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6745 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6747 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6748 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6749 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6753 static struct hda_verb alc882_asus_a7m_verbs[] = {
6754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6755 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6757 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6759 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6761 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6762 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6763 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6765 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6766 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6767 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6771 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6773 unsigned int gpiostate, gpiomask, gpiodir;
6775 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6776 AC_VERB_GET_GPIO_DATA, 0);
6779 gpiostate |= (1 << pin);
6781 gpiostate &= ~(1 << pin);
6783 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6784 AC_VERB_GET_GPIO_MASK, 0);
6785 gpiomask |= (1 << pin);
6787 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6788 AC_VERB_GET_GPIO_DIRECTION, 0);
6789 gpiodir |= (1 << pin);
6792 snd_hda_codec_write(codec, codec->afg, 0,
6793 AC_VERB_SET_GPIO_MASK, gpiomask);
6794 snd_hda_codec_write(codec, codec->afg, 0,
6795 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6799 snd_hda_codec_write(codec, codec->afg, 0,
6800 AC_VERB_SET_GPIO_DATA, gpiostate);
6803 /* set up GPIO at initialization */
6804 static void alc885_macpro_init_hook(struct hda_codec *codec)
6806 alc882_gpio_mute(codec, 0, 0);
6807 alc882_gpio_mute(codec, 1, 0);
6810 /* set up GPIO and update auto-muting at initialization */
6811 static void alc885_imac24_init_hook(struct hda_codec *codec)
6813 alc885_macpro_init_hook(codec);
6814 alc885_imac24_automute_init_hook(codec);
6818 * generic initialization of ADC, input mixers and output mixers
6820 static struct hda_verb alc882_auto_init_verbs[] = {
6822 * Unmute ADC0-2 and set the default input to mic-in
6824 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6826 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6828 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6829 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6831 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6833 * Note: PASD motherboards uses the Line In 2 as the input for
6834 * front panel mic (mic 2)
6836 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6844 * Set up output mixers (0x0c - 0x0f)
6846 /* set vol=0 to output mixers */
6847 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6851 /* set up input amps for analog loopback */
6852 /* Amp Indices: DAC = 0, mixer = 1 */
6853 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6854 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6855 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6856 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6857 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6858 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6859 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6860 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6861 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6862 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6864 /* FIXME: use matrix-type input source selection */
6865 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6866 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6867 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6868 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6869 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6870 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6872 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6873 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6874 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6875 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6877 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6878 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6880 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6885 #ifdef CONFIG_SND_HDA_POWER_SAVE
6886 #define alc882_loopbacks alc880_loopbacks
6889 /* pcm configuration: identiacal with ALC880 */
6890 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6891 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6892 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6893 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6896 * configuration and preset
6898 static const char *alc882_models[ALC882_MODEL_LAST] = {
6899 [ALC882_3ST_DIG] = "3stack-dig",
6900 [ALC882_6ST_DIG] = "6stack-dig",
6901 [ALC882_ARIMA] = "arima",
6902 [ALC882_W2JC] = "w2jc",
6903 [ALC882_TARGA] = "targa",
6904 [ALC882_ASUS_A7J] = "asus-a7j",
6905 [ALC882_ASUS_A7M] = "asus-a7m",
6906 [ALC885_MACPRO] = "macpro",
6907 [ALC885_MB5] = "mb5",
6908 [ALC885_MBP3] = "mbp3",
6909 [ALC885_IMAC24] = "imac24",
6910 [ALC882_AUTO] = "auto",
6913 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6914 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6915 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6916 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6917 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6918 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6919 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6920 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6921 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6922 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6923 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6924 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6925 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6929 static struct alc_config_preset alc882_presets[] = {
6930 [ALC882_3ST_DIG] = {
6931 .mixers = { alc882_base_mixer },
6932 .init_verbs = { alc882_init_verbs },
6933 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6934 .dac_nids = alc882_dac_nids,
6935 .dig_out_nid = ALC882_DIGOUT_NID,
6936 .dig_in_nid = ALC882_DIGIN_NID,
6937 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6938 .channel_mode = alc882_ch_modes,
6940 .input_mux = &alc882_capture_source,
6942 [ALC882_6ST_DIG] = {
6943 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6944 .init_verbs = { alc882_init_verbs },
6945 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6946 .dac_nids = alc882_dac_nids,
6947 .dig_out_nid = ALC882_DIGOUT_NID,
6948 .dig_in_nid = ALC882_DIGIN_NID,
6949 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6950 .channel_mode = alc882_sixstack_modes,
6951 .input_mux = &alc882_capture_source,
6954 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6955 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6956 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6957 .dac_nids = alc882_dac_nids,
6958 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6959 .channel_mode = alc882_sixstack_modes,
6960 .input_mux = &alc882_capture_source,
6963 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6964 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6965 alc880_gpio1_init_verbs },
6966 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6967 .dac_nids = alc882_dac_nids,
6968 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6969 .channel_mode = alc880_threestack_modes,
6971 .input_mux = &alc882_capture_source,
6972 .dig_out_nid = ALC882_DIGOUT_NID,
6975 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6976 .init_verbs = { alc885_mbp3_init_verbs,
6977 alc880_gpio1_init_verbs },
6978 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6979 .dac_nids = alc882_dac_nids,
6980 .channel_mode = alc885_mbp_6ch_modes,
6981 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6982 .input_mux = &alc882_capture_source,
6983 .dig_out_nid = ALC882_DIGOUT_NID,
6984 .dig_in_nid = ALC882_DIGIN_NID,
6985 .unsol_event = alc_automute_amp_unsol_event,
6986 .init_hook = alc885_mbp3_init_hook,
6989 .mixers = { alc885_mb5_mixer },
6990 .init_verbs = { alc885_mb5_init_verbs,
6991 alc880_gpio1_init_verbs },
6992 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6993 .dac_nids = alc882_dac_nids,
6994 .channel_mode = alc885_mbp_6ch_modes,
6995 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6996 .input_mux = &mb5_capture_source,
6997 .dig_out_nid = ALC882_DIGOUT_NID,
6998 .dig_in_nid = ALC882_DIGIN_NID,
7001 .mixers = { alc882_macpro_mixer },
7002 .init_verbs = { alc882_macpro_init_verbs },
7003 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7004 .dac_nids = alc882_dac_nids,
7005 .dig_out_nid = ALC882_DIGOUT_NID,
7006 .dig_in_nid = ALC882_DIGIN_NID,
7007 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7008 .channel_mode = alc882_ch_modes,
7009 .input_mux = &alc882_capture_source,
7010 .init_hook = alc885_macpro_init_hook,
7013 .mixers = { alc885_imac24_mixer },
7014 .init_verbs = { alc885_imac24_init_verbs },
7015 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7016 .dac_nids = alc882_dac_nids,
7017 .dig_out_nid = ALC882_DIGOUT_NID,
7018 .dig_in_nid = ALC882_DIGIN_NID,
7019 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7020 .channel_mode = alc882_ch_modes,
7021 .input_mux = &alc882_capture_source,
7022 .unsol_event = alc_automute_amp_unsol_event,
7023 .init_hook = alc885_imac24_init_hook,
7026 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7027 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7028 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7029 .dac_nids = alc882_dac_nids,
7030 .dig_out_nid = ALC882_DIGOUT_NID,
7031 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7032 .adc_nids = alc882_adc_nids,
7033 .capsrc_nids = alc882_capsrc_nids,
7034 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7035 .channel_mode = alc882_3ST_6ch_modes,
7037 .input_mux = &alc882_capture_source,
7038 .unsol_event = alc882_targa_unsol_event,
7039 .init_hook = alc882_targa_init_hook,
7041 [ALC882_ASUS_A7J] = {
7042 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7043 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7044 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7045 .dac_nids = alc882_dac_nids,
7046 .dig_out_nid = ALC882_DIGOUT_NID,
7047 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7048 .adc_nids = alc882_adc_nids,
7049 .capsrc_nids = alc882_capsrc_nids,
7050 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7051 .channel_mode = alc882_3ST_6ch_modes,
7053 .input_mux = &alc882_capture_source,
7055 [ALC882_ASUS_A7M] = {
7056 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7057 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7058 alc880_gpio1_init_verbs,
7059 alc882_asus_a7m_verbs },
7060 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7061 .dac_nids = alc882_dac_nids,
7062 .dig_out_nid = ALC882_DIGOUT_NID,
7063 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7064 .channel_mode = alc880_threestack_modes,
7066 .input_mux = &alc882_capture_source,
7075 PINFIX_ABIT_AW9D_MAX
7078 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7079 { 0x15, 0x01080104 }, /* side */
7080 { 0x16, 0x01011012 }, /* rear */
7081 { 0x17, 0x01016011 }, /* clfe */
7085 static const struct alc_pincfg *alc882_pin_fixes[] = {
7086 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7089 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7090 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7095 * BIOS auto configuration
7097 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7098 hda_nid_t nid, int pin_type,
7102 struct alc_spec *spec = codec->spec;
7105 alc_set_pin_output(codec, nid, pin_type);
7106 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7109 idx = spec->multiout.dac_nids[dac_idx] - 2;
7110 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7114 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7116 struct alc_spec *spec = codec->spec;
7119 for (i = 0; i <= HDA_SIDE; i++) {
7120 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7121 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7123 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7128 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7130 struct alc_spec *spec = codec->spec;
7133 pin = spec->autocfg.hp_pins[0];
7134 if (pin) /* connect to front */
7136 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7137 pin = spec->autocfg.speaker_pins[0];
7139 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7142 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7143 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7145 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7147 struct alc_spec *spec = codec->spec;
7150 for (i = 0; i < AUTO_PIN_LAST; i++) {
7151 hda_nid_t nid = spec->autocfg.input_pins[i];
7154 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7155 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7156 snd_hda_codec_write(codec, nid, 0,
7157 AC_VERB_SET_AMP_GAIN_MUTE,
7162 static void alc882_auto_init_input_src(struct hda_codec *codec)
7164 struct alc_spec *spec = codec->spec;
7167 for (c = 0; c < spec->num_adc_nids; c++) {
7168 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7169 hda_nid_t nid = spec->capsrc_nids[c];
7170 unsigned int mux_idx;
7171 const struct hda_input_mux *imux;
7172 int conns, mute, idx, item;
7174 conns = snd_hda_get_connections(codec, nid, conn_list,
7175 ARRAY_SIZE(conn_list));
7178 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7179 imux = &spec->input_mux[mux_idx];
7180 for (idx = 0; idx < conns; idx++) {
7181 /* if the current connection is the selected one,
7182 * unmute it as default - otherwise mute it
7184 mute = AMP_IN_MUTE(idx);
7185 for (item = 0; item < imux->num_items; item++) {
7186 if (imux->items[item].index == idx) {
7187 if (spec->cur_mux[c] == item)
7188 mute = AMP_IN_UNMUTE(idx);
7192 /* check if we have a selector or mixer
7193 * we could check for the widget type instead, but
7194 * just check for Amp-In presence (in case of mixer
7195 * without amp-in there is something wrong, this
7196 * function shouldn't be used or capsrc nid is wrong)
7198 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7199 snd_hda_codec_write(codec, nid, 0,
7200 AC_VERB_SET_AMP_GAIN_MUTE,
7202 else if (mute != AMP_IN_MUTE(idx))
7203 snd_hda_codec_write(codec, nid, 0,
7204 AC_VERB_SET_CONNECT_SEL,
7210 /* add mic boosts if needed */
7211 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7213 struct alc_spec *spec = codec->spec;
7217 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7218 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7219 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7221 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7225 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7226 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7227 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7229 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7236 /* almost identical with ALC880 parser... */
7237 static int alc882_parse_auto_config(struct hda_codec *codec)
7239 struct alc_spec *spec = codec->spec;
7240 int err = alc880_parse_auto_config(codec);
7245 return 0; /* no config found */
7247 err = alc_auto_add_mic_boost(codec);
7251 /* hack - override the init verbs */
7252 spec->init_verbs[0] = alc882_auto_init_verbs;
7254 return 1; /* config found */
7257 /* additional initialization for auto-configuration model */
7258 static void alc882_auto_init(struct hda_codec *codec)
7260 struct alc_spec *spec = codec->spec;
7261 alc882_auto_init_multi_out(codec);
7262 alc882_auto_init_hp_out(codec);
7263 alc882_auto_init_analog_input(codec);
7264 alc882_auto_init_input_src(codec);
7265 if (spec->unsol_event)
7266 alc_inithook(codec);
7269 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7271 static int patch_alc882(struct hda_codec *codec)
7273 struct alc_spec *spec;
7274 int err, board_config;
7276 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7282 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7286 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7287 /* Pick up systems that don't supply PCI SSID */
7288 switch (codec->subsystem_id) {
7289 case 0x106b0c00: /* Mac Pro */
7290 board_config = ALC885_MACPRO;
7292 case 0x106b1000: /* iMac 24 */
7293 case 0x106b2800: /* AppleTV */
7294 case 0x106b3e00: /* iMac 24 Aluminium */
7295 board_config = ALC885_IMAC24;
7297 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7298 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7299 case 0x106b00a4: /* MacbookPro4,1 */
7300 case 0x106b2c00: /* Macbook Pro rev3 */
7301 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7302 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7303 board_config = ALC885_MBP3;
7305 case 0x106b3f00: /* Macbook 5,1 */
7306 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7307 * seems not working, so apparently
7308 * no perfect solution yet
7310 board_config = ALC885_MB5;
7313 /* ALC889A is handled better as ALC888-compatible */
7314 if (codec->revision_id == 0x100101 ||
7315 codec->revision_id == 0x100103) {
7317 return patch_alc883(codec);
7319 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7320 "trying auto-probe from BIOS...\n",
7322 board_config = ALC882_AUTO;
7326 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7328 if (board_config == ALC882_AUTO) {
7329 /* automatic parse from the BIOS config */
7330 err = alc882_parse_auto_config(codec);
7336 "hda_codec: Cannot set up configuration "
7337 "from BIOS. Using base mode...\n");
7338 board_config = ALC882_3ST_DIG;
7342 err = snd_hda_attach_beep_device(codec, 0x1);
7348 if (board_config != ALC882_AUTO)
7349 setup_preset(spec, &alc882_presets[board_config]);
7351 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7352 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7353 /* FIXME: setup DAC5 */
7354 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7355 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7357 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7358 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7360 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7361 if (!spec->adc_nids && spec->input_mux) {
7362 /* check whether NID 0x07 is valid */
7363 unsigned int wcap = get_wcaps(codec, 0x07);
7365 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7366 if (wcap != AC_WID_AUD_IN) {
7367 spec->adc_nids = alc882_adc_nids_alt;
7368 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7369 spec->capsrc_nids = alc882_capsrc_nids_alt;
7371 spec->adc_nids = alc882_adc_nids;
7372 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7373 spec->capsrc_nids = alc882_capsrc_nids;
7376 set_capture_mixer(spec);
7377 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7379 spec->vmaster_nid = 0x0c;
7381 codec->patch_ops = alc_patch_ops;
7382 if (board_config == ALC882_AUTO)
7383 spec->init_hook = alc882_auto_init;
7384 #ifdef CONFIG_SND_HDA_POWER_SAVE
7385 if (!spec->loopback.amplist)
7386 spec->loopback.amplist = alc882_loopbacks;
7388 codec->proc_widget_hook = print_realtek_coef;
7396 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7397 * configuration. Each pin widget can choose any input DACs and a mixer.
7398 * Each ADC is connected from a mixer of all inputs. This makes possible
7399 * 6-channel independent captures.
7401 * In addition, an independent DAC for the multi-playback (not used in this
7404 #define ALC883_DIGOUT_NID 0x06
7405 #define ALC883_DIGIN_NID 0x0a
7407 #define ALC1200_DIGOUT_NID 0x10
7409 static hda_nid_t alc883_dac_nids[4] = {
7410 /* front, rear, clfe, rear_surr */
7411 0x02, 0x03, 0x04, 0x05
7414 static hda_nid_t alc883_adc_nids[2] = {
7419 static hda_nid_t alc883_adc_nids_alt[1] = {
7424 static hda_nid_t alc883_adc_nids_rev[2] = {
7429 #define alc889_adc_nids alc880_adc_nids
7431 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7433 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7435 #define alc889_capsrc_nids alc882_capsrc_nids
7438 /* FIXME: should be a matrix-type input source selection */
7440 static struct hda_input_mux alc883_capture_source = {
7444 { "Front Mic", 0x1 },
7450 static struct hda_input_mux alc883_3stack_6ch_intel = {
7454 { "Front Mic", 0x0 },
7460 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7468 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7478 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7486 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7490 { "Front Mic", 0x1 },
7495 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7503 static struct hda_input_mux alc889A_mb31_capture_source = {
7507 /* Front Mic (0x01) unused */
7509 /* Line 2 (0x03) unused */
7510 /* CD (0x04) unsused? */
7517 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7524 static struct hda_verb alc883_3ST_ch2_init[] = {
7525 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7526 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7527 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7528 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7535 static struct hda_verb alc883_3ST_ch4_init[] = {
7536 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7537 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7538 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7539 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7540 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7547 static struct hda_verb alc883_3ST_ch6_init[] = {
7548 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7549 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7550 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7551 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7552 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7553 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7557 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7558 { 2, alc883_3ST_ch2_init },
7559 { 4, alc883_3ST_ch4_init },
7560 { 6, alc883_3ST_ch6_init },
7566 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7567 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7568 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7569 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7570 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7577 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7578 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7579 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7580 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7581 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7582 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7589 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7590 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7591 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7592 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7593 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7594 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7595 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7599 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7600 { 2, alc883_3ST_ch2_intel_init },
7601 { 4, alc883_3ST_ch4_intel_init },
7602 { 6, alc883_3ST_ch6_intel_init },
7608 static struct hda_verb alc883_sixstack_ch6_init[] = {
7609 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7610 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7611 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7612 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7619 static struct hda_verb alc883_sixstack_ch8_init[] = {
7620 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7621 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7622 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7623 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7627 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7628 { 6, alc883_sixstack_ch6_init },
7629 { 8, alc883_sixstack_ch8_init },
7632 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7633 static struct hda_verb alc889A_mb31_ch2_init[] = {
7634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7635 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7636 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7641 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7642 static struct hda_verb alc889A_mb31_ch4_init[] = {
7643 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7644 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7645 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7650 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7651 static struct hda_verb alc889A_mb31_ch5_init[] = {
7652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7653 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7654 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7659 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7660 static struct hda_verb alc889A_mb31_ch6_init[] = {
7661 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7662 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7663 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7664 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7668 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7669 { 2, alc889A_mb31_ch2_init },
7670 { 4, alc889A_mb31_ch4_init },
7671 { 5, alc889A_mb31_ch5_init },
7672 { 6, alc889A_mb31_ch6_init },
7675 static struct hda_verb alc883_medion_eapd_verbs[] = {
7676 /* eanable EAPD on medion laptop */
7677 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7678 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7682 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7683 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7686 static struct snd_kcontrol_new alc883_base_mixer[] = {
7687 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7688 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7689 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7690 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7691 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7692 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7693 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7694 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7695 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7696 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7697 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7698 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7699 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7700 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7701 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7703 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7705 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7706 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7707 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7711 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7712 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7713 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7714 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7715 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7716 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7717 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7720 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7722 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7723 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7724 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7728 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7729 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7730 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7731 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7732 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7733 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7734 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7735 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7736 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7737 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7738 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7742 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7743 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7744 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7745 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7746 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7747 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7748 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7750 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7751 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7752 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7756 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7757 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7759 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7760 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7761 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7762 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7763 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7765 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7766 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7767 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7768 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7769 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7773 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7774 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7775 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7776 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7777 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7778 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7779 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7780 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7781 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7783 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7784 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7785 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7786 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7788 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7789 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7790 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7791 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7792 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7796 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7797 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7798 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7799 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7800 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7801 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7803 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7804 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7805 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7806 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7807 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7808 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7809 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7810 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7812 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7813 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7814 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7816 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7820 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7821 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7822 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7823 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7824 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7825 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7826 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7827 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7828 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7829 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7830 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7831 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7832 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7833 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7835 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7836 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7837 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7838 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7839 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7843 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7844 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7845 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7846 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7847 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7848 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7849 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7850 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7851 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7852 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7853 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7854 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7855 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7856 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7858 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7863 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7864 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7865 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7866 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7867 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7868 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7869 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7870 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7871 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7872 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7873 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7874 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7878 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7880 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7881 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7882 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7883 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7885 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7886 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7890 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7891 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7892 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7894 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7895 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7898 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7899 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7903 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7906 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7911 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7912 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7916 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7918 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7919 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7920 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7921 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7922 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7923 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7924 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7928 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7929 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7930 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7931 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7932 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7933 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7934 0x0d, 1, 0x0, HDA_OUTPUT),
7935 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7936 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7937 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7938 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7939 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7942 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7943 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7945 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7946 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7947 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7949 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7953 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
7955 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7956 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7957 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7958 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7959 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
7961 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
7962 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
7963 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
7964 /* Output switches */
7965 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
7966 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
7967 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
7969 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7970 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7979 static struct hda_bind_ctls alc883_bind_cap_vol = {
7980 .ops = &snd_hda_bind_vol,
7982 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7983 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7988 static struct hda_bind_ctls alc883_bind_cap_switch = {
7989 .ops = &snd_hda_bind_sw,
7991 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7992 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7997 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7998 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7999 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8001 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8002 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8003 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8004 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8009 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8010 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8011 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8013 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8014 /* .name = "Capture Source", */
8015 .name = "Input Source",
8017 .info = alc_mux_enum_info,
8018 .get = alc_mux_enum_get,
8019 .put = alc_mux_enum_put,
8024 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8026 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8027 .name = "Channel Mode",
8028 .info = alc_ch_mode_info,
8029 .get = alc_ch_mode_get,
8030 .put = alc_ch_mode_put,
8035 static struct hda_verb alc883_init_verbs[] = {
8036 /* ADC1: mute amp left and right */
8037 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8038 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8039 /* ADC2: mute amp left and right */
8040 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8041 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8042 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8045 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8047 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8048 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8052 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8053 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8055 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8056 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8057 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8059 /* mute analog input loopbacks */
8060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8066 /* Front Pin: output 0 (0x0c) */
8067 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8068 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8069 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8070 /* Rear Pin: output 1 (0x0d) */
8071 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8072 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8073 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8074 /* CLFE Pin: output 2 (0x0e) */
8075 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8076 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8077 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8078 /* Side Pin: output 3 (0x0f) */
8079 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8080 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8081 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8082 /* Mic (rear) pin: input vref at 80% */
8083 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8084 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8085 /* Front Mic pin: input vref at 80% */
8086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8087 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8088 /* Line In pin: input */
8089 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8090 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8091 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8092 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8093 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8094 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8095 /* CD pin widget for input */
8096 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8098 /* FIXME: use matrix-type input source selection */
8099 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8101 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8102 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8103 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8104 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8106 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8108 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8109 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8113 /* toggle speaker-output according to the hp-jack state */
8114 static void alc883_mitac_init_hook(struct hda_codec *codec)
8116 struct alc_spec *spec = codec->spec;
8118 spec->autocfg.hp_pins[0] = 0x15;
8119 spec->autocfg.speaker_pins[0] = 0x14;
8120 spec->autocfg.speaker_pins[1] = 0x17;
8121 alc_automute_amp(codec);
8124 /* auto-toggle front mic */
8126 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8128 unsigned int present;
8131 present = snd_hda_codec_read(codec, 0x18, 0,
8132 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8133 bits = present ? HDA_AMP_MUTE : 0;
8134 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8138 static struct hda_verb alc883_mitac_verbs[] = {
8140 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8143 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8144 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8146 /* enable unsolicited event */
8147 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8148 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8153 static struct hda_verb alc883_clevo_m720_verbs[] = {
8155 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8158 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8161 /* enable unsolicited event */
8162 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8163 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8168 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8170 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8173 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8176 /* enable unsolicited event */
8177 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8182 static struct hda_verb alc883_tagra_verbs[] = {
8183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8186 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8187 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8189 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8190 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8191 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8193 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8194 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8195 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8196 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8201 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8202 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8203 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8204 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8208 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8209 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8210 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8211 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8212 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8216 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8219 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8220 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8221 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8225 static struct hda_verb alc883_haier_w66_verbs[] = {
8226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8229 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8231 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8232 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8233 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8234 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8238 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8239 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8240 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8241 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8242 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8243 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8244 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8245 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8246 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8250 static struct hda_verb alc888_6st_dell_verbs[] = {
8251 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8255 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8257 struct alc_spec *spec = codec->spec;
8259 spec->autocfg.hp_pins[0] = 0x1b;
8260 spec->autocfg.speaker_pins[0] = 0x14;
8261 spec->autocfg.speaker_pins[1] = 0x16;
8262 spec->autocfg.speaker_pins[2] = 0x18;
8263 alc_automute_amp(codec);
8266 static struct hda_verb alc888_3st_hp_verbs[] = {
8267 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8268 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8269 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8270 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8277 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8278 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8279 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8280 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8281 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8288 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8289 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8290 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8291 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8292 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8293 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8300 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8303 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8304 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8305 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8306 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8310 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8311 { 2, alc888_3st_hp_2ch_init },
8312 { 4, alc888_3st_hp_4ch_init },
8313 { 6, alc888_3st_hp_6ch_init },
8316 /* toggle front-jack and RCA according to the hp-jack state */
8317 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8319 unsigned int present;
8321 present = snd_hda_codec_read(codec, 0x1b, 0,
8322 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8323 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8324 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8325 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8326 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8329 /* toggle RCA according to the front-jack state */
8330 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8332 unsigned int present;
8334 present = snd_hda_codec_read(codec, 0x14, 0,
8335 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8336 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8337 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8340 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8343 if ((res >> 26) == ALC880_HP_EVENT)
8344 alc888_lenovo_ms7195_front_automute(codec);
8345 if ((res >> 26) == ALC880_FRONT_EVENT)
8346 alc888_lenovo_ms7195_rca_automute(codec);
8349 static struct hda_verb alc883_medion_md2_verbs[] = {
8350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8353 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8355 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8359 /* toggle speaker-output according to the hp-jack state */
8360 static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8362 struct alc_spec *spec = codec->spec;
8364 spec->autocfg.hp_pins[0] = 0x14;
8365 spec->autocfg.speaker_pins[0] = 0x15;
8366 alc_automute_amp(codec);
8369 /* toggle speaker-output according to the hp-jack state */
8370 #define alc883_tagra_init_hook alc882_targa_init_hook
8371 #define alc883_tagra_unsol_event alc882_targa_unsol_event
8373 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8375 unsigned int present;
8377 present = snd_hda_codec_read(codec, 0x18, 0,
8378 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8379 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8380 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8383 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8385 struct alc_spec *spec = codec->spec;
8387 spec->autocfg.hp_pins[0] = 0x15;
8388 spec->autocfg.speaker_pins[0] = 0x14;
8389 alc_automute_amp(codec);
8390 alc883_clevo_m720_mic_automute(codec);
8393 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8396 switch (res >> 26) {
8397 case ALC880_MIC_EVENT:
8398 alc883_clevo_m720_mic_automute(codec);
8401 alc_automute_amp_unsol_event(codec, res);
8406 /* toggle speaker-output according to the hp-jack state */
8407 static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8409 struct alc_spec *spec = codec->spec;
8411 spec->autocfg.hp_pins[0] = 0x14;
8412 spec->autocfg.speaker_pins[0] = 0x15;
8413 alc_automute_amp(codec);
8416 static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8418 struct alc_spec *spec = codec->spec;
8420 spec->autocfg.hp_pins[0] = 0x1b;
8421 spec->autocfg.speaker_pins[0] = 0x14;
8422 alc_automute_amp(codec);
8425 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8427 unsigned int present;
8430 present = snd_hda_codec_read(codec, 0x14, 0,
8431 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8432 bits = present ? HDA_AMP_MUTE : 0;
8433 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8434 HDA_AMP_MUTE, bits);
8437 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8439 unsigned int present;
8442 present = snd_hda_codec_read(codec, 0x1b, 0,
8443 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8444 bits = present ? HDA_AMP_MUTE : 0;
8445 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8446 HDA_AMP_MUTE, bits);
8447 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8448 HDA_AMP_MUTE, bits);
8451 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8454 if ((res >> 26) == ALC880_HP_EVENT)
8455 alc883_lenovo_101e_all_automute(codec);
8456 if ((res >> 26) == ALC880_FRONT_EVENT)
8457 alc883_lenovo_101e_ispeaker_automute(codec);
8460 /* toggle speaker-output according to the hp-jack state */
8461 static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8463 struct alc_spec *spec = codec->spec;
8465 spec->autocfg.hp_pins[0] = 0x14;
8466 spec->autocfg.speaker_pins[0] = 0x15;
8467 spec->autocfg.speaker_pins[1] = 0x16;
8468 alc_automute_amp(codec);
8471 static struct hda_verb alc883_acer_eapd_verbs[] = {
8472 /* HP Pin: output 0 (0x0c) */
8473 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8474 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8475 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8476 /* Front Pin: output 0 (0x0c) */
8477 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8478 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8480 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8481 /* eanable EAPD on medion laptop */
8482 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8483 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8484 /* enable unsolicited event */
8485 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8489 static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8491 struct alc_spec *spec = codec->spec;
8493 spec->autocfg.hp_pins[0] = 0x1b;
8494 spec->autocfg.speaker_pins[0] = 0x14;
8495 spec->autocfg.speaker_pins[1] = 0x15;
8496 spec->autocfg.speaker_pins[2] = 0x16;
8497 spec->autocfg.speaker_pins[3] = 0x17;
8498 alc_automute_amp(codec);
8501 static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8503 struct alc_spec *spec = codec->spec;
8505 spec->autocfg.hp_pins[0] = 0x1b;
8506 spec->autocfg.speaker_pins[0] = 0x14;
8507 spec->autocfg.speaker_pins[1] = 0x15;
8508 spec->autocfg.speaker_pins[2] = 0x16;
8509 spec->autocfg.speaker_pins[3] = 0x17;
8510 spec->autocfg.speaker_pins[4] = 0x1a;
8511 alc_automute_amp(codec);
8515 * generic initialization of ADC, input mixers and output mixers
8517 static struct hda_verb alc883_auto_init_verbs[] = {
8519 * Unmute ADC0-2 and set the default input to mic-in
8521 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8523 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8524 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8526 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8528 * Note: PASD motherboards uses the Line In 2 as the input for
8529 * front panel mic (mic 2)
8531 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8532 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8533 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8534 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8535 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8536 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8539 * Set up output mixers (0x0c - 0x0f)
8541 /* set vol=0 to output mixers */
8542 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8543 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8544 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8545 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8546 /* set up input amps for analog loopback */
8547 /* Amp Indices: DAC = 0, mixer = 1 */
8548 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8551 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8553 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8554 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8555 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8556 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8557 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8559 /* FIXME: use matrix-type input source selection */
8560 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8563 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8565 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8566 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8571 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8577 static struct hda_verb alc888_asus_m90v_verbs[] = {
8578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8579 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8580 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8581 /* enable unsolicited event */
8582 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8583 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8587 static void alc883_nb_mic_automute(struct hda_codec *codec)
8589 unsigned int present;
8591 present = snd_hda_codec_read(codec, 0x18, 0,
8592 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8593 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8594 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8595 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8596 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8599 static void alc883_M90V_init_hook(struct hda_codec *codec)
8601 struct alc_spec *spec = codec->spec;
8603 spec->autocfg.hp_pins[0] = 0x1b;
8604 spec->autocfg.speaker_pins[0] = 0x14;
8605 spec->autocfg.speaker_pins[1] = 0x15;
8606 spec->autocfg.speaker_pins[2] = 0x16;
8607 alc_automute_pin(codec);
8610 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8613 switch (res >> 26) {
8614 case ALC880_MIC_EVENT:
8615 alc883_nb_mic_automute(codec);
8618 alc_sku_unsol_event(codec, res);
8623 static void alc883_mode2_inithook(struct hda_codec *codec)
8625 alc883_M90V_init_hook(codec);
8626 alc883_nb_mic_automute(codec);
8629 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8631 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8632 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8633 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8634 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8635 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8636 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8637 /* enable unsolicited event */
8638 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8642 static void alc883_eee1601_inithook(struct hda_codec *codec)
8644 struct alc_spec *spec = codec->spec;
8646 spec->autocfg.hp_pins[0] = 0x14;
8647 spec->autocfg.speaker_pins[0] = 0x1b;
8648 alc_automute_pin(codec);
8651 static struct hda_verb alc889A_mb31_verbs[] = {
8652 /* Init rear pin (used as headphone output) */
8653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8655 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8656 /* Init line pin (used as output in 4ch and 6ch mode) */
8657 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8658 /* Init line 2 pin (used as headphone out by default) */
8659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8664 /* Mute speakers according to the headphone jack state */
8665 static void alc889A_mb31_automute(struct hda_codec *codec)
8667 unsigned int present;
8669 /* Mute only in 2ch or 4ch mode */
8670 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8672 present = snd_hda_codec_read(codec, 0x15, 0,
8673 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8674 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8675 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8676 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8677 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8681 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8683 if ((res >> 26) == ALC880_HP_EVENT)
8684 alc889A_mb31_automute(codec);
8687 #ifdef CONFIG_SND_HDA_POWER_SAVE
8688 #define alc883_loopbacks alc880_loopbacks
8691 /* pcm configuration: identiacal with ALC880 */
8692 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8693 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8694 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8695 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8696 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8699 * configuration and preset
8701 static const char *alc883_models[ALC883_MODEL_LAST] = {
8702 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8703 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8704 [ALC883_3ST_6ch] = "3stack-6ch",
8705 [ALC883_6ST_DIG] = "6stack-dig",
8706 [ALC883_TARGA_DIG] = "targa-dig",
8707 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8708 [ALC883_ACER] = "acer",
8709 [ALC883_ACER_ASPIRE] = "acer-aspire",
8710 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8711 [ALC883_MEDION] = "medion",
8712 [ALC883_MEDION_MD2] = "medion-md2",
8713 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8714 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8715 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8716 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8717 [ALC888_LENOVO_SKY] = "lenovo-sky",
8718 [ALC883_HAIER_W66] = "haier-w66",
8719 [ALC888_3ST_HP] = "3stack-hp",
8720 [ALC888_6ST_DELL] = "6stack-dell",
8721 [ALC883_MITAC] = "mitac",
8722 [ALC883_CLEVO_M720] = "clevo-m720",
8723 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8724 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8725 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8726 [ALC1200_ASUS_P5Q] = "asus-p5q",
8727 [ALC889A_MB31] = "mb31",
8728 [ALC883_AUTO] = "auto",
8731 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8732 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8733 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8734 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8735 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8736 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8737 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8738 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8739 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8740 ALC888_ACER_ASPIRE_4930G),
8741 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8742 ALC888_ACER_ASPIRE_4930G),
8743 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8744 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8745 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8746 ALC888_ACER_ASPIRE_4930G),
8747 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8748 ALC888_ACER_ASPIRE_4930G),
8749 /* default Acer -- disabled as it causes more problems.
8750 * model=auto should work fine now
8752 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8753 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8754 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8755 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8756 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8757 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8758 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8759 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8760 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8761 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8762 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8763 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8764 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8765 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8766 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8767 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8768 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8769 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8770 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8771 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8772 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8773 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8774 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8775 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8776 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8777 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8778 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8779 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8780 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8781 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8782 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8783 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8784 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8785 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8786 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8787 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8788 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8789 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8790 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8791 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8792 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8793 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8794 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8795 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8796 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8797 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8798 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8799 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8800 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8801 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8802 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8803 ALC883_FUJITSU_PI2515),
8804 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8805 ALC888_FUJITSU_XA3530),
8806 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8807 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8808 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8809 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8810 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8811 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8812 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8813 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8814 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8815 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8816 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8817 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8818 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8819 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8823 static hda_nid_t alc883_slave_dig_outs[] = {
8824 ALC1200_DIGOUT_NID, 0,
8827 static hda_nid_t alc1200_slave_dig_outs[] = {
8828 ALC883_DIGOUT_NID, 0,
8831 static struct alc_config_preset alc883_presets[] = {
8832 [ALC883_3ST_2ch_DIG] = {
8833 .mixers = { alc883_3ST_2ch_mixer },
8834 .init_verbs = { alc883_init_verbs },
8835 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8836 .dac_nids = alc883_dac_nids,
8837 .dig_out_nid = ALC883_DIGOUT_NID,
8838 .dig_in_nid = ALC883_DIGIN_NID,
8839 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8840 .channel_mode = alc883_3ST_2ch_modes,
8841 .input_mux = &alc883_capture_source,
8843 [ALC883_3ST_6ch_DIG] = {
8844 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8845 .init_verbs = { alc883_init_verbs },
8846 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8847 .dac_nids = alc883_dac_nids,
8848 .dig_out_nid = ALC883_DIGOUT_NID,
8849 .dig_in_nid = ALC883_DIGIN_NID,
8850 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8851 .channel_mode = alc883_3ST_6ch_modes,
8853 .input_mux = &alc883_capture_source,
8855 [ALC883_3ST_6ch] = {
8856 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8857 .init_verbs = { alc883_init_verbs },
8858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8859 .dac_nids = alc883_dac_nids,
8860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8861 .channel_mode = alc883_3ST_6ch_modes,
8863 .input_mux = &alc883_capture_source,
8865 [ALC883_3ST_6ch_INTEL] = {
8866 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8867 .init_verbs = { alc883_init_verbs },
8868 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8869 .dac_nids = alc883_dac_nids,
8870 .dig_out_nid = ALC883_DIGOUT_NID,
8871 .dig_in_nid = ALC883_DIGIN_NID,
8872 .slave_dig_outs = alc883_slave_dig_outs,
8873 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8874 .channel_mode = alc883_3ST_6ch_intel_modes,
8876 .input_mux = &alc883_3stack_6ch_intel,
8878 [ALC883_6ST_DIG] = {
8879 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8880 .init_verbs = { alc883_init_verbs },
8881 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8882 .dac_nids = alc883_dac_nids,
8883 .dig_out_nid = ALC883_DIGOUT_NID,
8884 .dig_in_nid = ALC883_DIGIN_NID,
8885 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8886 .channel_mode = alc883_sixstack_modes,
8887 .input_mux = &alc883_capture_source,
8889 [ALC883_TARGA_DIG] = {
8890 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8891 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8892 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8893 .dac_nids = alc883_dac_nids,
8894 .dig_out_nid = ALC883_DIGOUT_NID,
8895 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8896 .channel_mode = alc883_3ST_6ch_modes,
8898 .input_mux = &alc883_capture_source,
8899 .unsol_event = alc883_tagra_unsol_event,
8900 .init_hook = alc883_tagra_init_hook,
8902 [ALC883_TARGA_2ch_DIG] = {
8903 .mixers = { alc883_tagra_2ch_mixer},
8904 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8905 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8906 .dac_nids = alc883_dac_nids,
8907 .adc_nids = alc883_adc_nids_alt,
8908 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8909 .dig_out_nid = ALC883_DIGOUT_NID,
8910 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8911 .channel_mode = alc883_3ST_2ch_modes,
8912 .input_mux = &alc883_capture_source,
8913 .unsol_event = alc883_tagra_unsol_event,
8914 .init_hook = alc883_tagra_init_hook,
8917 .mixers = { alc883_base_mixer },
8918 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8919 * and the headphone jack. Turn this on and rely on the
8920 * standard mute methods whenever the user wants to turn
8921 * these outputs off.
8923 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8924 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8925 .dac_nids = alc883_dac_nids,
8926 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8927 .channel_mode = alc883_3ST_2ch_modes,
8928 .input_mux = &alc883_capture_source,
8930 [ALC883_ACER_ASPIRE] = {
8931 .mixers = { alc883_acer_aspire_mixer },
8932 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8933 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8934 .dac_nids = alc883_dac_nids,
8935 .dig_out_nid = ALC883_DIGOUT_NID,
8936 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8937 .channel_mode = alc883_3ST_2ch_modes,
8938 .input_mux = &alc883_capture_source,
8939 .unsol_event = alc_automute_amp_unsol_event,
8940 .init_hook = alc883_acer_aspire_init_hook,
8942 [ALC888_ACER_ASPIRE_4930G] = {
8943 .mixers = { alc888_base_mixer,
8944 alc883_chmode_mixer },
8945 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8946 alc888_acer_aspire_4930g_verbs },
8947 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8948 .dac_nids = alc883_dac_nids,
8949 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8950 .adc_nids = alc883_adc_nids_rev,
8951 .capsrc_nids = alc883_capsrc_nids_rev,
8952 .dig_out_nid = ALC883_DIGOUT_NID,
8953 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8954 .channel_mode = alc883_3ST_6ch_modes,
8957 ARRAY_SIZE(alc888_2_capture_sources),
8958 .input_mux = alc888_2_capture_sources,
8959 .unsol_event = alc_automute_amp_unsol_event,
8960 .init_hook = alc888_acer_aspire_4930g_init_hook,
8963 .mixers = { alc883_fivestack_mixer,
8964 alc883_chmode_mixer },
8965 .init_verbs = { alc883_init_verbs,
8966 alc883_medion_eapd_verbs },
8967 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8968 .dac_nids = alc883_dac_nids,
8969 .adc_nids = alc883_adc_nids_alt,
8970 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8971 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8972 .channel_mode = alc883_sixstack_modes,
8973 .input_mux = &alc883_capture_source,
8975 [ALC883_MEDION_MD2] = {
8976 .mixers = { alc883_medion_md2_mixer},
8977 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8978 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8979 .dac_nids = alc883_dac_nids,
8980 .dig_out_nid = ALC883_DIGOUT_NID,
8981 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8982 .channel_mode = alc883_3ST_2ch_modes,
8983 .input_mux = &alc883_capture_source,
8984 .unsol_event = alc_automute_amp_unsol_event,
8985 .init_hook = alc883_medion_md2_init_hook,
8987 [ALC883_LAPTOP_EAPD] = {
8988 .mixers = { alc883_base_mixer },
8989 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8990 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8991 .dac_nids = alc883_dac_nids,
8992 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8993 .channel_mode = alc883_3ST_2ch_modes,
8994 .input_mux = &alc883_capture_source,
8996 [ALC883_CLEVO_M720] = {
8997 .mixers = { alc883_clevo_m720_mixer },
8998 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8999 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9000 .dac_nids = alc883_dac_nids,
9001 .dig_out_nid = ALC883_DIGOUT_NID,
9002 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9003 .channel_mode = alc883_3ST_2ch_modes,
9004 .input_mux = &alc883_capture_source,
9005 .unsol_event = alc883_clevo_m720_unsol_event,
9006 .init_hook = alc883_clevo_m720_init_hook,
9008 [ALC883_LENOVO_101E_2ch] = {
9009 .mixers = { alc883_lenovo_101e_2ch_mixer},
9010 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9011 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9012 .dac_nids = alc883_dac_nids,
9013 .adc_nids = alc883_adc_nids_alt,
9014 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9015 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9016 .channel_mode = alc883_3ST_2ch_modes,
9017 .input_mux = &alc883_lenovo_101e_capture_source,
9018 .unsol_event = alc883_lenovo_101e_unsol_event,
9019 .init_hook = alc883_lenovo_101e_all_automute,
9021 [ALC883_LENOVO_NB0763] = {
9022 .mixers = { alc883_lenovo_nb0763_mixer },
9023 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9024 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9025 .dac_nids = alc883_dac_nids,
9026 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9027 .channel_mode = alc883_3ST_2ch_modes,
9029 .input_mux = &alc883_lenovo_nb0763_capture_source,
9030 .unsol_event = alc_automute_amp_unsol_event,
9031 .init_hook = alc883_medion_md2_init_hook,
9033 [ALC888_LENOVO_MS7195_DIG] = {
9034 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9035 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9036 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9037 .dac_nids = alc883_dac_nids,
9038 .dig_out_nid = ALC883_DIGOUT_NID,
9039 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9040 .channel_mode = alc883_3ST_6ch_modes,
9042 .input_mux = &alc883_capture_source,
9043 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9044 .init_hook = alc888_lenovo_ms7195_front_automute,
9046 [ALC883_HAIER_W66] = {
9047 .mixers = { alc883_tagra_2ch_mixer},
9048 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9049 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9050 .dac_nids = alc883_dac_nids,
9051 .dig_out_nid = ALC883_DIGOUT_NID,
9052 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9053 .channel_mode = alc883_3ST_2ch_modes,
9054 .input_mux = &alc883_capture_source,
9055 .unsol_event = alc_automute_amp_unsol_event,
9056 .init_hook = alc883_haier_w66_init_hook,
9059 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9060 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9061 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9062 .dac_nids = alc883_dac_nids,
9063 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9064 .channel_mode = alc888_3st_hp_modes,
9066 .input_mux = &alc883_capture_source,
9067 .unsol_event = alc_automute_amp_unsol_event,
9068 .init_hook = alc888_3st_hp_init_hook,
9070 [ALC888_6ST_DELL] = {
9071 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9072 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9073 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9074 .dac_nids = alc883_dac_nids,
9075 .dig_out_nid = ALC883_DIGOUT_NID,
9076 .dig_in_nid = ALC883_DIGIN_NID,
9077 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9078 .channel_mode = alc883_sixstack_modes,
9079 .input_mux = &alc883_capture_source,
9080 .unsol_event = alc_automute_amp_unsol_event,
9081 .init_hook = alc888_6st_dell_init_hook,
9084 .mixers = { alc883_mitac_mixer },
9085 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9086 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9087 .dac_nids = alc883_dac_nids,
9088 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9089 .channel_mode = alc883_3ST_2ch_modes,
9090 .input_mux = &alc883_capture_source,
9091 .unsol_event = alc_automute_amp_unsol_event,
9092 .init_hook = alc883_mitac_init_hook,
9094 [ALC883_FUJITSU_PI2515] = {
9095 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9096 .init_verbs = { alc883_init_verbs,
9097 alc883_2ch_fujitsu_pi2515_verbs},
9098 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9099 .dac_nids = alc883_dac_nids,
9100 .dig_out_nid = ALC883_DIGOUT_NID,
9101 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9102 .channel_mode = alc883_3ST_2ch_modes,
9103 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9104 .unsol_event = alc_automute_amp_unsol_event,
9105 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
9107 [ALC888_FUJITSU_XA3530] = {
9108 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9109 .init_verbs = { alc883_init_verbs,
9110 alc888_fujitsu_xa3530_verbs },
9111 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9112 .dac_nids = alc883_dac_nids,
9113 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9114 .adc_nids = alc883_adc_nids_rev,
9115 .capsrc_nids = alc883_capsrc_nids_rev,
9116 .dig_out_nid = ALC883_DIGOUT_NID,
9117 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9118 .channel_mode = alc888_4ST_8ch_intel_modes,
9120 ARRAY_SIZE(alc888_2_capture_sources),
9121 .input_mux = alc888_2_capture_sources,
9122 .unsol_event = alc_automute_amp_unsol_event,
9123 .init_hook = alc888_fujitsu_xa3530_init_hook,
9125 [ALC888_LENOVO_SKY] = {
9126 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9127 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9128 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9129 .dac_nids = alc883_dac_nids,
9130 .dig_out_nid = ALC883_DIGOUT_NID,
9131 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9132 .channel_mode = alc883_sixstack_modes,
9134 .input_mux = &alc883_lenovo_sky_capture_source,
9135 .unsol_event = alc_automute_amp_unsol_event,
9136 .init_hook = alc888_lenovo_sky_init_hook,
9138 [ALC888_ASUS_M90V] = {
9139 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9140 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9141 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9142 .dac_nids = alc883_dac_nids,
9143 .dig_out_nid = ALC883_DIGOUT_NID,
9144 .dig_in_nid = ALC883_DIGIN_NID,
9145 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9146 .channel_mode = alc883_3ST_6ch_modes,
9148 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9149 .unsol_event = alc883_mode2_unsol_event,
9150 .init_hook = alc883_mode2_inithook,
9152 [ALC888_ASUS_EEE1601] = {
9153 .mixers = { alc883_asus_eee1601_mixer },
9154 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9155 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9156 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9157 .dac_nids = alc883_dac_nids,
9158 .dig_out_nid = ALC883_DIGOUT_NID,
9159 .dig_in_nid = ALC883_DIGIN_NID,
9160 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9161 .channel_mode = alc883_3ST_2ch_modes,
9163 .input_mux = &alc883_asus_eee1601_capture_source,
9164 .unsol_event = alc_sku_unsol_event,
9165 .init_hook = alc883_eee1601_inithook,
9167 [ALC1200_ASUS_P5Q] = {
9168 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9169 .init_verbs = { alc883_init_verbs },
9170 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9171 .dac_nids = alc883_dac_nids,
9172 .dig_out_nid = ALC1200_DIGOUT_NID,
9173 .dig_in_nid = ALC883_DIGIN_NID,
9174 .slave_dig_outs = alc1200_slave_dig_outs,
9175 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9176 .channel_mode = alc883_sixstack_modes,
9177 .input_mux = &alc883_capture_source,
9180 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9181 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9182 alc880_gpio1_init_verbs },
9183 .adc_nids = alc883_adc_nids,
9184 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9185 .dac_nids = alc883_dac_nids,
9186 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9187 .channel_mode = alc889A_mb31_6ch_modes,
9188 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9189 .input_mux = &alc889A_mb31_capture_source,
9190 .dig_out_nid = ALC883_DIGOUT_NID,
9191 .unsol_event = alc889A_mb31_unsol_event,
9192 .init_hook = alc889A_mb31_automute,
9198 * BIOS auto configuration
9200 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9201 hda_nid_t nid, int pin_type,
9205 struct alc_spec *spec = codec->spec;
9208 alc_set_pin_output(codec, nid, pin_type);
9209 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9212 idx = spec->multiout.dac_nids[dac_idx] - 2;
9213 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9217 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9219 struct alc_spec *spec = codec->spec;
9222 for (i = 0; i <= HDA_SIDE; i++) {
9223 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9224 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9226 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9231 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9233 struct alc_spec *spec = codec->spec;
9236 pin = spec->autocfg.hp_pins[0];
9237 if (pin) /* connect to front */
9239 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9240 pin = spec->autocfg.speaker_pins[0];
9242 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9245 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9246 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9248 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9250 struct alc_spec *spec = codec->spec;
9253 for (i = 0; i < AUTO_PIN_LAST; i++) {
9254 hda_nid_t nid = spec->autocfg.input_pins[i];
9255 if (alc883_is_input_pin(nid)) {
9256 alc_set_input_pin(codec, nid, i);
9257 if (nid != ALC883_PIN_CD_NID &&
9258 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9259 snd_hda_codec_write(codec, nid, 0,
9260 AC_VERB_SET_AMP_GAIN_MUTE,
9266 #define alc883_auto_init_input_src alc882_auto_init_input_src
9268 /* almost identical with ALC880 parser... */
9269 static int alc883_parse_auto_config(struct hda_codec *codec)
9271 struct alc_spec *spec = codec->spec;
9272 int err = alc880_parse_auto_config(codec);
9273 struct auto_pin_cfg *cfg = &spec->autocfg;
9279 return 0; /* no config found */
9281 err = alc_auto_add_mic_boost(codec);
9285 /* hack - override the init verbs */
9286 spec->init_verbs[0] = alc883_auto_init_verbs;
9288 /* setup input_mux for ALC889 */
9289 if (codec->vendor_id == 0x10ec0889) {
9290 /* digital-mic input pin is excluded in alc880_auto_create..()
9291 * because it's under 0x18
9293 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9294 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9295 struct hda_input_mux *imux = &spec->private_imux[0];
9296 for (i = 1; i < 3; i++)
9297 memcpy(&spec->private_imux[i],
9298 &spec->private_imux[0],
9299 sizeof(spec->private_imux[0]));
9300 imux->items[imux->num_items].label = "Int DMic";
9301 imux->items[imux->num_items].index = 0x0b;
9303 spec->num_mux_defs = 3;
9304 spec->input_mux = spec->private_imux;
9308 return 1; /* config found */
9311 /* additional initialization for auto-configuration model */
9312 static void alc883_auto_init(struct hda_codec *codec)
9314 struct alc_spec *spec = codec->spec;
9315 alc883_auto_init_multi_out(codec);
9316 alc883_auto_init_hp_out(codec);
9317 alc883_auto_init_analog_input(codec);
9318 alc883_auto_init_input_src(codec);
9319 if (spec->unsol_event)
9320 alc_inithook(codec);
9323 static int patch_alc883(struct hda_codec *codec)
9325 struct alc_spec *spec;
9326 int err, board_config;
9328 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9334 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9336 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9339 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
9340 /* Pick up systems that don't supply PCI SSID */
9341 switch (codec->subsystem_id) {
9342 case 0x106b3600: /* Macbook 3.1 */
9343 board_config = ALC889A_MB31;
9347 "hda_codec: Unknown model for %s, trying "
9348 "auto-probe from BIOS...\n", codec->chip_name);
9349 board_config = ALC883_AUTO;
9353 if (board_config == ALC883_AUTO) {
9354 /* automatic parse from the BIOS config */
9355 err = alc883_parse_auto_config(codec);
9361 "hda_codec: Cannot set up configuration "
9362 "from BIOS. Using base mode...\n");
9363 board_config = ALC883_3ST_2ch_DIG;
9367 err = snd_hda_attach_beep_device(codec, 0x1);
9373 if (board_config != ALC883_AUTO)
9374 setup_preset(spec, &alc883_presets[board_config]);
9376 switch (codec->vendor_id) {
9378 if (!spec->num_adc_nids) {
9379 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9380 spec->adc_nids = alc883_adc_nids;
9382 if (!spec->capsrc_nids)
9383 spec->capsrc_nids = alc883_capsrc_nids;
9384 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9385 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9388 if (!spec->num_adc_nids) {
9389 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9390 spec->adc_nids = alc889_adc_nids;
9392 if (!spec->capsrc_nids)
9393 spec->capsrc_nids = alc889_capsrc_nids;
9394 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9398 if (!spec->num_adc_nids) {
9399 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9400 spec->adc_nids = alc883_adc_nids;
9402 if (!spec->capsrc_nids)
9403 spec->capsrc_nids = alc883_capsrc_nids;
9404 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9408 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9409 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9410 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9412 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9413 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9415 if (!spec->cap_mixer)
9416 set_capture_mixer(spec);
9417 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9419 spec->vmaster_nid = 0x0c;
9421 codec->patch_ops = alc_patch_ops;
9422 if (board_config == ALC883_AUTO)
9423 spec->init_hook = alc883_auto_init;
9425 #ifdef CONFIG_SND_HDA_POWER_SAVE
9426 if (!spec->loopback.amplist)
9427 spec->loopback.amplist = alc883_loopbacks;
9429 codec->proc_widget_hook = print_realtek_coef;
9438 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9439 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9441 #define alc262_dac_nids alc260_dac_nids
9442 #define alc262_adc_nids alc882_adc_nids
9443 #define alc262_adc_nids_alt alc882_adc_nids_alt
9444 #define alc262_capsrc_nids alc882_capsrc_nids
9445 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9447 #define alc262_modes alc260_modes
9448 #define alc262_capture_source alc882_capture_source
9450 static hda_nid_t alc262_dmic_adc_nids[1] = {
9455 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9457 static struct snd_kcontrol_new alc262_base_mixer[] = {
9458 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9459 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9460 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9461 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9466 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9467 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9468 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9469 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9470 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9471 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9472 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9473 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9477 /* update HP, line and mono-out pins according to the master switch */
9478 static void alc262_hp_master_update(struct hda_codec *codec)
9480 struct alc_spec *spec = codec->spec;
9481 int val = spec->master_sw;
9484 snd_hda_codec_write_cache(codec, 0x1b, 0,
9485 AC_VERB_SET_PIN_WIDGET_CONTROL,
9487 snd_hda_codec_write_cache(codec, 0x15, 0,
9488 AC_VERB_SET_PIN_WIDGET_CONTROL,
9490 /* mono (speaker) depending on the HP jack sense */
9491 val = val && !spec->jack_present;
9492 snd_hda_codec_write_cache(codec, 0x16, 0,
9493 AC_VERB_SET_PIN_WIDGET_CONTROL,
9497 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9499 struct alc_spec *spec = codec->spec;
9500 unsigned int presence;
9501 presence = snd_hda_codec_read(codec, 0x1b, 0,
9502 AC_VERB_GET_PIN_SENSE, 0);
9503 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9504 alc262_hp_master_update(codec);
9507 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9509 if ((res >> 26) != ALC880_HP_EVENT)
9511 alc262_hp_bpc_automute(codec);
9514 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9516 struct alc_spec *spec = codec->spec;
9517 unsigned int presence;
9518 presence = snd_hda_codec_read(codec, 0x15, 0,
9519 AC_VERB_GET_PIN_SENSE, 0);
9520 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9521 alc262_hp_master_update(codec);
9524 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9527 if ((res >> 26) != ALC880_HP_EVENT)
9529 alc262_hp_wildwest_automute(codec);
9532 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
9534 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9535 struct snd_ctl_elem_value *ucontrol)
9537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9538 struct alc_spec *spec = codec->spec;
9539 int val = !!*ucontrol->value.integer.value;
9541 if (val == spec->master_sw)
9543 spec->master_sw = val;
9544 alc262_hp_master_update(codec);
9548 #define ALC262_HP_MASTER_SWITCH \
9550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9551 .name = "Master Playback Switch", \
9552 .info = snd_ctl_boolean_mono_info, \
9553 .get = alc262_hp_master_sw_get, \
9554 .put = alc262_hp_master_sw_put, \
9557 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9558 ALC262_HP_MASTER_SWITCH,
9559 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9560 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9561 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9562 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9564 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9568 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9569 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9570 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9571 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9572 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9573 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9574 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9575 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9576 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9577 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9581 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9582 ALC262_HP_MASTER_SWITCH,
9583 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9584 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9585 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9587 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9589 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9591 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9592 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9593 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9594 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9595 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9596 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9597 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9601 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9602 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9603 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9604 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9608 /* mute/unmute internal speaker according to the hp jack and mute state */
9609 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9611 struct alc_spec *spec = codec->spec;
9613 spec->autocfg.hp_pins[0] = 0x15;
9614 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9615 alc_automute_amp(codec);
9618 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9619 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9620 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9621 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9622 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9624 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9625 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9629 static struct hda_verb alc262_hp_t5735_verbs[] = {
9630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9631 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9633 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9637 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9638 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9639 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9640 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9641 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9647 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9648 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9649 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9650 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9651 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9653 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9657 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9661 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9668 /* bind hp and internal speaker mute (with plug check) as master switch */
9669 static void alc262_hippo_master_update(struct hda_codec *codec)
9671 struct alc_spec *spec = codec->spec;
9672 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9673 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9674 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9678 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9679 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9680 HDA_AMP_MUTE, mute);
9681 /* mute internal speaker per jack sense */
9682 if (spec->jack_present)
9683 mute = HDA_AMP_MUTE;
9685 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9686 HDA_AMP_MUTE, mute);
9687 if (speaker_nid && speaker_nid != line_nid)
9688 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9689 HDA_AMP_MUTE, mute);
9692 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9694 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9695 struct snd_ctl_elem_value *ucontrol)
9697 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9698 struct alc_spec *spec = codec->spec;
9699 int val = !!*ucontrol->value.integer.value;
9701 if (val == spec->master_sw)
9703 spec->master_sw = val;
9704 alc262_hippo_master_update(codec);
9708 #define ALC262_HIPPO_MASTER_SWITCH \
9710 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9711 .name = "Master Playback Switch", \
9712 .info = snd_ctl_boolean_mono_info, \
9713 .get = alc262_hippo_master_sw_get, \
9714 .put = alc262_hippo_master_sw_put, \
9717 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9718 ALC262_HIPPO_MASTER_SWITCH,
9719 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9720 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9721 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9722 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9723 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9724 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9725 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9726 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9727 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9728 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9729 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9730 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9734 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9735 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9736 ALC262_HIPPO_MASTER_SWITCH,
9737 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9738 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9739 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9740 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9742 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9743 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9744 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9745 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9746 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9750 /* mute/unmute internal speaker according to the hp jack and mute state */
9751 static void alc262_hippo_automute(struct hda_codec *codec)
9753 struct alc_spec *spec = codec->spec;
9754 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9755 unsigned int present;
9757 /* need to execute and sync at first */
9758 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9759 present = snd_hda_codec_read(codec, hp_nid, 0,
9760 AC_VERB_GET_PIN_SENSE, 0);
9761 spec->jack_present = (present & 0x80000000) != 0;
9762 alc262_hippo_master_update(codec);
9765 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9767 if ((res >> 26) != ALC880_HP_EVENT)
9769 alc262_hippo_automute(codec);
9772 static void alc262_hippo_init_hook(struct hda_codec *codec)
9774 struct alc_spec *spec = codec->spec;
9776 spec->autocfg.hp_pins[0] = 0x15;
9777 spec->autocfg.speaker_pins[0] = 0x14;
9778 alc262_hippo_automute(codec);
9781 static void alc262_hippo1_init_hook(struct hda_codec *codec)
9783 struct alc_spec *spec = codec->spec;
9785 spec->autocfg.hp_pins[0] = 0x1b;
9786 spec->autocfg.speaker_pins[0] = 0x14;
9787 alc262_hippo_automute(codec);
9791 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9792 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9793 ALC262_HIPPO_MASTER_SWITCH,
9794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9795 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9796 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9797 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9801 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9802 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9803 ALC262_HIPPO_MASTER_SWITCH,
9804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9806 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9807 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9808 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9812 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9813 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9814 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9815 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9816 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9821 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9822 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9823 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9824 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9828 static struct hda_verb alc262_tyan_verbs[] = {
9829 /* Headphone automute */
9830 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9831 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9832 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9834 /* P11 AUX_IN, white 4-pin connector */
9835 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9836 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9837 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9838 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9843 /* unsolicited event for HP jack sensing */
9844 static void alc262_tyan_init_hook(struct hda_codec *codec)
9846 struct alc_spec *spec = codec->spec;
9848 spec->autocfg.hp_pins[0] = 0x1b;
9849 spec->autocfg.speaker_pins[0] = 0x15;
9850 alc_automute_amp(codec);
9854 #define alc262_capture_mixer alc882_capture_mixer
9855 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9858 * generic initialization of ADC, input mixers and output mixers
9860 static struct hda_verb alc262_init_verbs[] = {
9862 * Unmute ADC0-2 and set the default input to mic-in
9864 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9865 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9866 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9867 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9868 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9869 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9871 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9873 * Note: PASD motherboards uses the Line In 2 as the input for
9874 * front panel mic (mic 2)
9876 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9877 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9878 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9879 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9880 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9881 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9884 * Set up output mixers (0x0c - 0x0e)
9886 /* set vol=0 to output mixers */
9887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9889 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9890 /* set up input amps for analog loopback */
9891 /* Amp Indices: DAC = 0, mixer = 1 */
9892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9893 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9894 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9895 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9896 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9897 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9899 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9900 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9901 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9902 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9904 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9906 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9907 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9908 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9909 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9910 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9912 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9913 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9915 /* FIXME: use matrix-type input source selection */
9916 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9917 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9918 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9936 static struct hda_verb alc262_eapd_verbs[] = {
9937 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9938 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9942 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9943 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9944 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9948 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9949 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9950 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9951 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9953 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9958 static struct hda_verb alc262_sony_unsol_verbs[] = {
9959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9960 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9961 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9963 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9964 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9968 static struct hda_input_mux alc262_dmic_capture_source = {
9971 { "Int DMic", 0x9 },
9976 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9977 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9978 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9979 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9985 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9986 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9987 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9989 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9990 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9991 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9992 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9993 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9997 static void alc262_dmic_automute(struct hda_codec *codec)
9999 unsigned int present;
10001 present = snd_hda_codec_read(codec, 0x18, 0,
10002 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10003 snd_hda_codec_write(codec, 0x22, 0,
10004 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
10008 /* unsolicited event for HP jack sensing */
10009 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
10012 if ((res >> 26) == ALC880_MIC_EVENT)
10013 alc262_dmic_automute(codec);
10015 alc_sku_unsol_event(codec, res);
10018 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
10020 struct alc_spec *spec = codec->spec;
10022 spec->autocfg.hp_pins[0] = 0x15;
10023 spec->autocfg.speaker_pins[0] = 0x14;
10024 alc_automute_pin(codec);
10025 alc262_dmic_automute(codec);
10031 * 0x16 = internal speaker
10032 * 0x18 = external mic
10035 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10036 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10037 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10039 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10040 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10041 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10044 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10048 static struct hda_verb alc262_nec_verbs[] = {
10049 /* Unmute Speaker */
10050 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10053 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10056 /* External mic to headphone */
10057 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10058 /* External mic to speaker */
10059 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10065 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10066 * 0x1b = port replicator headphone out
10069 #define ALC_HP_EVENT 0x37
10071 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10072 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10073 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
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_verb alc262_lenovo_3000_unsol_verbs[] = {
10080 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10081 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10085 static struct hda_input_mux alc262_fujitsu_capture_source = {
10089 { "Int Mic", 0x1 },
10094 static struct hda_input_mux alc262_HP_capture_source = {
10098 { "Front Mic", 0x1 },
10105 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10109 { "Front Mic", 0x2 },
10115 /* mute/unmute internal speaker according to the hp jacks and mute state */
10116 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10118 struct alc_spec *spec = codec->spec;
10121 if (force || !spec->sense_updated) {
10122 unsigned int present;
10123 /* need to execute and sync at first */
10124 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10125 /* check laptop HP jack */
10126 present = snd_hda_codec_read(codec, 0x14, 0,
10127 AC_VERB_GET_PIN_SENSE, 0);
10128 /* need to execute and sync at first */
10129 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10130 /* check docking HP jack */
10131 present |= snd_hda_codec_read(codec, 0x1b, 0,
10132 AC_VERB_GET_PIN_SENSE, 0);
10133 if (present & AC_PINSENSE_PRESENCE)
10134 spec->jack_present = 1;
10136 spec->jack_present = 0;
10137 spec->sense_updated = 1;
10139 /* unmute internal speaker only if both HPs are unplugged and
10140 * master switch is on
10142 if (spec->jack_present)
10143 mute = HDA_AMP_MUTE;
10145 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10146 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10147 HDA_AMP_MUTE, mute);
10150 /* unsolicited event for HP jack sensing */
10151 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10154 if ((res >> 26) != ALC_HP_EVENT)
10156 alc262_fujitsu_automute(codec, 1);
10159 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10161 alc262_fujitsu_automute(codec, 1);
10164 /* bind volumes of both NID 0x0c and 0x0d */
10165 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10166 .ops = &snd_hda_bind_vol,
10168 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10169 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10174 /* mute/unmute internal speaker according to the hp jack and mute state */
10175 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10177 struct alc_spec *spec = codec->spec;
10180 if (force || !spec->sense_updated) {
10181 unsigned int present_int_hp;
10182 /* need to execute and sync at first */
10183 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10184 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10185 AC_VERB_GET_PIN_SENSE, 0);
10186 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10187 spec->sense_updated = 1;
10189 if (spec->jack_present) {
10190 /* mute internal speaker */
10191 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10192 HDA_AMP_MUTE, HDA_AMP_MUTE);
10193 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10194 HDA_AMP_MUTE, HDA_AMP_MUTE);
10196 /* unmute internal speaker if necessary */
10197 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10198 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10199 HDA_AMP_MUTE, mute);
10200 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10201 HDA_AMP_MUTE, mute);
10205 /* unsolicited event for HP jack sensing */
10206 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10209 if ((res >> 26) != ALC_HP_EVENT)
10211 alc262_lenovo_3000_automute(codec, 1);
10214 /* bind hp and internal speaker mute (with plug check) */
10215 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10216 struct snd_ctl_elem_value *ucontrol)
10218 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10219 long *valp = ucontrol->value.integer.value;
10222 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10224 valp ? 0 : HDA_AMP_MUTE);
10225 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10227 valp ? 0 : HDA_AMP_MUTE);
10230 alc262_fujitsu_automute(codec, 0);
10234 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10235 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10238 .name = "Master Playback Switch",
10239 .info = snd_hda_mixer_amp_switch_info,
10240 .get = snd_hda_mixer_amp_switch_get,
10241 .put = alc262_fujitsu_master_sw_put,
10242 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10244 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10245 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10246 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10249 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10250 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10251 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10255 /* bind hp and internal speaker mute (with plug check) */
10256 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10257 struct snd_ctl_elem_value *ucontrol)
10259 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10260 long *valp = ucontrol->value.integer.value;
10263 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10265 valp ? 0 : HDA_AMP_MUTE);
10268 alc262_lenovo_3000_automute(codec, 0);
10272 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10273 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10276 .name = "Master Playback Switch",
10277 .info = snd_hda_mixer_amp_switch_info,
10278 .get = snd_hda_mixer_amp_switch_get,
10279 .put = alc262_lenovo_3000_master_sw_put,
10280 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10282 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10283 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10284 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10286 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10287 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10288 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10289 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10293 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10294 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10295 ALC262_HIPPO_MASTER_SWITCH,
10296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10299 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10300 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10301 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10305 /* additional init verbs for Benq laptops */
10306 static struct hda_verb alc262_EAPD_verbs[] = {
10307 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10308 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10312 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10313 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10314 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10316 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10317 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10321 /* Samsung Q1 Ultra Vista model setup */
10322 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10323 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10324 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10327 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10328 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10332 static struct hda_verb alc262_ultra_verbs[] = {
10334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10336 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10340 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10341 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10343 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10347 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10349 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10350 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10351 /* ADC, choose mic */
10352 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10365 /* mute/unmute internal speaker according to the hp jack and mute state */
10366 static void alc262_ultra_automute(struct hda_codec *codec)
10368 struct alc_spec *spec = codec->spec;
10372 /* auto-mute only when HP is used as HP */
10373 if (!spec->cur_mux[0]) {
10374 unsigned int present;
10375 /* need to execute and sync at first */
10376 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10377 present = snd_hda_codec_read(codec, 0x15, 0,
10378 AC_VERB_GET_PIN_SENSE, 0);
10379 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10380 if (spec->jack_present)
10381 mute = HDA_AMP_MUTE;
10383 /* mute/unmute internal speaker */
10384 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10385 HDA_AMP_MUTE, mute);
10386 /* mute/unmute HP */
10387 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10388 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10391 /* unsolicited event for HP jack sensing */
10392 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10395 if ((res >> 26) != ALC880_HP_EVENT)
10397 alc262_ultra_automute(codec);
10400 static struct hda_input_mux alc262_ultra_capture_source = {
10404 { "Headphone", 0x7 },
10408 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10409 struct snd_ctl_elem_value *ucontrol)
10411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10412 struct alc_spec *spec = codec->spec;
10415 ret = alc_mux_enum_put(kcontrol, ucontrol);
10418 /* reprogram the HP pin as mic or HP according to the input source */
10419 snd_hda_codec_write_cache(codec, 0x15, 0,
10420 AC_VERB_SET_PIN_WIDGET_CONTROL,
10421 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10422 alc262_ultra_automute(codec); /* mute/unmute HP */
10426 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10427 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10428 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10431 .name = "Capture Source",
10432 .info = alc_mux_enum_info,
10433 .get = alc_mux_enum_get,
10434 .put = alc262_ultra_mux_enum_put,
10439 /* add playback controls from the parsed DAC table */
10440 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10441 const struct auto_pin_cfg *cfg)
10446 spec->multiout.num_dacs = 1; /* only use one dac */
10447 spec->multiout.dac_nids = spec->private_dac_nids;
10448 spec->multiout.dac_nids[0] = 2;
10450 nid = cfg->line_out_pins[0];
10452 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10453 "Front Playback Volume",
10454 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10457 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10458 "Front Playback Switch",
10459 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10464 nid = cfg->speaker_pins[0];
10467 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10468 "Speaker Playback Volume",
10469 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10473 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10474 "Speaker Playback Switch",
10475 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10480 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10481 "Speaker Playback Switch",
10482 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10488 nid = cfg->hp_pins[0];
10490 /* spec->multiout.hp_nid = 2; */
10492 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10493 "Headphone Playback Volume",
10494 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10498 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10499 "Headphone Playback Switch",
10500 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10505 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10506 "Headphone Playback Switch",
10507 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10516 /* identical with ALC880 */
10517 #define alc262_auto_create_analog_input_ctls \
10518 alc880_auto_create_analog_input_ctls
10521 * generic initialization of ADC, input mixers and output mixers
10523 static struct hda_verb alc262_volume_init_verbs[] = {
10525 * Unmute ADC0-2 and set the default input to mic-in
10527 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10529 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10531 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10534 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10536 * Note: PASD motherboards uses the Line In 2 as the input for
10537 * front panel mic (mic 2)
10539 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10547 * Set up output mixers (0x0c - 0x0f)
10549 /* set vol=0 to output mixers */
10550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10551 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10554 /* set up input amps for analog loopback */
10555 /* Amp Indices: DAC = 0, mixer = 1 */
10556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10563 /* FIXME: use matrix-type input source selection */
10564 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10565 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10569 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10571 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10584 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10586 * Unmute ADC0-2 and set the default input to mic-in
10588 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10589 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10590 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10591 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10592 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10595 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10597 * Note: PASD motherboards uses the Line In 2 as the input for
10598 * front panel mic (mic 2)
10600 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10607 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10610 * Set up output mixers (0x0c - 0x0e)
10612 /* set vol=0 to output mixers */
10613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10615 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10617 /* set up input amps for analog loopback */
10618 /* Amp Indices: DAC = 0, mixer = 1 */
10619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10620 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10621 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10622 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10623 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10624 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10626 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10627 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10628 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10630 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10633 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10636 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10637 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10638 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10639 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10640 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10642 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10646 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10647 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10650 /* FIXME: use matrix-type input source selection */
10651 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
10652 /* Input mixer1: only unmute Mic */
10653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10656 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10657 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10658 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10659 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10660 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10661 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10663 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10664 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10665 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10666 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10667 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10668 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10670 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10680 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10681 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10683 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10688 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10690 * Unmute ADC0-2 and set the default input to mic-in
10692 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10694 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10695 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10696 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10697 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10699 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10701 * Note: PASD motherboards uses the Line In 2 as the input for front
10702 * panel mic (mic 2)
10704 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10705 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10706 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10707 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10714 * Set up output mixers (0x0c - 0x0e)
10716 /* set vol=0 to output mixers */
10717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10718 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10719 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10721 /* set up input amps for analog loopback */
10722 /* Amp Indices: DAC = 0, mixer = 1 */
10723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10726 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10727 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10728 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10731 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10732 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10733 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10734 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10735 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10736 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10737 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10739 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10740 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10742 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10745 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10747 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10749 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10750 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10752 /* FIXME: use matrix-type input source selection */
10753 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10754 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10756 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10757 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10760 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10768 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10769 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10776 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10779 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10784 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10786 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10787 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10788 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10791 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10792 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10793 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10795 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10796 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10797 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10802 #ifdef CONFIG_SND_HDA_POWER_SAVE
10803 #define alc262_loopbacks alc880_loopbacks
10806 /* pcm configuration: identiacal with ALC880 */
10807 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10808 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10809 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10810 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10813 * BIOS auto configuration
10815 static int alc262_parse_auto_config(struct hda_codec *codec)
10817 struct alc_spec *spec = codec->spec;
10819 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10821 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10825 if (!spec->autocfg.line_outs) {
10826 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10827 spec->multiout.max_channels = 2;
10828 spec->no_analog = 1;
10831 return 0; /* can't find valid BIOS pin config */
10833 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10836 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10840 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10843 if (spec->autocfg.dig_outs) {
10844 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10845 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10847 if (spec->autocfg.dig_in_pin)
10848 spec->dig_in_nid = ALC262_DIGIN_NID;
10850 if (spec->kctls.list)
10851 add_mixer(spec, spec->kctls.list);
10853 add_verb(spec, alc262_volume_init_verbs);
10854 spec->num_mux_defs = 1;
10855 spec->input_mux = &spec->private_imux[0];
10857 err = alc_auto_add_mic_boost(codec);
10861 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10866 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10867 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10868 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10869 #define alc262_auto_init_input_src alc882_auto_init_input_src
10872 /* init callback for auto-configuration model -- overriding the default init */
10873 static void alc262_auto_init(struct hda_codec *codec)
10875 struct alc_spec *spec = codec->spec;
10876 alc262_auto_init_multi_out(codec);
10877 alc262_auto_init_hp_out(codec);
10878 alc262_auto_init_analog_input(codec);
10879 alc262_auto_init_input_src(codec);
10880 if (spec->unsol_event)
10881 alc_inithook(codec);
10885 * configuration and preset
10887 static const char *alc262_models[ALC262_MODEL_LAST] = {
10888 [ALC262_BASIC] = "basic",
10889 [ALC262_HIPPO] = "hippo",
10890 [ALC262_HIPPO_1] = "hippo_1",
10891 [ALC262_FUJITSU] = "fujitsu",
10892 [ALC262_HP_BPC] = "hp-bpc",
10893 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10894 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10895 [ALC262_HP_RP5700] = "hp-rp5700",
10896 [ALC262_BENQ_ED8] = "benq",
10897 [ALC262_BENQ_T31] = "benq-t31",
10898 [ALC262_SONY_ASSAMD] = "sony-assamd",
10899 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10900 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10901 [ALC262_ULTRA] = "ultra",
10902 [ALC262_LENOVO_3000] = "lenovo-3000",
10903 [ALC262_NEC] = "nec",
10904 [ALC262_TYAN] = "tyan",
10905 [ALC262_AUTO] = "auto",
10908 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10909 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10910 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10911 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10913 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10915 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10917 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10918 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10919 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10920 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10921 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10922 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10923 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10924 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10925 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10926 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10927 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10928 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10929 ALC262_HP_TC_T5735),
10930 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10931 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10932 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10933 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10934 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10935 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10936 ALC262_SONY_ASSAMD),
10937 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10938 ALC262_TOSHIBA_RX1),
10939 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10940 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10941 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10942 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10943 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10945 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10946 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10947 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10948 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10949 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10953 static struct alc_config_preset alc262_presets[] = {
10955 .mixers = { alc262_base_mixer },
10956 .init_verbs = { alc262_init_verbs },
10957 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10958 .dac_nids = alc262_dac_nids,
10960 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10961 .channel_mode = alc262_modes,
10962 .input_mux = &alc262_capture_source,
10965 .mixers = { alc262_hippo_mixer },
10966 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10967 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10968 .dac_nids = alc262_dac_nids,
10970 .dig_out_nid = ALC262_DIGOUT_NID,
10971 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10972 .channel_mode = alc262_modes,
10973 .input_mux = &alc262_capture_source,
10974 .unsol_event = alc262_hippo_unsol_event,
10975 .init_hook = alc262_hippo_init_hook,
10977 [ALC262_HIPPO_1] = {
10978 .mixers = { alc262_hippo1_mixer },
10979 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10980 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10981 .dac_nids = alc262_dac_nids,
10983 .dig_out_nid = ALC262_DIGOUT_NID,
10984 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10985 .channel_mode = alc262_modes,
10986 .input_mux = &alc262_capture_source,
10987 .unsol_event = alc262_hippo_unsol_event,
10988 .init_hook = alc262_hippo1_init_hook,
10990 [ALC262_FUJITSU] = {
10991 .mixers = { alc262_fujitsu_mixer },
10992 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10993 alc262_fujitsu_unsol_verbs },
10994 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10995 .dac_nids = alc262_dac_nids,
10997 .dig_out_nid = ALC262_DIGOUT_NID,
10998 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10999 .channel_mode = alc262_modes,
11000 .input_mux = &alc262_fujitsu_capture_source,
11001 .unsol_event = alc262_fujitsu_unsol_event,
11002 .init_hook = alc262_fujitsu_init_hook,
11004 [ALC262_HP_BPC] = {
11005 .mixers = { alc262_HP_BPC_mixer },
11006 .init_verbs = { alc262_HP_BPC_init_verbs },
11007 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11008 .dac_nids = alc262_dac_nids,
11010 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11011 .channel_mode = alc262_modes,
11012 .input_mux = &alc262_HP_capture_source,
11013 .unsol_event = alc262_hp_bpc_unsol_event,
11014 .init_hook = alc262_hp_bpc_automute,
11016 [ALC262_HP_BPC_D7000_WF] = {
11017 .mixers = { alc262_HP_BPC_WildWest_mixer },
11018 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11019 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11020 .dac_nids = alc262_dac_nids,
11022 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11023 .channel_mode = alc262_modes,
11024 .input_mux = &alc262_HP_D7000_capture_source,
11025 .unsol_event = alc262_hp_wildwest_unsol_event,
11026 .init_hook = alc262_hp_wildwest_automute,
11028 [ALC262_HP_BPC_D7000_WL] = {
11029 .mixers = { alc262_HP_BPC_WildWest_mixer,
11030 alc262_HP_BPC_WildWest_option_mixer },
11031 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11032 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11033 .dac_nids = alc262_dac_nids,
11035 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11036 .channel_mode = alc262_modes,
11037 .input_mux = &alc262_HP_D7000_capture_source,
11038 .unsol_event = alc262_hp_wildwest_unsol_event,
11039 .init_hook = alc262_hp_wildwest_automute,
11041 [ALC262_HP_TC_T5735] = {
11042 .mixers = { alc262_hp_t5735_mixer },
11043 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_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,
11050 .unsol_event = alc_automute_amp_unsol_event,
11051 .init_hook = alc262_hp_t5735_init_hook,
11053 [ALC262_HP_RP5700] = {
11054 .mixers = { alc262_hp_rp5700_mixer },
11055 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11056 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11057 .dac_nids = alc262_dac_nids,
11058 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11059 .channel_mode = alc262_modes,
11060 .input_mux = &alc262_hp_rp5700_capture_source,
11062 [ALC262_BENQ_ED8] = {
11063 .mixers = { alc262_base_mixer },
11064 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11065 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11066 .dac_nids = alc262_dac_nids,
11068 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11069 .channel_mode = alc262_modes,
11070 .input_mux = &alc262_capture_source,
11072 [ALC262_SONY_ASSAMD] = {
11073 .mixers = { alc262_sony_mixer },
11074 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11075 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11076 .dac_nids = alc262_dac_nids,
11078 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11079 .channel_mode = alc262_modes,
11080 .input_mux = &alc262_capture_source,
11081 .unsol_event = alc262_hippo_unsol_event,
11082 .init_hook = alc262_hippo_init_hook,
11084 [ALC262_BENQ_T31] = {
11085 .mixers = { alc262_benq_t31_mixer },
11086 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11087 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11088 .dac_nids = alc262_dac_nids,
11090 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11091 .channel_mode = alc262_modes,
11092 .input_mux = &alc262_capture_source,
11093 .unsol_event = alc262_hippo_unsol_event,
11094 .init_hook = alc262_hippo_init_hook,
11097 .mixers = { alc262_ultra_mixer },
11098 .cap_mixer = alc262_ultra_capture_mixer,
11099 .init_verbs = { alc262_ultra_verbs },
11100 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11101 .dac_nids = alc262_dac_nids,
11102 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11103 .channel_mode = alc262_modes,
11104 .input_mux = &alc262_ultra_capture_source,
11105 .adc_nids = alc262_adc_nids, /* ADC0 */
11106 .capsrc_nids = alc262_capsrc_nids,
11107 .num_adc_nids = 1, /* single ADC */
11108 .unsol_event = alc262_ultra_unsol_event,
11109 .init_hook = alc262_ultra_automute,
11111 [ALC262_LENOVO_3000] = {
11112 .mixers = { alc262_lenovo_3000_mixer },
11113 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11114 alc262_lenovo_3000_unsol_verbs },
11115 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11116 .dac_nids = alc262_dac_nids,
11118 .dig_out_nid = ALC262_DIGOUT_NID,
11119 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11120 .channel_mode = alc262_modes,
11121 .input_mux = &alc262_fujitsu_capture_source,
11122 .unsol_event = alc262_lenovo_3000_unsol_event,
11125 .mixers = { alc262_nec_mixer },
11126 .init_verbs = { alc262_nec_verbs },
11127 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11128 .dac_nids = alc262_dac_nids,
11130 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11131 .channel_mode = alc262_modes,
11132 .input_mux = &alc262_capture_source,
11134 [ALC262_TOSHIBA_S06] = {
11135 .mixers = { alc262_toshiba_s06_mixer },
11136 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11137 alc262_eapd_verbs },
11138 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11139 .capsrc_nids = alc262_dmic_capsrc_nids,
11140 .dac_nids = alc262_dac_nids,
11141 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11142 .dig_out_nid = ALC262_DIGOUT_NID,
11143 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11144 .channel_mode = alc262_modes,
11145 .input_mux = &alc262_dmic_capture_source,
11146 .unsol_event = alc262_toshiba_s06_unsol_event,
11147 .init_hook = alc262_toshiba_s06_init_hook,
11149 [ALC262_TOSHIBA_RX1] = {
11150 .mixers = { alc262_toshiba_rx1_mixer },
11151 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11152 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11153 .dac_nids = alc262_dac_nids,
11155 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11156 .channel_mode = alc262_modes,
11157 .input_mux = &alc262_capture_source,
11158 .unsol_event = alc262_hippo_unsol_event,
11159 .init_hook = alc262_hippo_init_hook,
11162 .mixers = { alc262_tyan_mixer },
11163 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11164 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11165 .dac_nids = alc262_dac_nids,
11167 .dig_out_nid = ALC262_DIGOUT_NID,
11168 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11169 .channel_mode = alc262_modes,
11170 .input_mux = &alc262_capture_source,
11171 .unsol_event = alc_automute_amp_unsol_event,
11172 .init_hook = alc262_tyan_init_hook,
11176 static int patch_alc262(struct hda_codec *codec)
11178 struct alc_spec *spec;
11182 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11186 codec->spec = spec;
11188 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11193 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11194 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11195 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11196 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11200 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11202 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11206 if (board_config < 0) {
11207 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11208 "trying auto-probe from BIOS...\n", codec->chip_name);
11209 board_config = ALC262_AUTO;
11212 if (board_config == ALC262_AUTO) {
11213 /* automatic parse from the BIOS config */
11214 err = alc262_parse_auto_config(codec);
11220 "hda_codec: Cannot set up configuration "
11221 "from BIOS. Using base mode...\n");
11222 board_config = ALC262_BASIC;
11226 if (!spec->no_analog) {
11227 err = snd_hda_attach_beep_device(codec, 0x1);
11234 if (board_config != ALC262_AUTO)
11235 setup_preset(spec, &alc262_presets[board_config]);
11237 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11238 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11240 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11241 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11243 spec->capture_style = CAPT_MIX;
11244 if (!spec->adc_nids && spec->input_mux) {
11245 /* check whether NID 0x07 is valid */
11246 unsigned int wcap = get_wcaps(codec, 0x07);
11249 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11250 if (wcap != AC_WID_AUD_IN) {
11251 spec->adc_nids = alc262_adc_nids_alt;
11252 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11253 spec->capsrc_nids = alc262_capsrc_nids_alt;
11255 spec->adc_nids = alc262_adc_nids;
11256 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11257 spec->capsrc_nids = alc262_capsrc_nids;
11260 if (!spec->cap_mixer && !spec->no_analog)
11261 set_capture_mixer(spec);
11262 if (!spec->no_analog)
11263 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11265 spec->vmaster_nid = 0x0c;
11267 codec->patch_ops = alc_patch_ops;
11268 if (board_config == ALC262_AUTO)
11269 spec->init_hook = alc262_auto_init;
11270 #ifdef CONFIG_SND_HDA_POWER_SAVE
11271 if (!spec->loopback.amplist)
11272 spec->loopback.amplist = alc262_loopbacks;
11274 codec->proc_widget_hook = print_realtek_coef;
11280 * ALC268 channel source setting (2 channel)
11282 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11283 #define alc268_modes alc260_modes
11285 static hda_nid_t alc268_dac_nids[2] = {
11290 static hda_nid_t alc268_adc_nids[2] = {
11295 static hda_nid_t alc268_adc_nids_alt[1] = {
11300 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11302 static struct snd_kcontrol_new alc268_base_mixer[] = {
11303 /* output mixer control */
11304 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11305 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11306 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11307 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11308 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11309 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11310 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11314 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11315 /* output mixer control */
11316 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11317 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11318 ALC262_HIPPO_MASTER_SWITCH,
11319 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11320 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11321 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11325 /* bind Beep switches of both NID 0x0f and 0x10 */
11326 static struct hda_bind_ctls alc268_bind_beep_sw = {
11327 .ops = &snd_hda_bind_sw,
11329 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11330 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11335 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11336 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11337 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11341 static struct hda_verb alc268_eapd_verbs[] = {
11342 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11343 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11347 /* Toshiba specific */
11348 static struct hda_verb alc268_toshiba_verbs[] = {
11349 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11353 static struct hda_input_mux alc268_acer_lc_capture_source = {
11361 /* Acer specific */
11362 /* bind volumes of both NID 0x02 and 0x03 */
11363 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11364 .ops = &snd_hda_bind_vol,
11366 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11367 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11372 /* mute/unmute internal speaker according to the hp jack and mute state */
11373 static void alc268_acer_automute(struct hda_codec *codec, int force)
11375 struct alc_spec *spec = codec->spec;
11378 if (force || !spec->sense_updated) {
11379 unsigned int present;
11380 present = snd_hda_codec_read(codec, 0x14, 0,
11381 AC_VERB_GET_PIN_SENSE, 0);
11382 spec->jack_present = (present & 0x80000000) != 0;
11383 spec->sense_updated = 1;
11385 if (spec->jack_present)
11386 mute = HDA_AMP_MUTE; /* mute internal speaker */
11387 else /* unmute internal speaker if necessary */
11388 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11389 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11390 HDA_AMP_MUTE, mute);
11394 /* bind hp and internal speaker mute (with plug check) */
11395 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11396 struct snd_ctl_elem_value *ucontrol)
11398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11399 long *valp = ucontrol->value.integer.value;
11402 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11404 valp[0] ? 0 : HDA_AMP_MUTE);
11405 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11407 valp[1] ? 0 : HDA_AMP_MUTE);
11409 alc268_acer_automute(codec, 0);
11413 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11414 /* output mixer control */
11415 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11418 .name = "Master Playback Switch",
11419 .info = snd_hda_mixer_amp_switch_info,
11420 .get = snd_hda_mixer_amp_switch_get,
11421 .put = alc268_acer_master_sw_put,
11422 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11424 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11428 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11429 /* output mixer control */
11430 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11432 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11433 .name = "Master Playback Switch",
11434 .info = snd_hda_mixer_amp_switch_info,
11435 .get = snd_hda_mixer_amp_switch_get,
11436 .put = alc268_acer_master_sw_put,
11437 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11439 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11440 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11441 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11445 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11446 /* output mixer control */
11447 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11449 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11450 .name = "Master Playback Switch",
11451 .info = snd_hda_mixer_amp_switch_info,
11452 .get = snd_hda_mixer_amp_switch_get,
11453 .put = alc268_acer_master_sw_put,
11454 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11456 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11457 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11461 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11462 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11464 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11465 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11466 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11471 static struct hda_verb alc268_acer_verbs[] = {
11472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11473 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11476 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11477 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11478 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11482 /* unsolicited event for HP jack sensing */
11483 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11484 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11486 static void alc268_acer_unsol_event(struct hda_codec *codec,
11489 if ((res >> 26) != ALC880_HP_EVENT)
11491 alc268_acer_automute(codec, 1);
11494 static void alc268_acer_init_hook(struct hda_codec *codec)
11496 alc268_acer_automute(codec, 1);
11499 /* toggle speaker-output according to the hp-jack state */
11500 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11502 unsigned int present;
11503 unsigned char bits;
11505 present = snd_hda_codec_read(codec, 0x15, 0,
11506 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11507 bits = present ? AMP_IN_MUTE(0) : 0;
11508 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11509 AMP_IN_MUTE(0), bits);
11510 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11511 AMP_IN_MUTE(0), bits);
11515 static void alc268_acer_mic_automute(struct hda_codec *codec)
11517 unsigned int present;
11519 present = snd_hda_codec_read(codec, 0x18, 0,
11520 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11521 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11522 present ? 0x0 : 0x6);
11525 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11528 if ((res >> 26) == ALC880_HP_EVENT)
11529 alc268_aspire_one_speaker_automute(codec);
11530 if ((res >> 26) == ALC880_MIC_EVENT)
11531 alc268_acer_mic_automute(codec);
11534 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11536 alc268_aspire_one_speaker_automute(codec);
11537 alc268_acer_mic_automute(codec);
11540 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11541 /* output mixer control */
11542 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11543 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11544 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11545 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11546 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11547 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11551 static struct hda_verb alc268_dell_verbs[] = {
11552 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11553 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11554 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11558 /* mute/unmute internal speaker according to the hp jack and mute state */
11559 static void alc268_dell_init_hook(struct hda_codec *codec)
11561 struct alc_spec *spec = codec->spec;
11563 spec->autocfg.hp_pins[0] = 0x15;
11564 spec->autocfg.speaker_pins[0] = 0x14;
11565 alc_automute_pin(codec);
11568 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11569 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11570 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11571 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11572 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11573 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11574 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11575 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11576 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11580 static struct hda_verb alc267_quanta_il1_verbs[] = {
11581 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11582 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11586 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11588 unsigned int present;
11590 present = snd_hda_codec_read(codec, 0x18, 0,
11591 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11592 snd_hda_codec_write(codec, 0x23, 0,
11593 AC_VERB_SET_CONNECT_SEL,
11594 present ? 0x00 : 0x01);
11597 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11599 struct alc_spec *spec = codec->spec;
11601 spec->autocfg.hp_pins[0] = 0x15;
11602 spec->autocfg.speaker_pins[0] = 0x14;
11603 alc_automute_pin(codec);
11604 alc267_quanta_il1_mic_automute(codec);
11607 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11610 switch (res >> 26) {
11611 case ALC880_MIC_EVENT:
11612 alc267_quanta_il1_mic_automute(codec);
11615 alc_sku_unsol_event(codec, res);
11621 * generic initialization of ADC, input mixers and output mixers
11623 static struct hda_verb alc268_base_init_verbs[] = {
11624 /* Unmute DAC0-1 and set vol = 0 */
11625 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11626 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11629 * Set up output mixers (0x0c - 0x0e)
11631 /* set vol=0 to output mixers */
11632 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11633 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11635 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11636 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11639 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11640 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11641 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11642 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11643 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11644 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11645 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11647 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11649 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11650 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11651 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11653 /* set PCBEEP vol = 0, mute connections */
11654 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11656 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11658 /* Unmute Selector 23h,24h and set the default input to mic-in */
11660 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11662 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11663 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11669 * generic initialization of ADC, input mixers and output mixers
11671 static struct hda_verb alc268_volume_init_verbs[] = {
11672 /* set output DAC */
11673 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11674 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11676 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11677 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11678 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11679 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11680 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11683 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11686 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11687 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11689 /* set PCBEEP vol = 0, mute connections */
11690 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11691 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11692 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11697 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11698 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11699 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11702 /* The multiple "Capture Source" controls confuse alsamixer
11703 * So call somewhat different..
11705 /* .name = "Capture Source", */
11706 .name = "Input Source",
11708 .info = alc_mux_enum_info,
11709 .get = alc_mux_enum_get,
11710 .put = alc_mux_enum_put,
11715 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11716 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11717 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11718 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11719 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11721 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11722 /* The multiple "Capture Source" controls confuse alsamixer
11723 * So call somewhat different..
11725 /* .name = "Capture Source", */
11726 .name = "Input Source",
11728 .info = alc_mux_enum_info,
11729 .get = alc_mux_enum_get,
11730 .put = alc_mux_enum_put,
11735 static struct hda_input_mux alc268_capture_source = {
11739 { "Front Mic", 0x1 },
11745 static struct hda_input_mux alc268_acer_capture_source = {
11749 { "Internal Mic", 0x1 },
11754 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11758 { "Internal Mic", 0x6 },
11763 #ifdef CONFIG_SND_DEBUG
11764 static struct snd_kcontrol_new alc268_test_mixer[] = {
11765 /* Volume widgets */
11766 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11767 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11768 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11769 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11770 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11771 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11772 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11773 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11774 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11775 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11776 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11777 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11778 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11779 /* The below appears problematic on some hardwares */
11780 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11781 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11782 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11783 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11784 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11786 /* Modes for retasking pin widgets */
11787 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11788 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11789 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11790 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11792 /* Controls for GPIO pins, assuming they are configured as outputs */
11793 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11794 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11795 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11796 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11798 /* Switches to allow the digital SPDIF output pin to be enabled.
11799 * The ALC268 does not have an SPDIF input.
11801 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11803 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11804 * this output to turn on an external amplifier.
11806 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11807 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11813 /* create input playback/capture controls for the given pin */
11814 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11815 const char *ctlname, int idx)
11820 sprintf(name, "%s Playback Volume", ctlname);
11822 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11823 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11827 } else if (nid == 0x15) {
11828 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11829 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11835 sprintf(name, "%s Playback Switch", ctlname);
11836 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11837 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11843 /* add playback controls from the parsed DAC table */
11844 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11845 const struct auto_pin_cfg *cfg)
11850 spec->multiout.num_dacs = 2; /* only use one dac */
11851 spec->multiout.dac_nids = spec->private_dac_nids;
11852 spec->multiout.dac_nids[0] = 2;
11853 spec->multiout.dac_nids[1] = 3;
11855 nid = cfg->line_out_pins[0];
11857 alc268_new_analog_output(spec, nid, "Front", 0);
11859 nid = cfg->speaker_pins[0];
11861 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11862 "Speaker Playback Volume",
11863 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11867 nid = cfg->hp_pins[0];
11869 alc268_new_analog_output(spec, nid, "Headphone", 0);
11871 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11873 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11874 "Mono Playback Switch",
11875 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11882 /* create playback/capture controls for input pins */
11883 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11884 const struct auto_pin_cfg *cfg)
11886 struct hda_input_mux *imux = &spec->private_imux[0];
11889 for (i = 0; i < AUTO_PIN_LAST; i++) {
11890 switch(cfg->input_pins[i]) {
11892 idx1 = 0; /* Mic 1 */
11895 idx1 = 1; /* Mic 2 */
11898 idx1 = 2; /* Line In */
11905 idx1 = 6; /* digital mics */
11910 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11911 imux->items[imux->num_items].index = idx1;
11917 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11919 struct alc_spec *spec = codec->spec;
11920 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11921 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11922 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11923 unsigned int dac_vol1, dac_vol2;
11926 snd_hda_codec_write(codec, speaker_nid, 0,
11927 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11928 snd_hda_codec_write(codec, 0x0f, 0,
11929 AC_VERB_SET_AMP_GAIN_MUTE,
11931 snd_hda_codec_write(codec, 0x10, 0,
11932 AC_VERB_SET_AMP_GAIN_MUTE,
11935 snd_hda_codec_write(codec, 0x0f, 0,
11936 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11937 snd_hda_codec_write(codec, 0x10, 0,
11938 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11941 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11942 if (line_nid == 0x14)
11943 dac_vol2 = AMP_OUT_ZERO;
11944 else if (line_nid == 0x15)
11945 dac_vol1 = AMP_OUT_ZERO;
11946 if (hp_nid == 0x14)
11947 dac_vol2 = AMP_OUT_ZERO;
11948 else if (hp_nid == 0x15)
11949 dac_vol1 = AMP_OUT_ZERO;
11950 if (line_nid != 0x16 || hp_nid != 0x16 ||
11951 spec->autocfg.line_out_pins[1] != 0x16 ||
11952 spec->autocfg.line_out_pins[2] != 0x16)
11953 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11955 snd_hda_codec_write(codec, 0x02, 0,
11956 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11957 snd_hda_codec_write(codec, 0x03, 0,
11958 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11961 /* pcm configuration: identiacal with ALC880 */
11962 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11963 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11964 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11965 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11968 * BIOS auto configuration
11970 static int alc268_parse_auto_config(struct hda_codec *codec)
11972 struct alc_spec *spec = codec->spec;
11974 static hda_nid_t alc268_ignore[] = { 0 };
11976 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11980 if (!spec->autocfg.line_outs) {
11981 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11982 spec->multiout.max_channels = 2;
11983 spec->no_analog = 1;
11986 return 0; /* can't find valid BIOS pin config */
11988 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11991 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11995 spec->multiout.max_channels = 2;
11998 /* digital only support output */
11999 if (spec->autocfg.dig_outs) {
12000 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12001 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12003 if (spec->kctls.list)
12004 add_mixer(spec, spec->kctls.list);
12006 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12007 add_mixer(spec, alc268_beep_mixer);
12009 add_verb(spec, alc268_volume_init_verbs);
12010 spec->num_mux_defs = 1;
12011 spec->input_mux = &spec->private_imux[0];
12013 err = alc_auto_add_mic_boost(codec);
12020 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12021 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12022 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12024 /* init callback for auto-configuration model -- overriding the default init */
12025 static void alc268_auto_init(struct hda_codec *codec)
12027 struct alc_spec *spec = codec->spec;
12028 alc268_auto_init_multi_out(codec);
12029 alc268_auto_init_hp_out(codec);
12030 alc268_auto_init_mono_speaker_out(codec);
12031 alc268_auto_init_analog_input(codec);
12032 if (spec->unsol_event)
12033 alc_inithook(codec);
12037 * configuration and preset
12039 static const char *alc268_models[ALC268_MODEL_LAST] = {
12040 [ALC267_QUANTA_IL1] = "quanta-il1",
12041 [ALC268_3ST] = "3stack",
12042 [ALC268_TOSHIBA] = "toshiba",
12043 [ALC268_ACER] = "acer",
12044 [ALC268_ACER_DMIC] = "acer-dmic",
12045 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12046 [ALC268_DELL] = "dell",
12047 [ALC268_ZEPTO] = "zepto",
12048 #ifdef CONFIG_SND_DEBUG
12049 [ALC268_TEST] = "test",
12051 [ALC268_AUTO] = "auto",
12054 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12055 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12056 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12057 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12058 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12059 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12060 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12061 ALC268_ACER_ASPIRE_ONE),
12062 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12063 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12064 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
12065 SND_PCI_QUIRK(0x103c, 0x30f1, "HP TX25xx series", ALC268_TOSHIBA),
12066 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12067 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
12068 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
12069 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
12070 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12071 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12072 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12073 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12077 static struct alc_config_preset alc268_presets[] = {
12078 [ALC267_QUANTA_IL1] = {
12079 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12080 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12081 alc267_quanta_il1_verbs },
12082 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12083 .dac_nids = alc268_dac_nids,
12084 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12085 .adc_nids = alc268_adc_nids_alt,
12087 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12088 .channel_mode = alc268_modes,
12089 .input_mux = &alc268_capture_source,
12090 .unsol_event = alc267_quanta_il1_unsol_event,
12091 .init_hook = alc267_quanta_il1_init_hook,
12094 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12095 alc268_beep_mixer },
12096 .init_verbs = { alc268_base_init_verbs },
12097 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12098 .dac_nids = alc268_dac_nids,
12099 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12100 .adc_nids = alc268_adc_nids_alt,
12101 .capsrc_nids = alc268_capsrc_nids,
12103 .dig_out_nid = ALC268_DIGOUT_NID,
12104 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12105 .channel_mode = alc268_modes,
12106 .input_mux = &alc268_capture_source,
12108 [ALC268_TOSHIBA] = {
12109 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12110 alc268_beep_mixer },
12111 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12112 alc268_toshiba_verbs },
12113 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12114 .dac_nids = alc268_dac_nids,
12115 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12116 .adc_nids = alc268_adc_nids_alt,
12117 .capsrc_nids = alc268_capsrc_nids,
12119 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12120 .channel_mode = alc268_modes,
12121 .input_mux = &alc268_capture_source,
12122 .unsol_event = alc268_toshiba_unsol_event,
12123 .init_hook = alc268_toshiba_init_hook,
12126 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12127 alc268_beep_mixer },
12128 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12129 alc268_acer_verbs },
12130 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12131 .dac_nids = alc268_dac_nids,
12132 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12133 .adc_nids = alc268_adc_nids_alt,
12134 .capsrc_nids = alc268_capsrc_nids,
12136 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12137 .channel_mode = alc268_modes,
12138 .input_mux = &alc268_acer_capture_source,
12139 .unsol_event = alc268_acer_unsol_event,
12140 .init_hook = alc268_acer_init_hook,
12142 [ALC268_ACER_DMIC] = {
12143 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12144 alc268_beep_mixer },
12145 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12146 alc268_acer_verbs },
12147 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12148 .dac_nids = alc268_dac_nids,
12149 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12150 .adc_nids = alc268_adc_nids_alt,
12151 .capsrc_nids = alc268_capsrc_nids,
12153 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12154 .channel_mode = alc268_modes,
12155 .input_mux = &alc268_acer_dmic_capture_source,
12156 .unsol_event = alc268_acer_unsol_event,
12157 .init_hook = alc268_acer_init_hook,
12159 [ALC268_ACER_ASPIRE_ONE] = {
12160 .mixers = { alc268_acer_aspire_one_mixer,
12162 alc268_capture_alt_mixer },
12163 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12164 alc268_acer_aspire_one_verbs },
12165 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12166 .dac_nids = alc268_dac_nids,
12167 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12168 .adc_nids = alc268_adc_nids_alt,
12169 .capsrc_nids = alc268_capsrc_nids,
12171 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12172 .channel_mode = alc268_modes,
12173 .input_mux = &alc268_acer_lc_capture_source,
12174 .unsol_event = alc268_acer_lc_unsol_event,
12175 .init_hook = alc268_acer_lc_init_hook,
12178 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12179 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12180 alc268_dell_verbs },
12181 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12182 .dac_nids = alc268_dac_nids,
12184 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12185 .channel_mode = alc268_modes,
12186 .unsol_event = alc_sku_unsol_event,
12187 .init_hook = alc268_dell_init_hook,
12188 .input_mux = &alc268_capture_source,
12191 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12192 alc268_beep_mixer },
12193 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12194 alc268_toshiba_verbs },
12195 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12196 .dac_nids = alc268_dac_nids,
12197 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12198 .adc_nids = alc268_adc_nids_alt,
12199 .capsrc_nids = alc268_capsrc_nids,
12201 .dig_out_nid = ALC268_DIGOUT_NID,
12202 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12203 .channel_mode = alc268_modes,
12204 .input_mux = &alc268_capture_source,
12205 .unsol_event = alc268_toshiba_unsol_event,
12206 .init_hook = alc268_toshiba_init_hook
12208 #ifdef CONFIG_SND_DEBUG
12210 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12211 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12212 alc268_volume_init_verbs },
12213 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12214 .dac_nids = alc268_dac_nids,
12215 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12216 .adc_nids = alc268_adc_nids_alt,
12217 .capsrc_nids = alc268_capsrc_nids,
12219 .dig_out_nid = ALC268_DIGOUT_NID,
12220 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12221 .channel_mode = alc268_modes,
12222 .input_mux = &alc268_capture_source,
12227 static int patch_alc268(struct hda_codec *codec)
12229 struct alc_spec *spec;
12231 int i, has_beep, err;
12233 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12237 codec->spec = spec;
12239 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12243 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12244 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12245 "trying auto-probe from BIOS...\n", codec->chip_name);
12246 board_config = ALC268_AUTO;
12249 if (board_config == ALC268_AUTO) {
12250 /* automatic parse from the BIOS config */
12251 err = alc268_parse_auto_config(codec);
12257 "hda_codec: Cannot set up configuration "
12258 "from BIOS. Using base mode...\n");
12259 board_config = ALC268_3ST;
12263 if (board_config != ALC268_AUTO)
12264 setup_preset(spec, &alc268_presets[board_config]);
12266 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12267 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12268 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12270 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12273 for (i = 0; i < spec->num_mixers; i++) {
12274 if (spec->mixers[i] == alc268_beep_mixer) {
12281 err = snd_hda_attach_beep_device(codec, 0x1);
12286 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12287 /* override the amp caps for beep generator */
12288 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12289 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12290 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12291 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12292 (0 << AC_AMPCAP_MUTE_SHIFT));
12295 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12296 /* check whether NID 0x07 is valid */
12297 unsigned int wcap = get_wcaps(codec, 0x07);
12301 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12302 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12303 spec->adc_nids = alc268_adc_nids_alt;
12304 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12305 add_mixer(spec, alc268_capture_alt_mixer);
12307 spec->adc_nids = alc268_adc_nids;
12308 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12309 add_mixer(spec, alc268_capture_mixer);
12311 spec->capsrc_nids = alc268_capsrc_nids;
12312 /* set default input source */
12313 for (i = 0; i < spec->num_adc_nids; i++)
12314 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12315 0, AC_VERB_SET_CONNECT_SEL,
12316 spec->input_mux->items[0].index);
12319 spec->vmaster_nid = 0x02;
12321 codec->patch_ops = alc_patch_ops;
12322 if (board_config == ALC268_AUTO)
12323 spec->init_hook = alc268_auto_init;
12325 codec->proc_widget_hook = print_realtek_coef;
12331 * ALC269 channel source setting (2 channel)
12333 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12335 #define alc269_dac_nids alc260_dac_nids
12337 static hda_nid_t alc269_adc_nids[1] = {
12342 static hda_nid_t alc269_capsrc_nids[1] = {
12346 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12350 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12358 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12366 #define alc269_modes alc260_modes
12367 #define alc269_capture_source alc880_lg_lw_capture_source
12369 static struct snd_kcontrol_new alc269_base_mixer[] = {
12370 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12371 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12372 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12373 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
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("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12378 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12379 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12380 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12381 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12385 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12386 /* output mixer control */
12387 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12390 .name = "Master Playback Switch",
12391 .info = snd_hda_mixer_amp_switch_info,
12392 .get = snd_hda_mixer_amp_switch_get,
12393 .put = alc268_acer_master_sw_put,
12394 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12396 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12397 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12398 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12399 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12400 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12401 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12405 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12406 /* output mixer control */
12407 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12409 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12410 .name = "Master Playback Switch",
12411 .info = snd_hda_mixer_amp_switch_info,
12412 .get = snd_hda_mixer_amp_switch_get,
12413 .put = alc268_acer_master_sw_put,
12414 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12418 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12419 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12420 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12421 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12422 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12423 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12424 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12428 /* bind volumes of both NID 0x0c and 0x0d */
12429 static struct hda_bind_ctls alc269_epc_bind_vol = {
12430 .ops = &snd_hda_bind_vol,
12432 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12433 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12438 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12439 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12440 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12441 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12445 /* capture mixer elements */
12446 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12447 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12448 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12449 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12454 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12455 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12456 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12457 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12461 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12462 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12463 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12464 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12467 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12471 static struct hda_verb alc269_lifebook_verbs[] = {
12472 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12473 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12474 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12476 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12477 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12478 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12479 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12480 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12481 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12485 /* toggle speaker-output according to the hp-jack state */
12486 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12488 unsigned int present;
12489 unsigned char bits;
12491 present = snd_hda_codec_read(codec, 0x15, 0,
12492 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12493 bits = present ? AMP_IN_MUTE(0) : 0;
12494 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12495 AMP_IN_MUTE(0), bits);
12496 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12497 AMP_IN_MUTE(0), bits);
12499 snd_hda_codec_write(codec, 0x20, 0,
12500 AC_VERB_SET_COEF_INDEX, 0x0c);
12501 snd_hda_codec_write(codec, 0x20, 0,
12502 AC_VERB_SET_PROC_COEF, 0x680);
12504 snd_hda_codec_write(codec, 0x20, 0,
12505 AC_VERB_SET_COEF_INDEX, 0x0c);
12506 snd_hda_codec_write(codec, 0x20, 0,
12507 AC_VERB_SET_PROC_COEF, 0x480);
12510 /* toggle speaker-output according to the hp-jacks state */
12511 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12513 unsigned int present;
12514 unsigned char bits;
12516 /* Check laptop headphone socket */
12517 present = snd_hda_codec_read(codec, 0x15, 0,
12518 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12520 /* Check port replicator headphone socket */
12521 present |= snd_hda_codec_read(codec, 0x1a, 0,
12522 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12524 bits = present ? AMP_IN_MUTE(0) : 0;
12525 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12526 AMP_IN_MUTE(0), bits);
12527 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12528 AMP_IN_MUTE(0), bits);
12530 snd_hda_codec_write(codec, 0x20, 0,
12531 AC_VERB_SET_COEF_INDEX, 0x0c);
12532 snd_hda_codec_write(codec, 0x20, 0,
12533 AC_VERB_SET_PROC_COEF, 0x680);
12535 snd_hda_codec_write(codec, 0x20, 0,
12536 AC_VERB_SET_COEF_INDEX, 0x0c);
12537 snd_hda_codec_write(codec, 0x20, 0,
12538 AC_VERB_SET_PROC_COEF, 0x480);
12541 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12543 unsigned int present;
12545 present = snd_hda_codec_read(codec, 0x18, 0,
12546 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12547 snd_hda_codec_write(codec, 0x23, 0,
12548 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12551 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12553 unsigned int present_laptop;
12554 unsigned int present_dock;
12556 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12557 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12559 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12560 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12562 /* Laptop mic port overrides dock mic port, design decision */
12564 snd_hda_codec_write(codec, 0x23, 0,
12565 AC_VERB_SET_CONNECT_SEL, 0x3);
12566 if (present_laptop)
12567 snd_hda_codec_write(codec, 0x23, 0,
12568 AC_VERB_SET_CONNECT_SEL, 0x0);
12569 if (!present_dock && !present_laptop)
12570 snd_hda_codec_write(codec, 0x23, 0,
12571 AC_VERB_SET_CONNECT_SEL, 0x1);
12574 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12577 if ((res >> 26) == ALC880_HP_EVENT)
12578 alc269_quanta_fl1_speaker_automute(codec);
12579 if ((res >> 26) == ALC880_MIC_EVENT)
12580 alc269_quanta_fl1_mic_automute(codec);
12583 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12586 if ((res >> 26) == ALC880_HP_EVENT)
12587 alc269_lifebook_speaker_automute(codec);
12588 if ((res >> 26) == ALC880_MIC_EVENT)
12589 alc269_lifebook_mic_autoswitch(codec);
12592 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12594 alc269_quanta_fl1_speaker_automute(codec);
12595 alc269_quanta_fl1_mic_automute(codec);
12598 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12600 alc269_lifebook_speaker_automute(codec);
12601 alc269_lifebook_mic_autoswitch(codec);
12604 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12605 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12606 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12607 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12608 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12609 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12610 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12611 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12615 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12616 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12617 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12618 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12619 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12620 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12621 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12625 /* toggle speaker-output according to the hp-jack state */
12626 static void alc269_speaker_automute(struct hda_codec *codec)
12628 unsigned int present;
12629 unsigned char bits;
12631 present = snd_hda_codec_read(codec, 0x15, 0,
12632 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12633 bits = present ? AMP_IN_MUTE(0) : 0;
12634 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12635 AMP_IN_MUTE(0), bits);
12636 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12637 AMP_IN_MUTE(0), bits);
12640 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12642 unsigned int present;
12644 present = snd_hda_codec_read(codec, 0x18, 0,
12645 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12646 snd_hda_codec_write(codec, 0x23, 0,
12647 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12650 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12652 unsigned int present;
12654 present = snd_hda_codec_read(codec, 0x18, 0,
12655 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12656 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12657 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12658 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12659 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12662 /* unsolicited event for HP jack sensing */
12663 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12666 if ((res >> 26) == ALC880_HP_EVENT)
12667 alc269_speaker_automute(codec);
12669 if ((res >> 26) == ALC880_MIC_EVENT)
12670 alc269_eeepc_dmic_automute(codec);
12673 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12675 alc269_speaker_automute(codec);
12676 alc269_eeepc_dmic_automute(codec);
12679 /* unsolicited event for HP jack sensing */
12680 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12683 if ((res >> 26) == ALC880_HP_EVENT)
12684 alc269_speaker_automute(codec);
12686 if ((res >> 26) == ALC880_MIC_EVENT)
12687 alc269_eeepc_amic_automute(codec);
12690 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12692 alc269_speaker_automute(codec);
12693 alc269_eeepc_amic_automute(codec);
12697 * generic initialization of ADC, input mixers and output mixers
12699 static struct hda_verb alc269_init_verbs[] = {
12701 * Unmute ADC0 and set the default input to mic-in
12703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12705 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12706 * analog-loopback mixer widget
12707 * Note: PASD motherboards uses the Line In 2 as the input for
12708 * front panel mic (mic 2)
12710 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12713 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12714 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12718 * Set up output mixers (0x0c - 0x0e)
12720 /* set vol=0 to output mixers */
12721 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12722 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12724 /* set up input amps for analog loopback */
12725 /* Amp Indices: DAC = 0, mixer = 1 */
12726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12728 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12730 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12731 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12733 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12735 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12736 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12737 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12738 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12739 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12743 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12744 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12746 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12747 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12749 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12750 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12752 /* FIXME: use matrix-type input source selection */
12753 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12754 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12756 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12757 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12761 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12762 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12766 /* add playback controls from the parsed DAC table */
12767 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12768 const struct auto_pin_cfg *cfg)
12773 spec->multiout.num_dacs = 1; /* only use one dac */
12774 spec->multiout.dac_nids = spec->private_dac_nids;
12775 spec->multiout.dac_nids[0] = 2;
12777 nid = cfg->line_out_pins[0];
12779 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12780 "Front Playback Volume",
12781 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12784 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12785 "Front Playback Switch",
12786 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12791 nid = cfg->speaker_pins[0];
12793 if (!cfg->line_out_pins[0]) {
12794 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12795 "Speaker Playback Volume",
12796 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12802 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12803 "Speaker Playback Switch",
12804 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12809 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12810 "Speaker Playback Switch",
12811 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12817 nid = cfg->hp_pins[0];
12819 /* spec->multiout.hp_nid = 2; */
12820 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12821 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12822 "Headphone Playback Volume",
12823 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12829 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12830 "Headphone Playback Switch",
12831 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12836 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12837 "Headphone Playback Switch",
12838 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12847 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12848 const struct auto_pin_cfg *cfg)
12852 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12855 /* digital-mic input pin is excluded in alc880_auto_create..()
12856 * because it's under 0x18
12858 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12859 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12860 struct hda_input_mux *imux = &spec->private_imux[0];
12861 imux->items[imux->num_items].label = "Int Mic";
12862 imux->items[imux->num_items].index = 0x05;
12868 #ifdef CONFIG_SND_HDA_POWER_SAVE
12869 #define alc269_loopbacks alc880_loopbacks
12872 /* pcm configuration: identiacal with ALC880 */
12873 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12874 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12875 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12876 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12878 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12882 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12883 /* NID is set in alc_build_pcms */
12885 .open = alc880_playback_pcm_open,
12886 .prepare = alc880_playback_pcm_prepare,
12887 .cleanup = alc880_playback_pcm_cleanup
12891 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12895 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12896 /* NID is set in alc_build_pcms */
12900 * BIOS auto configuration
12902 static int alc269_parse_auto_config(struct hda_codec *codec)
12904 struct alc_spec *spec = codec->spec;
12906 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12908 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12913 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12916 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12920 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12922 if (spec->autocfg.dig_outs)
12923 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12925 if (spec->kctls.list)
12926 add_mixer(spec, spec->kctls.list);
12928 add_verb(spec, alc269_init_verbs);
12929 spec->num_mux_defs = 1;
12930 spec->input_mux = &spec->private_imux[0];
12931 /* set default input source */
12932 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12933 0, AC_VERB_SET_CONNECT_SEL,
12934 spec->input_mux->items[0].index);
12936 err = alc_auto_add_mic_boost(codec);
12940 if (!spec->cap_mixer && !spec->no_analog)
12941 set_capture_mixer(spec);
12946 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12947 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12948 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12951 /* init callback for auto-configuration model -- overriding the default init */
12952 static void alc269_auto_init(struct hda_codec *codec)
12954 struct alc_spec *spec = codec->spec;
12955 alc269_auto_init_multi_out(codec);
12956 alc269_auto_init_hp_out(codec);
12957 alc269_auto_init_analog_input(codec);
12958 if (spec->unsol_event)
12959 alc_inithook(codec);
12963 * configuration and preset
12965 static const char *alc269_models[ALC269_MODEL_LAST] = {
12966 [ALC269_BASIC] = "basic",
12967 [ALC269_QUANTA_FL1] = "quanta",
12968 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12969 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12970 [ALC269_FUJITSU] = "fujitsu",
12971 [ALC269_LIFEBOOK] = "lifebook"
12974 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12975 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12976 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12977 ALC269_ASUS_EEEPC_P703),
12978 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12979 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12980 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12981 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12982 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12983 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12984 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12985 ALC269_ASUS_EEEPC_P901),
12986 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12987 ALC269_ASUS_EEEPC_P901),
12988 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12989 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12990 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12994 static struct alc_config_preset alc269_presets[] = {
12996 .mixers = { alc269_base_mixer },
12997 .init_verbs = { alc269_init_verbs },
12998 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12999 .dac_nids = alc269_dac_nids,
13001 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13002 .channel_mode = alc269_modes,
13003 .input_mux = &alc269_capture_source,
13005 [ALC269_QUANTA_FL1] = {
13006 .mixers = { alc269_quanta_fl1_mixer },
13007 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13008 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13009 .dac_nids = alc269_dac_nids,
13011 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13012 .channel_mode = alc269_modes,
13013 .input_mux = &alc269_capture_source,
13014 .unsol_event = alc269_quanta_fl1_unsol_event,
13015 .init_hook = alc269_quanta_fl1_init_hook,
13017 [ALC269_ASUS_EEEPC_P703] = {
13018 .mixers = { alc269_eeepc_mixer },
13019 .cap_mixer = alc269_epc_capture_mixer,
13020 .init_verbs = { alc269_init_verbs,
13021 alc269_eeepc_amic_init_verbs },
13022 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13023 .dac_nids = alc269_dac_nids,
13025 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13026 .channel_mode = alc269_modes,
13027 .input_mux = &alc269_eeepc_amic_capture_source,
13028 .unsol_event = alc269_eeepc_amic_unsol_event,
13029 .init_hook = alc269_eeepc_amic_inithook,
13031 [ALC269_ASUS_EEEPC_P901] = {
13032 .mixers = { alc269_eeepc_mixer },
13033 .cap_mixer = alc269_epc_capture_mixer,
13034 .init_verbs = { alc269_init_verbs,
13035 alc269_eeepc_dmic_init_verbs },
13036 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13037 .dac_nids = alc269_dac_nids,
13039 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13040 .channel_mode = alc269_modes,
13041 .input_mux = &alc269_eeepc_dmic_capture_source,
13042 .unsol_event = alc269_eeepc_dmic_unsol_event,
13043 .init_hook = alc269_eeepc_dmic_inithook,
13045 [ALC269_FUJITSU] = {
13046 .mixers = { alc269_fujitsu_mixer },
13047 .cap_mixer = alc269_epc_capture_mixer,
13048 .init_verbs = { alc269_init_verbs,
13049 alc269_eeepc_dmic_init_verbs },
13050 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13051 .dac_nids = alc269_dac_nids,
13053 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13054 .channel_mode = alc269_modes,
13055 .input_mux = &alc269_eeepc_dmic_capture_source,
13056 .unsol_event = alc269_eeepc_dmic_unsol_event,
13057 .init_hook = alc269_eeepc_dmic_inithook,
13059 [ALC269_LIFEBOOK] = {
13060 .mixers = { alc269_lifebook_mixer },
13061 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13062 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13063 .dac_nids = alc269_dac_nids,
13065 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13066 .channel_mode = alc269_modes,
13067 .input_mux = &alc269_capture_source,
13068 .unsol_event = alc269_lifebook_unsol_event,
13069 .init_hook = alc269_lifebook_init_hook,
13073 static int patch_alc269(struct hda_codec *codec)
13075 struct alc_spec *spec;
13079 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13083 codec->spec = spec;
13085 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13087 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13091 if (board_config < 0) {
13092 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13093 "trying auto-probe from BIOS...\n", codec->chip_name);
13094 board_config = ALC269_AUTO;
13097 if (board_config == ALC269_AUTO) {
13098 /* automatic parse from the BIOS config */
13099 err = alc269_parse_auto_config(codec);
13105 "hda_codec: Cannot set up configuration "
13106 "from BIOS. Using base mode...\n");
13107 board_config = ALC269_BASIC;
13111 err = snd_hda_attach_beep_device(codec, 0x1);
13117 if (board_config != ALC269_AUTO)
13118 setup_preset(spec, &alc269_presets[board_config]);
13120 if (codec->subsystem_id == 0x17aa3bf8) {
13121 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13122 * fix the sample rate of analog I/O to 44.1kHz
13124 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13125 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13127 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13128 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13130 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13131 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13133 spec->adc_nids = alc269_adc_nids;
13134 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13135 spec->capsrc_nids = alc269_capsrc_nids;
13136 if (!spec->cap_mixer)
13137 set_capture_mixer(spec);
13138 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13140 codec->patch_ops = alc_patch_ops;
13141 if (board_config == ALC269_AUTO)
13142 spec->init_hook = alc269_auto_init;
13143 #ifdef CONFIG_SND_HDA_POWER_SAVE
13144 if (!spec->loopback.amplist)
13145 spec->loopback.amplist = alc269_loopbacks;
13147 codec->proc_widget_hook = print_realtek_coef;
13153 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13157 * set the path ways for 2 channel output
13158 * need to set the codec line out and mic 1 pin widgets to inputs
13160 static struct hda_verb alc861_threestack_ch2_init[] = {
13161 /* set pin widget 1Ah (line in) for input */
13162 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13163 /* set pin widget 18h (mic1/2) for input, for mic also enable
13166 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13168 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13170 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13171 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13177 * need to set the codec line out and mic 1 pin widgets to outputs
13179 static struct hda_verb alc861_threestack_ch6_init[] = {
13180 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13181 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13182 /* set pin widget 18h (mic1) for output (CLFE)*/
13183 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13185 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13186 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13188 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13190 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13191 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13196 static struct hda_channel_mode alc861_threestack_modes[2] = {
13197 { 2, alc861_threestack_ch2_init },
13198 { 6, alc861_threestack_ch6_init },
13200 /* Set mic1 as input and unmute the mixer */
13201 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13202 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13203 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13206 /* Set mic1 as output and mute mixer */
13207 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13208 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13209 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13213 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13214 { 2, alc861_uniwill_m31_ch2_init },
13215 { 4, alc861_uniwill_m31_ch4_init },
13218 /* Set mic1 and line-in as input and unmute the mixer */
13219 static struct hda_verb alc861_asus_ch2_init[] = {
13220 /* set pin widget 1Ah (line in) for input */
13221 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13222 /* set pin widget 18h (mic1/2) for input, for mic also enable
13225 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13227 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13229 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13230 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13234 /* Set mic1 nad line-in as output and mute mixer */
13235 static struct hda_verb alc861_asus_ch6_init[] = {
13236 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13237 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13238 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13239 /* set pin widget 18h (mic1) for output (CLFE)*/
13240 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13241 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13242 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13243 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13245 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13247 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13248 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13253 static struct hda_channel_mode alc861_asus_modes[2] = {
13254 { 2, alc861_asus_ch2_init },
13255 { 6, alc861_asus_ch6_init },
13260 static struct snd_kcontrol_new alc861_base_mixer[] = {
13261 /* output mixer control */
13262 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13263 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13264 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13265 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13266 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13268 /*Input mixer control */
13269 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13270 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13271 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13272 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13273 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13274 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13276 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13277 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13278 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13283 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13284 /* output mixer control */
13285 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13286 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13287 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13288 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13289 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13291 /* Input mixer control */
13292 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13293 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13294 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13295 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13296 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13297 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13299 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13300 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13304 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13305 .name = "Channel Mode",
13306 .info = alc_ch_mode_info,
13307 .get = alc_ch_mode_get,
13308 .put = alc_ch_mode_put,
13309 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13314 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13315 /* output mixer control */
13316 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13317 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13318 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13323 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13324 /* output mixer control */
13325 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13326 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13327 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13328 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13329 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13331 /* Input mixer control */
13332 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13333 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13334 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13335 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13336 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13337 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13338 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13339 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13340 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13341 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13345 .name = "Channel Mode",
13346 .info = alc_ch_mode_info,
13347 .get = alc_ch_mode_get,
13348 .put = alc_ch_mode_put,
13349 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13354 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13355 /* output mixer control */
13356 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13357 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13358 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13359 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13360 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13362 /* Input mixer control */
13363 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13364 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13365 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13366 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13367 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13368 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13369 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13370 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13371 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13372 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13375 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13376 .name = "Channel Mode",
13377 .info = alc_ch_mode_info,
13378 .get = alc_ch_mode_get,
13379 .put = alc_ch_mode_put,
13380 .private_value = ARRAY_SIZE(alc861_asus_modes),
13385 /* additional mixer */
13386 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13387 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13388 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13393 * generic initialization of ADC, input mixers and output mixers
13395 static struct hda_verb alc861_base_init_verbs[] = {
13397 * Unmute ADC0 and set the default input to mic-in
13399 /* port-A for surround (rear panel) */
13400 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13401 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13402 /* port-B for mic-in (rear panel) with vref */
13403 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13404 /* port-C for line-in (rear panel) */
13405 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13406 /* port-D for Front */
13407 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13408 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13409 /* port-E for HP out (front panel) */
13410 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13411 /* route front PCM to HP */
13412 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13413 /* port-F for mic-in (front panel) with vref */
13414 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13415 /* port-G for CLFE (rear panel) */
13416 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13417 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13418 /* port-H for side (rear panel) */
13419 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13420 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13422 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13423 /* route front mic to ADC1*/
13424 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13425 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13427 /* Unmute DAC0~3 & spdif out*/
13428 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13429 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13430 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13431 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13434 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13435 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13436 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13437 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13438 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13440 /* Unmute Stereo Mixer 15 */
13441 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13442 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13443 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13446 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13447 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13448 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13449 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13450 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13452 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13453 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13454 /* hp used DAC 3 (Front) */
13455 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13456 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13461 static struct hda_verb alc861_threestack_init_verbs[] = {
13463 * Unmute ADC0 and set the default input to mic-in
13465 /* port-A for surround (rear panel) */
13466 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13467 /* port-B for mic-in (rear panel) with vref */
13468 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13469 /* port-C for line-in (rear panel) */
13470 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13471 /* port-D for Front */
13472 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13473 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13474 /* port-E for HP out (front panel) */
13475 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13476 /* route front PCM to HP */
13477 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13478 /* port-F for mic-in (front panel) with vref */
13479 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13480 /* port-G for CLFE (rear panel) */
13481 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13482 /* port-H for side (rear panel) */
13483 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13485 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13486 /* route front mic to ADC1*/
13487 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13488 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489 /* Unmute DAC0~3 & spdif out*/
13490 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13491 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13492 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13493 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13494 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13496 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13497 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13498 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13499 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13500 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13502 /* Unmute Stereo Mixer 15 */
13503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13504 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13505 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13506 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13508 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13509 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13510 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13511 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13512 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13514 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13516 /* hp used DAC 3 (Front) */
13517 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13522 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13524 * Unmute ADC0 and set the default input to mic-in
13526 /* port-A for surround (rear panel) */
13527 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13528 /* port-B for mic-in (rear panel) with vref */
13529 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13530 /* port-C for line-in (rear panel) */
13531 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13532 /* port-D for Front */
13533 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13534 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13535 /* port-E for HP out (front panel) */
13536 /* this has to be set to VREF80 */
13537 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13538 /* route front PCM to HP */
13539 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13540 /* port-F for mic-in (front panel) with vref */
13541 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13542 /* port-G for CLFE (rear panel) */
13543 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13544 /* port-H for side (rear panel) */
13545 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13547 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13548 /* route front mic to ADC1*/
13549 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13550 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13551 /* Unmute DAC0~3 & spdif out*/
13552 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13553 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13554 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13555 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13556 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13558 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13559 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13560 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13561 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13562 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13564 /* Unmute Stereo Mixer 15 */
13565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13567 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13568 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13570 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13571 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13572 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13573 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13574 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13575 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13576 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13577 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13578 /* hp used DAC 3 (Front) */
13579 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13580 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13584 static struct hda_verb alc861_asus_init_verbs[] = {
13586 * Unmute ADC0 and set the default input to mic-in
13588 /* port-A for surround (rear panel)
13589 * according to codec#0 this is the HP jack
13591 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13592 /* route front PCM to HP */
13593 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13594 /* port-B for mic-in (rear panel) with vref */
13595 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13596 /* port-C for line-in (rear panel) */
13597 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13598 /* port-D for Front */
13599 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13600 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13601 /* port-E for HP out (front panel) */
13602 /* this has to be set to VREF80 */
13603 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13604 /* route front PCM to HP */
13605 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13606 /* port-F for mic-in (front panel) with vref */
13607 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13608 /* port-G for CLFE (rear panel) */
13609 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13610 /* port-H for side (rear panel) */
13611 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13613 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13614 /* route front mic to ADC1*/
13615 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13617 /* Unmute DAC0~3 & spdif out*/
13618 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13619 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13620 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13621 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13623 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13624 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13625 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13626 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13627 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13629 /* Unmute Stereo Mixer 15 */
13630 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13635 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13637 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13638 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13639 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13640 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13641 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13642 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13643 /* hp used DAC 3 (Front) */
13644 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13649 /* additional init verbs for ASUS laptops */
13650 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13651 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13652 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13657 * generic initialization of ADC, input mixers and output mixers
13659 static struct hda_verb alc861_auto_init_verbs[] = {
13661 * Unmute ADC0 and set the default input to mic-in
13663 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13664 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13666 /* Unmute DAC0~3 & spdif out*/
13667 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13668 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13669 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13670 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13673 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13674 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13675 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13676 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13677 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13679 /* Unmute Stereo Mixer 15 */
13680 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13682 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13685 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13686 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13687 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13688 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13689 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13691 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13692 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13695 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13698 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13699 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13700 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13701 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13703 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13708 static struct hda_verb alc861_toshiba_init_verbs[] = {
13709 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13714 /* toggle speaker-output according to the hp-jack state */
13715 static void alc861_toshiba_automute(struct hda_codec *codec)
13717 unsigned int present;
13719 present = snd_hda_codec_read(codec, 0x0f, 0,
13720 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13721 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13722 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13723 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13724 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13727 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13730 if ((res >> 26) == ALC880_HP_EVENT)
13731 alc861_toshiba_automute(codec);
13734 /* pcm configuration: identiacal with ALC880 */
13735 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13736 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13737 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13738 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13741 #define ALC861_DIGOUT_NID 0x07
13743 static struct hda_channel_mode alc861_8ch_modes[1] = {
13747 static hda_nid_t alc861_dac_nids[4] = {
13748 /* front, surround, clfe, side */
13749 0x03, 0x06, 0x05, 0x04
13752 static hda_nid_t alc660_dac_nids[3] = {
13753 /* front, clfe, surround */
13757 static hda_nid_t alc861_adc_nids[1] = {
13762 static struct hda_input_mux alc861_capture_source = {
13766 { "Front Mic", 0x3 },
13773 /* fill in the dac_nids table from the parsed pin configuration */
13774 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13775 const struct auto_pin_cfg *cfg)
13780 spec->multiout.dac_nids = spec->private_dac_nids;
13781 for (i = 0; i < cfg->line_outs; i++) {
13782 nid = cfg->line_out_pins[i];
13784 if (i >= ARRAY_SIZE(alc861_dac_nids))
13786 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13789 spec->multiout.num_dacs = cfg->line_outs;
13793 /* add playback controls from the parsed DAC table */
13794 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13795 const struct auto_pin_cfg *cfg)
13798 static const char *chname[4] = {
13799 "Front", "Surround", NULL /*CLFE*/, "Side"
13804 for (i = 0; i < cfg->line_outs; i++) {
13805 nid = spec->multiout.dac_nids[i];
13810 err = add_control(spec, ALC_CTL_BIND_MUTE,
13811 "Center Playback Switch",
13812 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13816 err = add_control(spec, ALC_CTL_BIND_MUTE,
13817 "LFE Playback Switch",
13818 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13823 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13825 if (nid == alc861_dac_nids[idx])
13827 sprintf(name, "%s Playback Switch", chname[idx]);
13828 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13829 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13838 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13846 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13848 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13849 "Headphone Playback Switch",
13850 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13853 spec->multiout.hp_nid = nid;
13858 /* create playback/capture controls for input pins */
13859 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13860 const struct auto_pin_cfg *cfg)
13862 struct hda_input_mux *imux = &spec->private_imux[0];
13863 int i, err, idx, idx1;
13865 for (i = 0; i < AUTO_PIN_LAST; i++) {
13866 switch (cfg->input_pins[i]) {
13869 idx = 2; /* Line In */
13873 idx = 2; /* Line In */
13877 idx = 1; /* Mic In */
13881 idx = 1; /* Mic In */
13891 err = new_analog_input(spec, cfg->input_pins[i],
13892 auto_pin_cfg_labels[i], idx, 0x15);
13896 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13897 imux->items[imux->num_items].index = idx1;
13903 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13905 int pin_type, int dac_idx)
13907 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13909 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13913 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13915 struct alc_spec *spec = codec->spec;
13918 for (i = 0; i < spec->autocfg.line_outs; i++) {
13919 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13920 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13922 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13923 spec->multiout.dac_nids[i]);
13927 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13929 struct alc_spec *spec = codec->spec;
13932 pin = spec->autocfg.hp_pins[0];
13933 if (pin) /* connect to front */
13934 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13935 spec->multiout.dac_nids[0]);
13936 pin = spec->autocfg.speaker_pins[0];
13938 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13941 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13943 struct alc_spec *spec = codec->spec;
13946 for (i = 0; i < AUTO_PIN_LAST; i++) {
13947 hda_nid_t nid = spec->autocfg.input_pins[i];
13948 if (nid >= 0x0c && nid <= 0x11)
13949 alc_set_input_pin(codec, nid, i);
13953 /* parse the BIOS configuration and set up the alc_spec */
13954 /* return 1 if successful, 0 if the proper config is not found,
13955 * or a negative error code
13957 static int alc861_parse_auto_config(struct hda_codec *codec)
13959 struct alc_spec *spec = codec->spec;
13961 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13963 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13967 if (!spec->autocfg.line_outs)
13968 return 0; /* can't find valid BIOS pin config */
13970 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13973 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13976 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13979 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13983 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13985 if (spec->autocfg.dig_outs)
13986 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13988 if (spec->kctls.list)
13989 add_mixer(spec, spec->kctls.list);
13991 add_verb(spec, alc861_auto_init_verbs);
13993 spec->num_mux_defs = 1;
13994 spec->input_mux = &spec->private_imux[0];
13996 spec->adc_nids = alc861_adc_nids;
13997 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13998 set_capture_mixer(spec);
14000 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14005 /* additional initialization for auto-configuration model */
14006 static void alc861_auto_init(struct hda_codec *codec)
14008 struct alc_spec *spec = codec->spec;
14009 alc861_auto_init_multi_out(codec);
14010 alc861_auto_init_hp_out(codec);
14011 alc861_auto_init_analog_input(codec);
14012 if (spec->unsol_event)
14013 alc_inithook(codec);
14016 #ifdef CONFIG_SND_HDA_POWER_SAVE
14017 static struct hda_amp_list alc861_loopbacks[] = {
14018 { 0x15, HDA_INPUT, 0 },
14019 { 0x15, HDA_INPUT, 1 },
14020 { 0x15, HDA_INPUT, 2 },
14021 { 0x15, HDA_INPUT, 3 },
14028 * configuration and preset
14030 static const char *alc861_models[ALC861_MODEL_LAST] = {
14031 [ALC861_3ST] = "3stack",
14032 [ALC660_3ST] = "3stack-660",
14033 [ALC861_3ST_DIG] = "3stack-dig",
14034 [ALC861_6ST_DIG] = "6stack-dig",
14035 [ALC861_UNIWILL_M31] = "uniwill-m31",
14036 [ALC861_TOSHIBA] = "toshiba",
14037 [ALC861_ASUS] = "asus",
14038 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14039 [ALC861_AUTO] = "auto",
14042 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14043 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14044 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14045 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14046 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14047 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14048 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14049 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14050 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14051 * Any other models that need this preset?
14053 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14054 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14055 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14056 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14057 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14058 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14059 /* FIXME: the below seems conflict */
14060 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14061 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14062 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14066 static struct alc_config_preset alc861_presets[] = {
14068 .mixers = { alc861_3ST_mixer },
14069 .init_verbs = { alc861_threestack_init_verbs },
14070 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14071 .dac_nids = alc861_dac_nids,
14072 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14073 .channel_mode = alc861_threestack_modes,
14075 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14076 .adc_nids = alc861_adc_nids,
14077 .input_mux = &alc861_capture_source,
14079 [ALC861_3ST_DIG] = {
14080 .mixers = { alc861_base_mixer },
14081 .init_verbs = { alc861_threestack_init_verbs },
14082 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14083 .dac_nids = alc861_dac_nids,
14084 .dig_out_nid = ALC861_DIGOUT_NID,
14085 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14086 .channel_mode = alc861_threestack_modes,
14088 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14089 .adc_nids = alc861_adc_nids,
14090 .input_mux = &alc861_capture_source,
14092 [ALC861_6ST_DIG] = {
14093 .mixers = { alc861_base_mixer },
14094 .init_verbs = { alc861_base_init_verbs },
14095 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14096 .dac_nids = alc861_dac_nids,
14097 .dig_out_nid = ALC861_DIGOUT_NID,
14098 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14099 .channel_mode = alc861_8ch_modes,
14100 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14101 .adc_nids = alc861_adc_nids,
14102 .input_mux = &alc861_capture_source,
14105 .mixers = { alc861_3ST_mixer },
14106 .init_verbs = { alc861_threestack_init_verbs },
14107 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14108 .dac_nids = alc660_dac_nids,
14109 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14110 .channel_mode = alc861_threestack_modes,
14112 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14113 .adc_nids = alc861_adc_nids,
14114 .input_mux = &alc861_capture_source,
14116 [ALC861_UNIWILL_M31] = {
14117 .mixers = { alc861_uniwill_m31_mixer },
14118 .init_verbs = { alc861_uniwill_m31_init_verbs },
14119 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14120 .dac_nids = alc861_dac_nids,
14121 .dig_out_nid = ALC861_DIGOUT_NID,
14122 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14123 .channel_mode = alc861_uniwill_m31_modes,
14125 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14126 .adc_nids = alc861_adc_nids,
14127 .input_mux = &alc861_capture_source,
14129 [ALC861_TOSHIBA] = {
14130 .mixers = { alc861_toshiba_mixer },
14131 .init_verbs = { alc861_base_init_verbs,
14132 alc861_toshiba_init_verbs },
14133 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14134 .dac_nids = alc861_dac_nids,
14135 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14136 .channel_mode = alc883_3ST_2ch_modes,
14137 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14138 .adc_nids = alc861_adc_nids,
14139 .input_mux = &alc861_capture_source,
14140 .unsol_event = alc861_toshiba_unsol_event,
14141 .init_hook = alc861_toshiba_automute,
14144 .mixers = { alc861_asus_mixer },
14145 .init_verbs = { alc861_asus_init_verbs },
14146 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14147 .dac_nids = alc861_dac_nids,
14148 .dig_out_nid = ALC861_DIGOUT_NID,
14149 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14150 .channel_mode = alc861_asus_modes,
14153 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14154 .adc_nids = alc861_adc_nids,
14155 .input_mux = &alc861_capture_source,
14157 [ALC861_ASUS_LAPTOP] = {
14158 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14159 .init_verbs = { alc861_asus_init_verbs,
14160 alc861_asus_laptop_init_verbs },
14161 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14162 .dac_nids = alc861_dac_nids,
14163 .dig_out_nid = ALC861_DIGOUT_NID,
14164 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14165 .channel_mode = alc883_3ST_2ch_modes,
14167 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14168 .adc_nids = alc861_adc_nids,
14169 .input_mux = &alc861_capture_source,
14174 static int patch_alc861(struct hda_codec *codec)
14176 struct alc_spec *spec;
14180 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14184 codec->spec = spec;
14186 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14190 if (board_config < 0) {
14191 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14192 "trying auto-probe from BIOS...\n", codec->chip_name);
14193 board_config = ALC861_AUTO;
14196 if (board_config == ALC861_AUTO) {
14197 /* automatic parse from the BIOS config */
14198 err = alc861_parse_auto_config(codec);
14204 "hda_codec: Cannot set up configuration "
14205 "from BIOS. Using base mode...\n");
14206 board_config = ALC861_3ST_DIG;
14210 err = snd_hda_attach_beep_device(codec, 0x23);
14216 if (board_config != ALC861_AUTO)
14217 setup_preset(spec, &alc861_presets[board_config]);
14219 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14220 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14222 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14223 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14225 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14227 spec->vmaster_nid = 0x03;
14229 codec->patch_ops = alc_patch_ops;
14230 if (board_config == ALC861_AUTO)
14231 spec->init_hook = alc861_auto_init;
14232 #ifdef CONFIG_SND_HDA_POWER_SAVE
14233 if (!spec->loopback.amplist)
14234 spec->loopback.amplist = alc861_loopbacks;
14236 codec->proc_widget_hook = print_realtek_coef;
14242 * ALC861-VD support
14246 * In addition, an independent DAC
14248 #define ALC861VD_DIGOUT_NID 0x06
14250 static hda_nid_t alc861vd_dac_nids[4] = {
14251 /* front, surr, clfe, side surr */
14252 0x02, 0x03, 0x04, 0x05
14255 /* dac_nids for ALC660vd are in a different order - according to
14256 * Realtek's driver.
14257 * This should probably tesult in a different mixer for 6stack models
14258 * of ALC660vd codecs, but for now there is only 3stack mixer
14259 * - and it is the same as in 861vd.
14260 * adc_nids in ALC660vd are (is) the same as in 861vd
14262 static hda_nid_t alc660vd_dac_nids[3] = {
14263 /* front, rear, clfe, rear_surr */
14267 static hda_nid_t alc861vd_adc_nids[1] = {
14272 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14275 /* FIXME: should be a matrix-type input source selection */
14276 static struct hda_input_mux alc861vd_capture_source = {
14280 { "Front Mic", 0x1 },
14286 static struct hda_input_mux alc861vd_dallas_capture_source = {
14289 { "Ext Mic", 0x0 },
14290 { "Int Mic", 0x1 },
14294 static struct hda_input_mux alc861vd_hp_capture_source = {
14297 { "Front Mic", 0x0 },
14298 { "ATAPI Mic", 0x1 },
14305 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14312 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14313 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14314 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14315 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14316 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14323 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14324 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14325 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14326 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14331 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14332 { 6, alc861vd_6stack_ch6_init },
14333 { 8, alc861vd_6stack_ch8_init },
14336 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14339 .name = "Channel Mode",
14340 .info = alc_ch_mode_info,
14341 .get = alc_ch_mode_get,
14342 .put = alc_ch_mode_put,
14347 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14348 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14350 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14351 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14352 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14354 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14355 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14357 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14359 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14361 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14362 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14364 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14365 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14367 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14369 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14373 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14374 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14375 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14377 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14378 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14380 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14381 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14386 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14387 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14388 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14392 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14393 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14394 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14396 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14397 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14398 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14400 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14401 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14403 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14404 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14409 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14410 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14411 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14412 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14414 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14416 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14418 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14420 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14421 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14422 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14424 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14425 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14430 /* Pin assignment: Speaker=0x14, HP = 0x15,
14431 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14433 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14434 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14435 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14436 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14437 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14438 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14439 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14440 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14441 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14442 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14443 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14447 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14448 * Front Mic=0x18, ATAPI Mic = 0x19,
14450 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14451 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14452 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14454 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14455 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14456 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14457 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14458 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14464 * generic initialization of ADC, input mixers and output mixers
14466 static struct hda_verb alc861vd_volume_init_verbs[] = {
14468 * Unmute ADC0 and set the default input to mic-in
14470 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14471 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14473 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14474 * the analog-loopback mixer widget
14476 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14477 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14478 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14479 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14480 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14481 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14483 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14484 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14485 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14486 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14487 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14490 * Set up output mixers (0x02 - 0x05)
14492 /* set vol=0 to output mixers */
14493 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14494 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14495 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14496 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14498 /* set up input amps for analog loopback */
14499 /* Amp Indices: DAC = 0, mixer = 1 */
14500 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14502 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14503 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14504 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14506 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14513 * 3-stack pin configuration:
14514 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14516 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14518 * Set pin mode and muting
14520 /* set front pin widgets 0x14 for output */
14521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14523 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14525 /* Mic (rear) pin: input vref at 80% */
14526 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14528 /* Front Mic pin: input vref at 80% */
14529 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14530 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14531 /* Line In pin: input */
14532 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14533 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14534 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14535 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14536 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14537 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14538 /* CD pin widget for input */
14539 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14545 * 6-stack pin configuration:
14547 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14549 * Set pin mode and muting
14551 /* set front pin widgets 0x14 for output */
14552 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14554 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14556 /* Rear Pin: output 1 (0x0d) */
14557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14559 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14560 /* CLFE Pin: output 2 (0x0e) */
14561 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14562 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14563 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14564 /* Side Pin: output 3 (0x0f) */
14565 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14566 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14567 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14569 /* Mic (rear) pin: input vref at 80% */
14570 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14571 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14572 /* Front Mic pin: input vref at 80% */
14573 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14574 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14575 /* Line In pin: input */
14576 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14577 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14578 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14579 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14580 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14581 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14582 /* CD pin widget for input */
14583 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14588 static struct hda_verb alc861vd_eapd_verbs[] = {
14589 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14593 static struct hda_verb alc660vd_eapd_verbs[] = {
14594 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14595 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14599 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14600 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14603 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14604 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14608 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14610 unsigned int present;
14611 unsigned char bits;
14613 present = snd_hda_codec_read(codec, 0x18, 0,
14614 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14615 bits = present ? HDA_AMP_MUTE : 0;
14616 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14617 HDA_AMP_MUTE, bits);
14620 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14622 struct alc_spec *spec = codec->spec;
14624 spec->autocfg.hp_pins[0] = 0x1b;
14625 spec->autocfg.speaker_pins[0] = 0x14;
14626 alc_automute_amp(codec);
14627 alc861vd_lenovo_mic_automute(codec);
14630 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14633 switch (res >> 26) {
14634 case ALC880_MIC_EVENT:
14635 alc861vd_lenovo_mic_automute(codec);
14638 alc_automute_amp_unsol_event(codec, res);
14643 static struct hda_verb alc861vd_dallas_verbs[] = {
14644 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14645 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14646 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14647 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14651 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14652 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14653 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14654 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14656 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14658 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14659 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14662 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14663 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14664 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14665 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14667 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14668 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14669 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14671 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14673 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14674 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14681 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14682 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14683 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14688 /* toggle speaker-output according to the hp-jack state */
14689 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14691 struct alc_spec *spec = codec->spec;
14693 spec->autocfg.hp_pins[0] = 0x15;
14694 spec->autocfg.speaker_pins[0] = 0x14;
14695 alc_automute_amp(codec);
14698 #ifdef CONFIG_SND_HDA_POWER_SAVE
14699 #define alc861vd_loopbacks alc880_loopbacks
14702 /* pcm configuration: identiacal with ALC880 */
14703 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14704 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14705 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14706 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14709 * configuration and preset
14711 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14712 [ALC660VD_3ST] = "3stack-660",
14713 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14714 [ALC660VD_ASUS_V1S] = "asus-v1s",
14715 [ALC861VD_3ST] = "3stack",
14716 [ALC861VD_3ST_DIG] = "3stack-digout",
14717 [ALC861VD_6ST_DIG] = "6stack-digout",
14718 [ALC861VD_LENOVO] = "lenovo",
14719 [ALC861VD_DALLAS] = "dallas",
14720 [ALC861VD_HP] = "hp",
14721 [ALC861VD_AUTO] = "auto",
14724 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14725 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14726 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14727 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14728 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14729 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14730 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14731 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14732 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14733 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14734 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14735 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14736 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14737 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14738 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14739 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14743 static struct alc_config_preset alc861vd_presets[] = {
14745 .mixers = { alc861vd_3st_mixer },
14746 .init_verbs = { alc861vd_volume_init_verbs,
14747 alc861vd_3stack_init_verbs },
14748 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14749 .dac_nids = alc660vd_dac_nids,
14750 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14751 .channel_mode = alc861vd_3stack_2ch_modes,
14752 .input_mux = &alc861vd_capture_source,
14754 [ALC660VD_3ST_DIG] = {
14755 .mixers = { alc861vd_3st_mixer },
14756 .init_verbs = { alc861vd_volume_init_verbs,
14757 alc861vd_3stack_init_verbs },
14758 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14759 .dac_nids = alc660vd_dac_nids,
14760 .dig_out_nid = ALC861VD_DIGOUT_NID,
14761 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14762 .channel_mode = alc861vd_3stack_2ch_modes,
14763 .input_mux = &alc861vd_capture_source,
14766 .mixers = { alc861vd_3st_mixer },
14767 .init_verbs = { alc861vd_volume_init_verbs,
14768 alc861vd_3stack_init_verbs },
14769 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14770 .dac_nids = alc861vd_dac_nids,
14771 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14772 .channel_mode = alc861vd_3stack_2ch_modes,
14773 .input_mux = &alc861vd_capture_source,
14775 [ALC861VD_3ST_DIG] = {
14776 .mixers = { alc861vd_3st_mixer },
14777 .init_verbs = { alc861vd_volume_init_verbs,
14778 alc861vd_3stack_init_verbs },
14779 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14780 .dac_nids = alc861vd_dac_nids,
14781 .dig_out_nid = ALC861VD_DIGOUT_NID,
14782 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14783 .channel_mode = alc861vd_3stack_2ch_modes,
14784 .input_mux = &alc861vd_capture_source,
14786 [ALC861VD_6ST_DIG] = {
14787 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14788 .init_verbs = { alc861vd_volume_init_verbs,
14789 alc861vd_6stack_init_verbs },
14790 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14791 .dac_nids = alc861vd_dac_nids,
14792 .dig_out_nid = ALC861VD_DIGOUT_NID,
14793 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14794 .channel_mode = alc861vd_6stack_modes,
14795 .input_mux = &alc861vd_capture_source,
14797 [ALC861VD_LENOVO] = {
14798 .mixers = { alc861vd_lenovo_mixer },
14799 .init_verbs = { alc861vd_volume_init_verbs,
14800 alc861vd_3stack_init_verbs,
14801 alc861vd_eapd_verbs,
14802 alc861vd_lenovo_unsol_verbs },
14803 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14804 .dac_nids = alc660vd_dac_nids,
14805 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14806 .channel_mode = alc861vd_3stack_2ch_modes,
14807 .input_mux = &alc861vd_capture_source,
14808 .unsol_event = alc861vd_lenovo_unsol_event,
14809 .init_hook = alc861vd_lenovo_init_hook,
14811 [ALC861VD_DALLAS] = {
14812 .mixers = { alc861vd_dallas_mixer },
14813 .init_verbs = { alc861vd_dallas_verbs },
14814 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14815 .dac_nids = alc861vd_dac_nids,
14816 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14817 .channel_mode = alc861vd_3stack_2ch_modes,
14818 .input_mux = &alc861vd_dallas_capture_source,
14819 .unsol_event = alc_automute_amp_unsol_event,
14820 .init_hook = alc861vd_dallas_init_hook,
14823 .mixers = { alc861vd_hp_mixer },
14824 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14825 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14826 .dac_nids = alc861vd_dac_nids,
14827 .dig_out_nid = ALC861VD_DIGOUT_NID,
14828 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14829 .channel_mode = alc861vd_3stack_2ch_modes,
14830 .input_mux = &alc861vd_hp_capture_source,
14831 .unsol_event = alc_automute_amp_unsol_event,
14832 .init_hook = alc861vd_dallas_init_hook,
14834 [ALC660VD_ASUS_V1S] = {
14835 .mixers = { alc861vd_lenovo_mixer },
14836 .init_verbs = { alc861vd_volume_init_verbs,
14837 alc861vd_3stack_init_verbs,
14838 alc861vd_eapd_verbs,
14839 alc861vd_lenovo_unsol_verbs },
14840 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14841 .dac_nids = alc660vd_dac_nids,
14842 .dig_out_nid = ALC861VD_DIGOUT_NID,
14843 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14844 .channel_mode = alc861vd_3stack_2ch_modes,
14845 .input_mux = &alc861vd_capture_source,
14846 .unsol_event = alc861vd_lenovo_unsol_event,
14847 .init_hook = alc861vd_lenovo_init_hook,
14852 * BIOS auto configuration
14854 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14855 hda_nid_t nid, int pin_type, int dac_idx)
14857 alc_set_pin_output(codec, nid, pin_type);
14860 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14862 struct alc_spec *spec = codec->spec;
14865 for (i = 0; i <= HDA_SIDE; i++) {
14866 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14867 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14869 alc861vd_auto_set_output_and_unmute(codec, nid,
14875 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14877 struct alc_spec *spec = codec->spec;
14880 pin = spec->autocfg.hp_pins[0];
14881 if (pin) /* connect to front and use dac 0 */
14882 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14883 pin = spec->autocfg.speaker_pins[0];
14885 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14888 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14889 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14891 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14893 struct alc_spec *spec = codec->spec;
14896 for (i = 0; i < AUTO_PIN_LAST; i++) {
14897 hda_nid_t nid = spec->autocfg.input_pins[i];
14898 if (alc861vd_is_input_pin(nid)) {
14899 alc_set_input_pin(codec, nid, i);
14900 if (nid != ALC861VD_PIN_CD_NID &&
14901 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14902 snd_hda_codec_write(codec, nid, 0,
14903 AC_VERB_SET_AMP_GAIN_MUTE,
14909 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14911 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14912 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14914 /* add playback controls from the parsed DAC table */
14915 /* Based on ALC880 version. But ALC861VD has separate,
14916 * different NIDs for mute/unmute switch and volume control */
14917 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14918 const struct auto_pin_cfg *cfg)
14921 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14922 hda_nid_t nid_v, nid_s;
14925 for (i = 0; i < cfg->line_outs; i++) {
14926 if (!spec->multiout.dac_nids[i])
14928 nid_v = alc861vd_idx_to_mixer_vol(
14930 spec->multiout.dac_nids[i]));
14931 nid_s = alc861vd_idx_to_mixer_switch(
14933 spec->multiout.dac_nids[i]));
14937 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14938 "Center Playback Volume",
14939 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14943 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14944 "LFE Playback Volume",
14945 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14949 err = add_control(spec, ALC_CTL_BIND_MUTE,
14950 "Center Playback Switch",
14951 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14955 err = add_control(spec, ALC_CTL_BIND_MUTE,
14956 "LFE Playback Switch",
14957 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14962 sprintf(name, "%s Playback Volume", chname[i]);
14963 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14964 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14968 sprintf(name, "%s Playback Switch", chname[i]);
14969 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14970 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14979 /* add playback controls for speaker and HP outputs */
14980 /* Based on ALC880 version. But ALC861VD has separate,
14981 * different NIDs for mute/unmute switch and volume control */
14982 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14983 hda_nid_t pin, const char *pfx)
14985 hda_nid_t nid_v, nid_s;
14992 if (alc880_is_fixed_pin(pin)) {
14993 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14994 /* specify the DAC as the extra output */
14995 if (!spec->multiout.hp_nid)
14996 spec->multiout.hp_nid = nid_v;
14998 spec->multiout.extra_out_nid[0] = nid_v;
14999 /* control HP volume/switch on the output mixer amp */
15000 nid_v = alc861vd_idx_to_mixer_vol(
15001 alc880_fixed_pin_idx(pin));
15002 nid_s = alc861vd_idx_to_mixer_switch(
15003 alc880_fixed_pin_idx(pin));
15005 sprintf(name, "%s Playback Volume", pfx);
15006 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15007 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15010 sprintf(name, "%s Playback Switch", pfx);
15011 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15012 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15015 } else if (alc880_is_multi_pin(pin)) {
15016 /* set manual connection */
15017 /* we have only a switch on HP-out PIN */
15018 sprintf(name, "%s Playback Switch", pfx);
15019 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15020 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15027 /* parse the BIOS configuration and set up the alc_spec
15028 * return 1 if successful, 0 if the proper config is not found,
15029 * or a negative error code
15030 * Based on ALC880 version - had to change it to override
15031 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15032 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15034 struct alc_spec *spec = codec->spec;
15036 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15038 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15042 if (!spec->autocfg.line_outs)
15043 return 0; /* can't find valid BIOS pin config */
15045 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15048 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15051 err = alc861vd_auto_create_extra_out(spec,
15052 spec->autocfg.speaker_pins[0],
15056 err = alc861vd_auto_create_extra_out(spec,
15057 spec->autocfg.hp_pins[0],
15061 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15065 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15067 if (spec->autocfg.dig_outs)
15068 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15070 if (spec->kctls.list)
15071 add_mixer(spec, spec->kctls.list);
15073 add_verb(spec, alc861vd_volume_init_verbs);
15075 spec->num_mux_defs = 1;
15076 spec->input_mux = &spec->private_imux[0];
15078 err = alc_auto_add_mic_boost(codec);
15082 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15087 /* additional initialization for auto-configuration model */
15088 static void alc861vd_auto_init(struct hda_codec *codec)
15090 struct alc_spec *spec = codec->spec;
15091 alc861vd_auto_init_multi_out(codec);
15092 alc861vd_auto_init_hp_out(codec);
15093 alc861vd_auto_init_analog_input(codec);
15094 alc861vd_auto_init_input_src(codec);
15095 if (spec->unsol_event)
15096 alc_inithook(codec);
15099 static int patch_alc861vd(struct hda_codec *codec)
15101 struct alc_spec *spec;
15102 int err, board_config;
15104 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15108 codec->spec = spec;
15110 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15114 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15115 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15116 "trying auto-probe from BIOS...\n", codec->chip_name);
15117 board_config = ALC861VD_AUTO;
15120 if (board_config == ALC861VD_AUTO) {
15121 /* automatic parse from the BIOS config */
15122 err = alc861vd_parse_auto_config(codec);
15128 "hda_codec: Cannot set up configuration "
15129 "from BIOS. Using base mode...\n");
15130 board_config = ALC861VD_3ST;
15134 err = snd_hda_attach_beep_device(codec, 0x23);
15140 if (board_config != ALC861VD_AUTO)
15141 setup_preset(spec, &alc861vd_presets[board_config]);
15143 if (codec->vendor_id == 0x10ec0660) {
15144 /* always turn on EAPD */
15145 add_verb(spec, alc660vd_eapd_verbs);
15148 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15149 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15151 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15152 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15154 spec->adc_nids = alc861vd_adc_nids;
15155 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15156 spec->capsrc_nids = alc861vd_capsrc_nids;
15157 spec->capture_style = CAPT_MIX;
15159 set_capture_mixer(spec);
15160 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15162 spec->vmaster_nid = 0x02;
15164 codec->patch_ops = alc_patch_ops;
15166 if (board_config == ALC861VD_AUTO)
15167 spec->init_hook = alc861vd_auto_init;
15168 #ifdef CONFIG_SND_HDA_POWER_SAVE
15169 if (!spec->loopback.amplist)
15170 spec->loopback.amplist = alc861vd_loopbacks;
15172 codec->proc_widget_hook = print_realtek_coef;
15180 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15181 * configuration. Each pin widget can choose any input DACs and a mixer.
15182 * Each ADC is connected from a mixer of all inputs. This makes possible
15183 * 6-channel independent captures.
15185 * In addition, an independent DAC for the multi-playback (not used in this
15188 #define ALC662_DIGOUT_NID 0x06
15189 #define ALC662_DIGIN_NID 0x0a
15191 static hda_nid_t alc662_dac_nids[4] = {
15192 /* front, rear, clfe, rear_surr */
15196 static hda_nid_t alc272_dac_nids[2] = {
15200 static hda_nid_t alc662_adc_nids[1] = {
15205 static hda_nid_t alc272_adc_nids[1] = {
15210 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15211 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15215 /* FIXME: should be a matrix-type input source selection */
15216 static struct hda_input_mux alc662_capture_source = {
15220 { "Front Mic", 0x1 },
15226 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15234 static struct hda_input_mux alc662_eeepc_capture_source = {
15242 static struct hda_input_mux alc663_capture_source = {
15246 { "Front Mic", 0x1 },
15251 static struct hda_input_mux alc663_m51va_capture_source = {
15254 { "Ext-Mic", 0x0 },
15259 #if 1 /* set to 0 for testing other input sources below */
15260 static struct hda_input_mux alc272_nc10_capture_source = {
15263 { "Autoselect Mic", 0x0 },
15264 { "Internal Mic", 0x1 },
15268 static struct hda_input_mux alc272_nc10_capture_source = {
15271 { "Autoselect Mic", 0x0 },
15272 { "Internal Mic", 0x1 },
15273 { "In-0x02", 0x2 },
15274 { "In-0x03", 0x3 },
15275 { "In-0x04", 0x4 },
15276 { "In-0x05", 0x5 },
15277 { "In-0x06", 0x6 },
15278 { "In-0x07", 0x7 },
15279 { "In-0x08", 0x8 },
15280 { "In-0x09", 0x9 },
15281 { "In-0x0a", 0x0a },
15282 { "In-0x0b", 0x0b },
15283 { "In-0x0c", 0x0c },
15284 { "In-0x0d", 0x0d },
15285 { "In-0x0e", 0x0e },
15286 { "In-0x0f", 0x0f },
15294 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15301 static struct hda_verb alc662_3ST_ch2_init[] = {
15302 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15303 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15304 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15305 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15312 static struct hda_verb alc662_3ST_ch6_init[] = {
15313 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15314 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15315 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15316 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15317 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15318 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15322 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15323 { 2, alc662_3ST_ch2_init },
15324 { 6, alc662_3ST_ch6_init },
15330 static struct hda_verb alc662_sixstack_ch6_init[] = {
15331 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15332 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15333 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15340 static struct hda_verb alc662_sixstack_ch8_init[] = {
15341 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15342 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15343 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15347 static struct hda_channel_mode alc662_5stack_modes[2] = {
15348 { 2, alc662_sixstack_ch6_init },
15349 { 6, alc662_sixstack_ch8_init },
15352 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15353 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15356 static struct snd_kcontrol_new alc662_base_mixer[] = {
15357 /* output mixer control */
15358 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15359 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15360 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15361 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15362 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15363 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15364 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15365 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15366 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15368 /*Input mixer control */
15369 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15370 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15371 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15372 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15373 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15374 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15375 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15376 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15380 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15381 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15382 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15383 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15384 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15385 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15386 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15387 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15389 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15390 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15391 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15395 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15396 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15397 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15398 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15399 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15400 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15401 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15402 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15403 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15404 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15405 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15406 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15407 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15408 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15409 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15410 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15411 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15412 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15416 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15417 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15418 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15419 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15420 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15421 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15422 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15423 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15429 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15430 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15431 ALC262_HIPPO_MASTER_SWITCH,
15433 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15434 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15435 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15437 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15438 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15439 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15443 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15444 ALC262_HIPPO_MASTER_SWITCH,
15445 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15448 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15449 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15450 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15451 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15452 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15453 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15457 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15458 .ops = &snd_hda_bind_vol,
15460 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15461 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15466 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15467 .ops = &snd_hda_bind_sw,
15469 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15470 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15475 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15476 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15477 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15478 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15479 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15483 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15484 .ops = &snd_hda_bind_sw,
15486 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15487 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15488 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15493 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15494 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15495 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15496 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15497 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15498 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15499 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15504 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15505 .ops = &snd_hda_bind_sw,
15507 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15508 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15509 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15514 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15515 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15516 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15519 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15520 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15524 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15525 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15526 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15527 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15528 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15529 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15530 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15531 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15535 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15536 .ops = &snd_hda_bind_vol,
15538 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15539 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15544 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15545 .ops = &snd_hda_bind_sw,
15547 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15548 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15553 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15554 HDA_BIND_VOL("Master Playback Volume",
15555 &alc663_asus_two_bind_master_vol),
15556 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15557 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15558 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),
15564 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15565 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15566 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15567 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15568 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15569 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15570 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15574 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15576 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15577 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15578 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15581 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15582 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15583 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15584 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15588 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15589 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15590 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15591 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15593 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15594 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15595 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15596 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15597 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15598 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15602 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15604 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15605 .name = "Channel Mode",
15606 .info = alc_ch_mode_info,
15607 .get = alc_ch_mode_get,
15608 .put = alc_ch_mode_put,
15613 static struct hda_verb alc662_init_verbs[] = {
15614 /* ADC: mute amp left and right */
15615 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15616 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15617 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15619 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15620 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15621 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15622 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15623 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15627 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15628 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15629 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15630 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15632 /* Front Pin: output 0 (0x0c) */
15633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15636 /* Rear Pin: output 1 (0x0d) */
15637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15640 /* CLFE Pin: output 2 (0x0e) */
15641 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15642 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15644 /* Mic (rear) pin: input vref at 80% */
15645 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15646 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15647 /* Front Mic pin: input vref at 80% */
15648 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15649 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15650 /* Line In pin: input */
15651 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15653 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15654 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15655 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15656 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15657 /* CD pin widget for input */
15658 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15660 /* FIXME: use matrix-type input source selection */
15661 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15664 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15666 /* always trun on EAPD */
15667 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15668 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15673 static struct hda_verb alc662_sue_init_verbs[] = {
15674 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15675 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15679 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15680 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15681 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15685 /* Set Unsolicited Event*/
15686 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15687 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15688 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15693 * generic initialization of ADC, input mixers and output mixers
15695 static struct hda_verb alc662_auto_init_verbs[] = {
15697 * Unmute ADC and set the default input to mic-in
15699 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15700 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15702 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15704 * Note: PASD motherboards uses the Line In 2 as the input for front
15705 * panel mic (mic 2)
15707 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15715 * Set up output mixers (0x0c - 0x0f)
15717 /* set vol=0 to output mixers */
15718 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15719 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15720 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15722 /* set up input amps for analog loopback */
15723 /* Amp Indices: DAC = 0, mixer = 1 */
15724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15726 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15727 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15728 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15729 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15732 /* FIXME: use matrix-type input source selection */
15733 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15735 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15736 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15740 /* additional verbs for ALC663 */
15741 static struct hda_verb alc663_auto_init_verbs[] = {
15742 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15743 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15747 static struct hda_verb alc663_m51va_init_verbs[] = {
15748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15749 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15750 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15751 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15753 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15754 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15755 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15756 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15760 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15761 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15762 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15763 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15764 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15766 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15767 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15771 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15772 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15773 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15774 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15775 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15778 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15779 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15783 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15784 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15785 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15786 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15789 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15790 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15794 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15795 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15796 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15797 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15798 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15802 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15803 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15804 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15805 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15806 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15810 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15811 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15812 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15813 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15814 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15815 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15817 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15820 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15821 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15822 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15826 static struct hda_verb alc663_g71v_init_verbs[] = {
15827 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15828 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15829 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15831 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15832 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15833 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15835 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15836 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15837 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15841 static struct hda_verb alc663_g50v_init_verbs[] = {
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, 0x00}, /* Headphone */
15846 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15847 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15851 static struct hda_verb alc662_ecs_init_verbs[] = {
15852 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15853 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15854 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15855 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15859 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15860 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15861 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15863 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15864 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15865 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15866 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15867 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15868 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15869 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15870 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15874 static struct hda_verb alc272_dell_init_verbs[] = {
15875 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15876 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15877 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15878 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15879 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15880 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15881 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15882 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15883 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15884 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15885 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15889 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15890 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15891 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15895 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15896 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15897 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15901 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15903 unsigned int present;
15904 unsigned char bits;
15906 present = snd_hda_codec_read(codec, 0x14, 0,
15907 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15908 bits = present ? HDA_AMP_MUTE : 0;
15909 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15910 HDA_AMP_MUTE, bits);
15913 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15915 unsigned int present;
15916 unsigned char bits;
15918 present = snd_hda_codec_read(codec, 0x1b, 0,
15919 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15920 bits = present ? HDA_AMP_MUTE : 0;
15921 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15922 HDA_AMP_MUTE, bits);
15923 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15924 HDA_AMP_MUTE, bits);
15927 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15930 if ((res >> 26) == ALC880_HP_EVENT)
15931 alc662_lenovo_101e_all_automute(codec);
15932 if ((res >> 26) == ALC880_FRONT_EVENT)
15933 alc662_lenovo_101e_ispeaker_automute(codec);
15936 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15938 unsigned int present;
15940 present = snd_hda_codec_read(codec, 0x18, 0,
15941 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15942 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15943 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15944 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15945 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15946 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15947 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15948 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15949 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15952 /* unsolicited event for HP jack sensing */
15953 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15956 if ((res >> 26) == ALC880_MIC_EVENT)
15957 alc662_eeepc_mic_automute(codec);
15959 alc262_hippo_unsol_event(codec, res);
15962 static void alc662_eeepc_inithook(struct hda_codec *codec)
15964 alc262_hippo1_init_hook(codec);
15965 alc662_eeepc_mic_automute(codec);
15968 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15970 struct alc_spec *spec = codec->spec;
15972 spec->autocfg.hp_pins[0] = 0x14;
15973 spec->autocfg.speaker_pins[0] = 0x1b;
15974 alc262_hippo_master_update(codec);
15977 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15979 unsigned int present;
15980 unsigned char bits;
15982 present = snd_hda_codec_read(codec, 0x21, 0,
15983 AC_VERB_GET_PIN_SENSE, 0)
15984 & AC_PINSENSE_PRESENCE;
15985 bits = present ? HDA_AMP_MUTE : 0;
15986 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15987 AMP_IN_MUTE(0), bits);
15988 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15989 AMP_IN_MUTE(0), bits);
15992 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15994 unsigned int present;
15995 unsigned char bits;
15997 present = snd_hda_codec_read(codec, 0x21, 0,
15998 AC_VERB_GET_PIN_SENSE, 0)
15999 & AC_PINSENSE_PRESENCE;
16000 bits = present ? HDA_AMP_MUTE : 0;
16001 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16002 AMP_IN_MUTE(0), bits);
16003 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16004 AMP_IN_MUTE(0), bits);
16005 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16006 AMP_IN_MUTE(0), bits);
16007 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16008 AMP_IN_MUTE(0), bits);
16011 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16013 unsigned int present;
16014 unsigned char bits;
16016 present = snd_hda_codec_read(codec, 0x15, 0,
16017 AC_VERB_GET_PIN_SENSE, 0)
16018 & AC_PINSENSE_PRESENCE;
16019 bits = present ? HDA_AMP_MUTE : 0;
16020 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16021 AMP_IN_MUTE(0), bits);
16022 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16023 AMP_IN_MUTE(0), bits);
16024 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16025 AMP_IN_MUTE(0), bits);
16026 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16027 AMP_IN_MUTE(0), bits);
16030 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16032 unsigned int present;
16033 unsigned char bits;
16035 present = snd_hda_codec_read(codec, 0x1b, 0,
16036 AC_VERB_GET_PIN_SENSE, 0)
16037 & AC_PINSENSE_PRESENCE;
16038 bits = present ? 0 : PIN_OUT;
16039 snd_hda_codec_write(codec, 0x14, 0,
16040 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16043 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16045 unsigned int present1, present2;
16047 present1 = snd_hda_codec_read(codec, 0x21, 0,
16048 AC_VERB_GET_PIN_SENSE, 0)
16049 & AC_PINSENSE_PRESENCE;
16050 present2 = snd_hda_codec_read(codec, 0x15, 0,
16051 AC_VERB_GET_PIN_SENSE, 0)
16052 & AC_PINSENSE_PRESENCE;
16054 if (present1 || present2) {
16055 snd_hda_codec_write_cache(codec, 0x14, 0,
16056 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16058 snd_hda_codec_write_cache(codec, 0x14, 0,
16059 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16063 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16065 unsigned int present1, present2;
16067 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16068 AC_VERB_GET_PIN_SENSE, 0)
16069 & AC_PINSENSE_PRESENCE;
16070 present2 = snd_hda_codec_read(codec, 0x15, 0,
16071 AC_VERB_GET_PIN_SENSE, 0)
16072 & AC_PINSENSE_PRESENCE;
16074 if (present1 || present2) {
16075 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16076 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16077 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16078 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16080 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16081 AMP_IN_MUTE(0), 0);
16082 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16083 AMP_IN_MUTE(0), 0);
16087 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16089 unsigned int present;
16091 present = snd_hda_codec_read(codec, 0x18, 0,
16092 AC_VERB_GET_PIN_SENSE, 0)
16093 & AC_PINSENSE_PRESENCE;
16094 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16095 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16096 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16097 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16098 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16099 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16100 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16101 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16104 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16107 switch (res >> 26) {
16108 case ALC880_HP_EVENT:
16109 alc663_m51va_speaker_automute(codec);
16111 case ALC880_MIC_EVENT:
16112 alc663_m51va_mic_automute(codec);
16117 static void alc663_m51va_inithook(struct hda_codec *codec)
16119 alc663_m51va_speaker_automute(codec);
16120 alc663_m51va_mic_automute(codec);
16123 /* ***************** Mode1 ******************************/
16124 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16127 switch (res >> 26) {
16128 case ALC880_HP_EVENT:
16129 alc663_m51va_speaker_automute(codec);
16131 case ALC880_MIC_EVENT:
16132 alc662_eeepc_mic_automute(codec);
16137 static void alc663_mode1_inithook(struct hda_codec *codec)
16139 alc663_m51va_speaker_automute(codec);
16140 alc662_eeepc_mic_automute(codec);
16142 /* ***************** Mode2 ******************************/
16143 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16146 switch (res >> 26) {
16147 case ALC880_HP_EVENT:
16148 alc662_f5z_speaker_automute(codec);
16150 case ALC880_MIC_EVENT:
16151 alc662_eeepc_mic_automute(codec);
16156 static void alc662_mode2_inithook(struct hda_codec *codec)
16158 alc662_f5z_speaker_automute(codec);
16159 alc662_eeepc_mic_automute(codec);
16161 /* ***************** Mode3 ******************************/
16162 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16165 switch (res >> 26) {
16166 case ALC880_HP_EVENT:
16167 alc663_two_hp_m1_speaker_automute(codec);
16169 case ALC880_MIC_EVENT:
16170 alc662_eeepc_mic_automute(codec);
16175 static void alc663_mode3_inithook(struct hda_codec *codec)
16177 alc663_two_hp_m1_speaker_automute(codec);
16178 alc662_eeepc_mic_automute(codec);
16180 /* ***************** Mode4 ******************************/
16181 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16184 switch (res >> 26) {
16185 case ALC880_HP_EVENT:
16186 alc663_21jd_two_speaker_automute(codec);
16188 case ALC880_MIC_EVENT:
16189 alc662_eeepc_mic_automute(codec);
16194 static void alc663_mode4_inithook(struct hda_codec *codec)
16196 alc663_21jd_two_speaker_automute(codec);
16197 alc662_eeepc_mic_automute(codec);
16199 /* ***************** Mode5 ******************************/
16200 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16203 switch (res >> 26) {
16204 case ALC880_HP_EVENT:
16205 alc663_15jd_two_speaker_automute(codec);
16207 case ALC880_MIC_EVENT:
16208 alc662_eeepc_mic_automute(codec);
16213 static void alc663_mode5_inithook(struct hda_codec *codec)
16215 alc663_15jd_two_speaker_automute(codec);
16216 alc662_eeepc_mic_automute(codec);
16218 /* ***************** Mode6 ******************************/
16219 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16222 switch (res >> 26) {
16223 case ALC880_HP_EVENT:
16224 alc663_two_hp_m2_speaker_automute(codec);
16226 case ALC880_MIC_EVENT:
16227 alc662_eeepc_mic_automute(codec);
16232 static void alc663_mode6_inithook(struct hda_codec *codec)
16234 alc663_two_hp_m2_speaker_automute(codec);
16235 alc662_eeepc_mic_automute(codec);
16238 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16240 unsigned int present;
16241 unsigned char bits;
16243 present = snd_hda_codec_read(codec, 0x21, 0,
16244 AC_VERB_GET_PIN_SENSE, 0)
16245 & AC_PINSENSE_PRESENCE;
16246 bits = present ? HDA_AMP_MUTE : 0;
16247 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16248 HDA_AMP_MUTE, bits);
16249 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16250 HDA_AMP_MUTE, bits);
16253 static void alc663_g71v_front_automute(struct hda_codec *codec)
16255 unsigned int present;
16256 unsigned char bits;
16258 present = snd_hda_codec_read(codec, 0x15, 0,
16259 AC_VERB_GET_PIN_SENSE, 0)
16260 & AC_PINSENSE_PRESENCE;
16261 bits = present ? HDA_AMP_MUTE : 0;
16262 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16263 HDA_AMP_MUTE, bits);
16266 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16269 switch (res >> 26) {
16270 case ALC880_HP_EVENT:
16271 alc663_g71v_hp_automute(codec);
16273 case ALC880_FRONT_EVENT:
16274 alc663_g71v_front_automute(codec);
16276 case ALC880_MIC_EVENT:
16277 alc662_eeepc_mic_automute(codec);
16282 static void alc663_g71v_inithook(struct hda_codec *codec)
16284 alc663_g71v_front_automute(codec);
16285 alc663_g71v_hp_automute(codec);
16286 alc662_eeepc_mic_automute(codec);
16289 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16292 switch (res >> 26) {
16293 case ALC880_HP_EVENT:
16294 alc663_m51va_speaker_automute(codec);
16296 case ALC880_MIC_EVENT:
16297 alc662_eeepc_mic_automute(codec);
16302 static void alc663_g50v_inithook(struct hda_codec *codec)
16304 alc663_m51va_speaker_automute(codec);
16305 alc662_eeepc_mic_automute(codec);
16308 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16309 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16310 ALC262_HIPPO_MASTER_SWITCH,
16312 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16313 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16314 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16316 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16317 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16318 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16322 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16323 /* Master Playback automatically created from Speaker and Headphone */
16324 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16325 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16326 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16327 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16329 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16330 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16331 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16333 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16334 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16335 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16339 #ifdef CONFIG_SND_HDA_POWER_SAVE
16340 #define alc662_loopbacks alc880_loopbacks
16344 /* pcm configuration: identiacal with ALC880 */
16345 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16346 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16347 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16348 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16351 * configuration and preset
16353 static const char *alc662_models[ALC662_MODEL_LAST] = {
16354 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16355 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16356 [ALC662_3ST_6ch] = "3stack-6ch",
16357 [ALC662_5ST_DIG] = "6stack-dig",
16358 [ALC662_LENOVO_101E] = "lenovo-101e",
16359 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16360 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16361 [ALC662_ECS] = "ecs",
16362 [ALC663_ASUS_M51VA] = "m51va",
16363 [ALC663_ASUS_G71V] = "g71v",
16364 [ALC663_ASUS_H13] = "h13",
16365 [ALC663_ASUS_G50V] = "g50v",
16366 [ALC663_ASUS_MODE1] = "asus-mode1",
16367 [ALC662_ASUS_MODE2] = "asus-mode2",
16368 [ALC663_ASUS_MODE3] = "asus-mode3",
16369 [ALC663_ASUS_MODE4] = "asus-mode4",
16370 [ALC663_ASUS_MODE5] = "asus-mode5",
16371 [ALC663_ASUS_MODE6] = "asus-mode6",
16372 [ALC272_DELL] = "dell",
16373 [ALC272_DELL_ZM1] = "dell-zm1",
16374 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16375 [ALC662_AUTO] = "auto",
16378 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16379 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16380 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16381 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16382 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16383 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16384 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16385 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16386 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16387 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16388 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16389 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16390 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16391 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16392 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16393 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16394 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16395 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16396 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16397 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16398 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16399 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16400 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16401 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16402 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16403 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16404 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16405 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16406 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16407 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16408 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16409 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16410 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16411 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16412 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16413 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16414 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16415 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16416 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16417 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16418 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16419 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16420 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16421 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16422 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16423 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16424 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16425 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16426 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16427 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16428 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16429 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16430 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16431 ALC662_3ST_6ch_DIG),
16432 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16433 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16434 ALC662_3ST_6ch_DIG),
16435 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16436 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16437 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16438 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16439 ALC662_3ST_6ch_DIG),
16440 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16445 static struct alc_config_preset alc662_presets[] = {
16446 [ALC662_3ST_2ch_DIG] = {
16447 .mixers = { alc662_3ST_2ch_mixer },
16448 .init_verbs = { alc662_init_verbs },
16449 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16450 .dac_nids = alc662_dac_nids,
16451 .dig_out_nid = ALC662_DIGOUT_NID,
16452 .dig_in_nid = ALC662_DIGIN_NID,
16453 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16454 .channel_mode = alc662_3ST_2ch_modes,
16455 .input_mux = &alc662_capture_source,
16457 [ALC662_3ST_6ch_DIG] = {
16458 .mixers = { alc662_3ST_6ch_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_3ST_6ch_modes),
16465 .channel_mode = alc662_3ST_6ch_modes,
16467 .input_mux = &alc662_capture_source,
16469 [ALC662_3ST_6ch] = {
16470 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16471 .init_verbs = { alc662_init_verbs },
16472 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16473 .dac_nids = alc662_dac_nids,
16474 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16475 .channel_mode = alc662_3ST_6ch_modes,
16477 .input_mux = &alc662_capture_source,
16479 [ALC662_5ST_DIG] = {
16480 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16481 .init_verbs = { alc662_init_verbs },
16482 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16483 .dac_nids = alc662_dac_nids,
16484 .dig_out_nid = ALC662_DIGOUT_NID,
16485 .dig_in_nid = ALC662_DIGIN_NID,
16486 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16487 .channel_mode = alc662_5stack_modes,
16488 .input_mux = &alc662_capture_source,
16490 [ALC662_LENOVO_101E] = {
16491 .mixers = { alc662_lenovo_101e_mixer },
16492 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16493 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16494 .dac_nids = alc662_dac_nids,
16495 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16496 .channel_mode = alc662_3ST_2ch_modes,
16497 .input_mux = &alc662_lenovo_101e_capture_source,
16498 .unsol_event = alc662_lenovo_101e_unsol_event,
16499 .init_hook = alc662_lenovo_101e_all_automute,
16501 [ALC662_ASUS_EEEPC_P701] = {
16502 .mixers = { alc662_eeepc_p701_mixer },
16503 .init_verbs = { alc662_init_verbs,
16504 alc662_eeepc_sue_init_verbs },
16505 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16506 .dac_nids = alc662_dac_nids,
16507 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16508 .channel_mode = alc662_3ST_2ch_modes,
16509 .input_mux = &alc662_eeepc_capture_source,
16510 .unsol_event = alc662_eeepc_unsol_event,
16511 .init_hook = alc662_eeepc_inithook,
16513 [ALC662_ASUS_EEEPC_EP20] = {
16514 .mixers = { alc662_eeepc_ep20_mixer,
16515 alc662_chmode_mixer },
16516 .init_verbs = { alc662_init_verbs,
16517 alc662_eeepc_ep20_sue_init_verbs },
16518 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16519 .dac_nids = alc662_dac_nids,
16520 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16521 .channel_mode = alc662_3ST_6ch_modes,
16522 .input_mux = &alc662_lenovo_101e_capture_source,
16523 .unsol_event = alc662_eeepc_unsol_event,
16524 .init_hook = alc662_eeepc_ep20_inithook,
16527 .mixers = { alc662_ecs_mixer },
16528 .init_verbs = { alc662_init_verbs,
16529 alc662_ecs_init_verbs },
16530 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16531 .dac_nids = alc662_dac_nids,
16532 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16533 .channel_mode = alc662_3ST_2ch_modes,
16534 .input_mux = &alc662_eeepc_capture_source,
16535 .unsol_event = alc662_eeepc_unsol_event,
16536 .init_hook = alc662_eeepc_inithook,
16538 [ALC663_ASUS_M51VA] = {
16539 .mixers = { alc663_m51va_mixer },
16540 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16541 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16542 .dac_nids = alc662_dac_nids,
16543 .dig_out_nid = ALC662_DIGOUT_NID,
16544 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16545 .channel_mode = alc662_3ST_2ch_modes,
16546 .input_mux = &alc663_m51va_capture_source,
16547 .unsol_event = alc663_m51va_unsol_event,
16548 .init_hook = alc663_m51va_inithook,
16550 [ALC663_ASUS_G71V] = {
16551 .mixers = { alc663_g71v_mixer },
16552 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16553 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16554 .dac_nids = alc662_dac_nids,
16555 .dig_out_nid = ALC662_DIGOUT_NID,
16556 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16557 .channel_mode = alc662_3ST_2ch_modes,
16558 .input_mux = &alc662_eeepc_capture_source,
16559 .unsol_event = alc663_g71v_unsol_event,
16560 .init_hook = alc663_g71v_inithook,
16562 [ALC663_ASUS_H13] = {
16563 .mixers = { alc663_m51va_mixer },
16564 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16565 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16566 .dac_nids = alc662_dac_nids,
16567 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16568 .channel_mode = alc662_3ST_2ch_modes,
16569 .input_mux = &alc663_m51va_capture_source,
16570 .unsol_event = alc663_m51va_unsol_event,
16571 .init_hook = alc663_m51va_inithook,
16573 [ALC663_ASUS_G50V] = {
16574 .mixers = { alc663_g50v_mixer },
16575 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16576 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16577 .dac_nids = alc662_dac_nids,
16578 .dig_out_nid = ALC662_DIGOUT_NID,
16579 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16580 .channel_mode = alc662_3ST_6ch_modes,
16581 .input_mux = &alc663_capture_source,
16582 .unsol_event = alc663_g50v_unsol_event,
16583 .init_hook = alc663_g50v_inithook,
16585 [ALC663_ASUS_MODE1] = {
16586 .mixers = { alc663_m51va_mixer },
16587 .cap_mixer = alc662_auto_capture_mixer,
16588 .init_verbs = { alc662_init_verbs,
16589 alc663_21jd_amic_init_verbs },
16590 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16592 .dac_nids = alc662_dac_nids,
16593 .dig_out_nid = ALC662_DIGOUT_NID,
16594 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16595 .channel_mode = alc662_3ST_2ch_modes,
16596 .input_mux = &alc662_eeepc_capture_source,
16597 .unsol_event = alc663_mode1_unsol_event,
16598 .init_hook = alc663_mode1_inithook,
16600 [ALC662_ASUS_MODE2] = {
16601 .mixers = { alc662_1bjd_mixer },
16602 .cap_mixer = alc662_auto_capture_mixer,
16603 .init_verbs = { alc662_init_verbs,
16604 alc662_1bjd_amic_init_verbs },
16605 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16606 .dac_nids = alc662_dac_nids,
16607 .dig_out_nid = ALC662_DIGOUT_NID,
16608 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16609 .channel_mode = alc662_3ST_2ch_modes,
16610 .input_mux = &alc662_eeepc_capture_source,
16611 .unsol_event = alc662_mode2_unsol_event,
16612 .init_hook = alc662_mode2_inithook,
16614 [ALC663_ASUS_MODE3] = {
16615 .mixers = { alc663_two_hp_m1_mixer },
16616 .cap_mixer = alc662_auto_capture_mixer,
16617 .init_verbs = { alc662_init_verbs,
16618 alc663_two_hp_amic_m1_init_verbs },
16619 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16621 .dac_nids = alc662_dac_nids,
16622 .dig_out_nid = ALC662_DIGOUT_NID,
16623 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16624 .channel_mode = alc662_3ST_2ch_modes,
16625 .input_mux = &alc662_eeepc_capture_source,
16626 .unsol_event = alc663_mode3_unsol_event,
16627 .init_hook = alc663_mode3_inithook,
16629 [ALC663_ASUS_MODE4] = {
16630 .mixers = { alc663_asus_21jd_clfe_mixer },
16631 .cap_mixer = alc662_auto_capture_mixer,
16632 .init_verbs = { alc662_init_verbs,
16633 alc663_21jd_amic_init_verbs},
16634 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16636 .dac_nids = alc662_dac_nids,
16637 .dig_out_nid = ALC662_DIGOUT_NID,
16638 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16639 .channel_mode = alc662_3ST_2ch_modes,
16640 .input_mux = &alc662_eeepc_capture_source,
16641 .unsol_event = alc663_mode4_unsol_event,
16642 .init_hook = alc663_mode4_inithook,
16644 [ALC663_ASUS_MODE5] = {
16645 .mixers = { alc663_asus_15jd_clfe_mixer },
16646 .cap_mixer = alc662_auto_capture_mixer,
16647 .init_verbs = { alc662_init_verbs,
16648 alc663_15jd_amic_init_verbs },
16649 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16651 .dac_nids = alc662_dac_nids,
16652 .dig_out_nid = ALC662_DIGOUT_NID,
16653 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16654 .channel_mode = alc662_3ST_2ch_modes,
16655 .input_mux = &alc662_eeepc_capture_source,
16656 .unsol_event = alc663_mode5_unsol_event,
16657 .init_hook = alc663_mode5_inithook,
16659 [ALC663_ASUS_MODE6] = {
16660 .mixers = { alc663_two_hp_m2_mixer },
16661 .cap_mixer = alc662_auto_capture_mixer,
16662 .init_verbs = { alc662_init_verbs,
16663 alc663_two_hp_amic_m2_init_verbs },
16664 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16666 .dac_nids = alc662_dac_nids,
16667 .dig_out_nid = ALC662_DIGOUT_NID,
16668 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16669 .channel_mode = alc662_3ST_2ch_modes,
16670 .input_mux = &alc662_eeepc_capture_source,
16671 .unsol_event = alc663_mode6_unsol_event,
16672 .init_hook = alc663_mode6_inithook,
16675 .mixers = { alc663_m51va_mixer },
16676 .cap_mixer = alc272_auto_capture_mixer,
16677 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16678 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16679 .dac_nids = alc662_dac_nids,
16680 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16681 .adc_nids = alc272_adc_nids,
16682 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16683 .capsrc_nids = alc272_capsrc_nids,
16684 .channel_mode = alc662_3ST_2ch_modes,
16685 .input_mux = &alc663_m51va_capture_source,
16686 .unsol_event = alc663_m51va_unsol_event,
16687 .init_hook = alc663_m51va_inithook,
16689 [ALC272_DELL_ZM1] = {
16690 .mixers = { alc663_m51va_mixer },
16691 .cap_mixer = alc662_auto_capture_mixer,
16692 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16693 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16694 .dac_nids = alc662_dac_nids,
16695 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16696 .adc_nids = alc662_adc_nids,
16697 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16698 .capsrc_nids = alc662_capsrc_nids,
16699 .channel_mode = alc662_3ST_2ch_modes,
16700 .input_mux = &alc663_m51va_capture_source,
16701 .unsol_event = alc663_m51va_unsol_event,
16702 .init_hook = alc663_m51va_inithook,
16704 [ALC272_SAMSUNG_NC10] = {
16705 .mixers = { alc272_nc10_mixer },
16706 .init_verbs = { alc662_init_verbs,
16707 alc663_21jd_amic_init_verbs },
16708 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16709 .dac_nids = alc272_dac_nids,
16710 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16711 .channel_mode = alc662_3ST_2ch_modes,
16712 .input_mux = &alc272_nc10_capture_source,
16713 .unsol_event = alc663_mode4_unsol_event,
16714 .init_hook = alc663_mode4_inithook,
16720 * BIOS auto configuration
16723 /* add playback controls from the parsed DAC table */
16724 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16725 const struct auto_pin_cfg *cfg)
16728 static const char *chname[4] = {
16729 "Front", "Surround", NULL /*CLFE*/, "Side"
16734 for (i = 0; i < cfg->line_outs; i++) {
16735 if (!spec->multiout.dac_nids[i])
16737 nid = alc880_idx_to_dac(i);
16740 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16741 "Center Playback Volume",
16742 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16746 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16747 "LFE Playback Volume",
16748 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16752 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16753 "Center Playback Switch",
16754 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16758 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16759 "LFE Playback Switch",
16760 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16765 sprintf(name, "%s Playback Volume", chname[i]);
16766 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16767 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16771 sprintf(name, "%s Playback Switch", chname[i]);
16772 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16773 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16782 /* add playback controls for speaker and HP outputs */
16783 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16794 /* ALC663 has a mono output pin on 0x17 */
16795 sprintf(name, "%s Playback Switch", pfx);
16796 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16797 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16801 if (alc880_is_fixed_pin(pin)) {
16802 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16803 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16804 /* specify the DAC as the extra output */
16805 if (!spec->multiout.hp_nid)
16806 spec->multiout.hp_nid = nid;
16808 spec->multiout.extra_out_nid[0] = nid;
16809 /* control HP volume/switch on the output mixer amp */
16810 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16811 sprintf(name, "%s Playback Volume", pfx);
16812 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16813 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16816 sprintf(name, "%s Playback Switch", pfx);
16817 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16818 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16821 } else if (alc880_is_multi_pin(pin)) {
16822 /* set manual connection */
16823 /* we have only a switch on HP-out PIN */
16824 sprintf(name, "%s Playback Switch", pfx);
16825 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16826 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16833 /* return the index of the src widget from the connection list of the nid.
16834 * return -1 if not found
16836 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16839 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16842 conns = snd_hda_get_connections(codec, nid, conn_list,
16843 ARRAY_SIZE(conn_list));
16846 for (i = 0; i < conns; i++)
16847 if (conn_list[i] == src)
16852 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16854 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16855 return (pincap & AC_PINCAP_IN) != 0;
16858 /* create playback/capture controls for input pins */
16859 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16860 const struct auto_pin_cfg *cfg)
16862 struct alc_spec *spec = codec->spec;
16863 struct hda_input_mux *imux = &spec->private_imux[0];
16866 for (i = 0; i < AUTO_PIN_LAST; i++) {
16867 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16868 idx = alc662_input_pin_idx(codec, 0x0b,
16869 cfg->input_pins[i]);
16871 err = new_analog_input(spec, cfg->input_pins[i],
16872 auto_pin_cfg_labels[i],
16877 idx = alc662_input_pin_idx(codec, 0x22,
16878 cfg->input_pins[i]);
16880 imux->items[imux->num_items].label =
16881 auto_pin_cfg_labels[i];
16882 imux->items[imux->num_items].index = idx;
16890 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16891 hda_nid_t nid, int pin_type,
16894 alc_set_pin_output(codec, nid, pin_type);
16895 /* need the manual connection? */
16896 if (alc880_is_multi_pin(nid)) {
16897 struct alc_spec *spec = codec->spec;
16898 int idx = alc880_multi_pin_idx(nid);
16899 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16900 AC_VERB_SET_CONNECT_SEL,
16901 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16905 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16907 struct alc_spec *spec = codec->spec;
16910 for (i = 0; i <= HDA_SIDE; i++) {
16911 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16912 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16914 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16919 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16921 struct alc_spec *spec = codec->spec;
16924 pin = spec->autocfg.hp_pins[0];
16925 if (pin) /* connect to front */
16927 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16928 pin = spec->autocfg.speaker_pins[0];
16930 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16933 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16935 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16937 struct alc_spec *spec = codec->spec;
16940 for (i = 0; i < AUTO_PIN_LAST; i++) {
16941 hda_nid_t nid = spec->autocfg.input_pins[i];
16942 if (alc662_is_input_pin(codec, nid)) {
16943 alc_set_input_pin(codec, nid, i);
16944 if (nid != ALC662_PIN_CD_NID &&
16945 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16946 snd_hda_codec_write(codec, nid, 0,
16947 AC_VERB_SET_AMP_GAIN_MUTE,
16953 #define alc662_auto_init_input_src alc882_auto_init_input_src
16955 static int alc662_parse_auto_config(struct hda_codec *codec)
16957 struct alc_spec *spec = codec->spec;
16959 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16961 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16965 if (!spec->autocfg.line_outs)
16966 return 0; /* can't find valid BIOS pin config */
16968 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16971 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16974 err = alc662_auto_create_extra_out(spec,
16975 spec->autocfg.speaker_pins[0],
16979 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16983 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
16987 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16989 if (spec->autocfg.dig_outs)
16990 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16992 if (spec->kctls.list)
16993 add_mixer(spec, spec->kctls.list);
16995 spec->num_mux_defs = 1;
16996 spec->input_mux = &spec->private_imux[0];
16998 add_verb(spec, alc662_auto_init_verbs);
16999 if (codec->vendor_id == 0x10ec0663)
17000 add_verb(spec, alc663_auto_init_verbs);
17002 err = alc_auto_add_mic_boost(codec);
17006 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17011 /* additional initialization for auto-configuration model */
17012 static void alc662_auto_init(struct hda_codec *codec)
17014 struct alc_spec *spec = codec->spec;
17015 alc662_auto_init_multi_out(codec);
17016 alc662_auto_init_hp_out(codec);
17017 alc662_auto_init_analog_input(codec);
17018 alc662_auto_init_input_src(codec);
17019 if (spec->unsol_event)
17020 alc_inithook(codec);
17023 static int patch_alc662(struct hda_codec *codec)
17025 struct alc_spec *spec;
17026 int err, board_config;
17028 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17032 codec->spec = spec;
17034 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17036 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17039 if (board_config < 0) {
17040 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17041 "trying auto-probe from BIOS...\n", codec->chip_name);
17042 board_config = ALC662_AUTO;
17045 if (board_config == ALC662_AUTO) {
17046 /* automatic parse from the BIOS config */
17047 err = alc662_parse_auto_config(codec);
17053 "hda_codec: Cannot set up configuration "
17054 "from BIOS. Using base mode...\n");
17055 board_config = ALC662_3ST_2ch_DIG;
17059 err = snd_hda_attach_beep_device(codec, 0x1);
17065 if (board_config != ALC662_AUTO)
17066 setup_preset(spec, &alc662_presets[board_config]);
17068 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17069 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17071 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17072 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17074 spec->adc_nids = alc662_adc_nids;
17075 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17076 spec->capsrc_nids = alc662_capsrc_nids;
17077 spec->capture_style = CAPT_MIX;
17079 if (!spec->cap_mixer)
17080 set_capture_mixer(spec);
17081 if (codec->vendor_id == 0x10ec0662)
17082 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17084 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17086 spec->vmaster_nid = 0x02;
17088 codec->patch_ops = alc_patch_ops;
17089 if (board_config == ALC662_AUTO)
17090 spec->init_hook = alc662_auto_init;
17091 #ifdef CONFIG_SND_HDA_POWER_SAVE
17092 if (!spec->loopback.amplist)
17093 spec->loopback.amplist = alc662_loopbacks;
17095 codec->proc_widget_hook = print_realtek_coef;
17103 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17104 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17105 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17106 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17107 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17108 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17109 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17110 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17111 .patch = patch_alc861 },
17112 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17113 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17114 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17115 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17116 .patch = patch_alc883 },
17117 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17118 .patch = patch_alc662 },
17119 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17120 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17121 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17122 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17123 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17124 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17125 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17126 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17127 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17128 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17129 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17130 .patch = patch_alc883 },
17131 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17132 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17133 {} /* terminator */
17136 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17138 MODULE_LICENSE("GPL");
17139 MODULE_DESCRIPTION("Realtek HD-audio codec");
17141 static struct hda_codec_preset_list realtek_list = {
17142 .preset = snd_hda_preset_realtek,
17143 .owner = THIS_MODULE,
17146 static int __init patch_realtek_init(void)
17148 return snd_hda_add_codec_preset(&realtek_list);
17151 static void __exit patch_realtek_exit(void)
17153 snd_hda_delete_codec_preset(&realtek_list);
17156 module_init(patch_realtek_init)
17157 module_exit(patch_realtek_exit)