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, 0x7023 },
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, 0x7023 },
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, 16, 17, 0b */
10652 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10656 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10668 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10673 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10675 * Unmute ADC0-2 and set the default input to mic-in
10677 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10679 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10680 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10681 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10682 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10684 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10686 * Note: PASD motherboards uses the Line In 2 as the input for front
10687 * panel mic (mic 2)
10689 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10699 * Set up output mixers (0x0c - 0x0e)
10701 /* set vol=0 to output mixers */
10702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10703 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10704 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10706 /* set up input amps for analog loopback */
10707 /* Amp Indices: DAC = 0, mixer = 1 */
10708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10717 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10718 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10720 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10721 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10722 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10724 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10727 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10728 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10730 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10731 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10732 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10733 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10734 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10735 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10737 /* FIXME: use matrix-type input source selection */
10738 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10739 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10743 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10744 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10745 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10746 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10748 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10749 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10752 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10753 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10754 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10761 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10764 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10769 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10771 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10773 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10775 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10776 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10777 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10781 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10782 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10787 #ifdef CONFIG_SND_HDA_POWER_SAVE
10788 #define alc262_loopbacks alc880_loopbacks
10791 /* pcm configuration: identiacal with ALC880 */
10792 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10793 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10794 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10795 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10798 * BIOS auto configuration
10800 static int alc262_parse_auto_config(struct hda_codec *codec)
10802 struct alc_spec *spec = codec->spec;
10804 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10806 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10810 if (!spec->autocfg.line_outs) {
10811 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10812 spec->multiout.max_channels = 2;
10813 spec->no_analog = 1;
10816 return 0; /* can't find valid BIOS pin config */
10818 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10821 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10825 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10828 if (spec->autocfg.dig_outs) {
10829 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10830 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10832 if (spec->autocfg.dig_in_pin)
10833 spec->dig_in_nid = ALC262_DIGIN_NID;
10835 if (spec->kctls.list)
10836 add_mixer(spec, spec->kctls.list);
10838 add_verb(spec, alc262_volume_init_verbs);
10839 spec->num_mux_defs = 1;
10840 spec->input_mux = &spec->private_imux[0];
10842 err = alc_auto_add_mic_boost(codec);
10846 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10851 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10852 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10853 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10854 #define alc262_auto_init_input_src alc882_auto_init_input_src
10857 /* init callback for auto-configuration model -- overriding the default init */
10858 static void alc262_auto_init(struct hda_codec *codec)
10860 struct alc_spec *spec = codec->spec;
10861 alc262_auto_init_multi_out(codec);
10862 alc262_auto_init_hp_out(codec);
10863 alc262_auto_init_analog_input(codec);
10864 alc262_auto_init_input_src(codec);
10865 if (spec->unsol_event)
10866 alc_inithook(codec);
10870 * configuration and preset
10872 static const char *alc262_models[ALC262_MODEL_LAST] = {
10873 [ALC262_BASIC] = "basic",
10874 [ALC262_HIPPO] = "hippo",
10875 [ALC262_HIPPO_1] = "hippo_1",
10876 [ALC262_FUJITSU] = "fujitsu",
10877 [ALC262_HP_BPC] = "hp-bpc",
10878 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10879 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10880 [ALC262_HP_RP5700] = "hp-rp5700",
10881 [ALC262_BENQ_ED8] = "benq",
10882 [ALC262_BENQ_T31] = "benq-t31",
10883 [ALC262_SONY_ASSAMD] = "sony-assamd",
10884 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10885 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10886 [ALC262_ULTRA] = "ultra",
10887 [ALC262_LENOVO_3000] = "lenovo-3000",
10888 [ALC262_NEC] = "nec",
10889 [ALC262_TYAN] = "tyan",
10890 [ALC262_AUTO] = "auto",
10893 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10894 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10895 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10896 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10898 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10900 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10902 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10903 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10904 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10905 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10906 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10907 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10908 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10909 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10910 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10911 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10912 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10913 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10914 ALC262_HP_TC_T5735),
10915 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10916 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10917 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10918 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10919 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10920 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10921 ALC262_SONY_ASSAMD),
10922 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10923 ALC262_TOSHIBA_RX1),
10924 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10925 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10926 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10927 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10928 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10930 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10931 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10932 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10933 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10934 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10938 static struct alc_config_preset alc262_presets[] = {
10940 .mixers = { alc262_base_mixer },
10941 .init_verbs = { alc262_init_verbs },
10942 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10943 .dac_nids = alc262_dac_nids,
10945 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10946 .channel_mode = alc262_modes,
10947 .input_mux = &alc262_capture_source,
10950 .mixers = { alc262_hippo_mixer },
10951 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10952 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10953 .dac_nids = alc262_dac_nids,
10955 .dig_out_nid = ALC262_DIGOUT_NID,
10956 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10957 .channel_mode = alc262_modes,
10958 .input_mux = &alc262_capture_source,
10959 .unsol_event = alc262_hippo_unsol_event,
10960 .init_hook = alc262_hippo_init_hook,
10962 [ALC262_HIPPO_1] = {
10963 .mixers = { alc262_hippo1_mixer },
10964 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10965 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10966 .dac_nids = alc262_dac_nids,
10968 .dig_out_nid = ALC262_DIGOUT_NID,
10969 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10970 .channel_mode = alc262_modes,
10971 .input_mux = &alc262_capture_source,
10972 .unsol_event = alc262_hippo_unsol_event,
10973 .init_hook = alc262_hippo1_init_hook,
10975 [ALC262_FUJITSU] = {
10976 .mixers = { alc262_fujitsu_mixer },
10977 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10978 alc262_fujitsu_unsol_verbs },
10979 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10980 .dac_nids = alc262_dac_nids,
10982 .dig_out_nid = ALC262_DIGOUT_NID,
10983 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10984 .channel_mode = alc262_modes,
10985 .input_mux = &alc262_fujitsu_capture_source,
10986 .unsol_event = alc262_fujitsu_unsol_event,
10987 .init_hook = alc262_fujitsu_init_hook,
10989 [ALC262_HP_BPC] = {
10990 .mixers = { alc262_HP_BPC_mixer },
10991 .init_verbs = { alc262_HP_BPC_init_verbs },
10992 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10993 .dac_nids = alc262_dac_nids,
10995 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10996 .channel_mode = alc262_modes,
10997 .input_mux = &alc262_HP_capture_source,
10998 .unsol_event = alc262_hp_bpc_unsol_event,
10999 .init_hook = alc262_hp_bpc_automute,
11001 [ALC262_HP_BPC_D7000_WF] = {
11002 .mixers = { alc262_HP_BPC_WildWest_mixer },
11003 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11004 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11005 .dac_nids = alc262_dac_nids,
11007 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11008 .channel_mode = alc262_modes,
11009 .input_mux = &alc262_HP_D7000_capture_source,
11010 .unsol_event = alc262_hp_wildwest_unsol_event,
11011 .init_hook = alc262_hp_wildwest_automute,
11013 [ALC262_HP_BPC_D7000_WL] = {
11014 .mixers = { alc262_HP_BPC_WildWest_mixer,
11015 alc262_HP_BPC_WildWest_option_mixer },
11016 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11017 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11018 .dac_nids = alc262_dac_nids,
11020 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11021 .channel_mode = alc262_modes,
11022 .input_mux = &alc262_HP_D7000_capture_source,
11023 .unsol_event = alc262_hp_wildwest_unsol_event,
11024 .init_hook = alc262_hp_wildwest_automute,
11026 [ALC262_HP_TC_T5735] = {
11027 .mixers = { alc262_hp_t5735_mixer },
11028 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11029 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11030 .dac_nids = alc262_dac_nids,
11032 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11033 .channel_mode = alc262_modes,
11034 .input_mux = &alc262_capture_source,
11035 .unsol_event = alc_automute_amp_unsol_event,
11036 .init_hook = alc262_hp_t5735_init_hook,
11038 [ALC262_HP_RP5700] = {
11039 .mixers = { alc262_hp_rp5700_mixer },
11040 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11041 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11042 .dac_nids = alc262_dac_nids,
11043 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11044 .channel_mode = alc262_modes,
11045 .input_mux = &alc262_hp_rp5700_capture_source,
11047 [ALC262_BENQ_ED8] = {
11048 .mixers = { alc262_base_mixer },
11049 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11050 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11051 .dac_nids = alc262_dac_nids,
11053 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11054 .channel_mode = alc262_modes,
11055 .input_mux = &alc262_capture_source,
11057 [ALC262_SONY_ASSAMD] = {
11058 .mixers = { alc262_sony_mixer },
11059 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11060 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11061 .dac_nids = alc262_dac_nids,
11063 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11064 .channel_mode = alc262_modes,
11065 .input_mux = &alc262_capture_source,
11066 .unsol_event = alc262_hippo_unsol_event,
11067 .init_hook = alc262_hippo_init_hook,
11069 [ALC262_BENQ_T31] = {
11070 .mixers = { alc262_benq_t31_mixer },
11071 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11072 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11073 .dac_nids = alc262_dac_nids,
11075 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11076 .channel_mode = alc262_modes,
11077 .input_mux = &alc262_capture_source,
11078 .unsol_event = alc262_hippo_unsol_event,
11079 .init_hook = alc262_hippo_init_hook,
11082 .mixers = { alc262_ultra_mixer },
11083 .cap_mixer = alc262_ultra_capture_mixer,
11084 .init_verbs = { alc262_ultra_verbs },
11085 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11086 .dac_nids = alc262_dac_nids,
11087 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11088 .channel_mode = alc262_modes,
11089 .input_mux = &alc262_ultra_capture_source,
11090 .adc_nids = alc262_adc_nids, /* ADC0 */
11091 .capsrc_nids = alc262_capsrc_nids,
11092 .num_adc_nids = 1, /* single ADC */
11093 .unsol_event = alc262_ultra_unsol_event,
11094 .init_hook = alc262_ultra_automute,
11096 [ALC262_LENOVO_3000] = {
11097 .mixers = { alc262_lenovo_3000_mixer },
11098 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11099 alc262_lenovo_3000_unsol_verbs },
11100 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11101 .dac_nids = alc262_dac_nids,
11103 .dig_out_nid = ALC262_DIGOUT_NID,
11104 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11105 .channel_mode = alc262_modes,
11106 .input_mux = &alc262_fujitsu_capture_source,
11107 .unsol_event = alc262_lenovo_3000_unsol_event,
11110 .mixers = { alc262_nec_mixer },
11111 .init_verbs = { alc262_nec_verbs },
11112 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11113 .dac_nids = alc262_dac_nids,
11115 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11116 .channel_mode = alc262_modes,
11117 .input_mux = &alc262_capture_source,
11119 [ALC262_TOSHIBA_S06] = {
11120 .mixers = { alc262_toshiba_s06_mixer },
11121 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11122 alc262_eapd_verbs },
11123 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11124 .capsrc_nids = alc262_dmic_capsrc_nids,
11125 .dac_nids = alc262_dac_nids,
11126 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11127 .dig_out_nid = ALC262_DIGOUT_NID,
11128 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11129 .channel_mode = alc262_modes,
11130 .input_mux = &alc262_dmic_capture_source,
11131 .unsol_event = alc262_toshiba_s06_unsol_event,
11132 .init_hook = alc262_toshiba_s06_init_hook,
11134 [ALC262_TOSHIBA_RX1] = {
11135 .mixers = { alc262_toshiba_rx1_mixer },
11136 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11137 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11138 .dac_nids = alc262_dac_nids,
11140 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11141 .channel_mode = alc262_modes,
11142 .input_mux = &alc262_capture_source,
11143 .unsol_event = alc262_hippo_unsol_event,
11144 .init_hook = alc262_hippo_init_hook,
11147 .mixers = { alc262_tyan_mixer },
11148 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11149 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11150 .dac_nids = alc262_dac_nids,
11152 .dig_out_nid = ALC262_DIGOUT_NID,
11153 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11154 .channel_mode = alc262_modes,
11155 .input_mux = &alc262_capture_source,
11156 .unsol_event = alc_automute_amp_unsol_event,
11157 .init_hook = alc262_tyan_init_hook,
11161 static int patch_alc262(struct hda_codec *codec)
11163 struct alc_spec *spec;
11167 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11171 codec->spec = spec;
11173 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11178 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11179 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11180 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11181 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11185 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11187 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11191 if (board_config < 0) {
11192 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11193 "trying auto-probe from BIOS...\n", codec->chip_name);
11194 board_config = ALC262_AUTO;
11197 if (board_config == ALC262_AUTO) {
11198 /* automatic parse from the BIOS config */
11199 err = alc262_parse_auto_config(codec);
11205 "hda_codec: Cannot set up configuration "
11206 "from BIOS. Using base mode...\n");
11207 board_config = ALC262_BASIC;
11211 if (!spec->no_analog) {
11212 err = snd_hda_attach_beep_device(codec, 0x1);
11219 if (board_config != ALC262_AUTO)
11220 setup_preset(spec, &alc262_presets[board_config]);
11222 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11223 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11225 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11226 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11228 spec->capture_style = CAPT_MIX;
11229 if (!spec->adc_nids && spec->input_mux) {
11230 /* check whether NID 0x07 is valid */
11231 unsigned int wcap = get_wcaps(codec, 0x07);
11234 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11235 if (wcap != AC_WID_AUD_IN) {
11236 spec->adc_nids = alc262_adc_nids_alt;
11237 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11238 spec->capsrc_nids = alc262_capsrc_nids_alt;
11240 spec->adc_nids = alc262_adc_nids;
11241 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11242 spec->capsrc_nids = alc262_capsrc_nids;
11245 if (!spec->cap_mixer && !spec->no_analog)
11246 set_capture_mixer(spec);
11247 if (!spec->no_analog)
11248 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11250 spec->vmaster_nid = 0x0c;
11252 codec->patch_ops = alc_patch_ops;
11253 if (board_config == ALC262_AUTO)
11254 spec->init_hook = alc262_auto_init;
11255 #ifdef CONFIG_SND_HDA_POWER_SAVE
11256 if (!spec->loopback.amplist)
11257 spec->loopback.amplist = alc262_loopbacks;
11259 codec->proc_widget_hook = print_realtek_coef;
11265 * ALC268 channel source setting (2 channel)
11267 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11268 #define alc268_modes alc260_modes
11270 static hda_nid_t alc268_dac_nids[2] = {
11275 static hda_nid_t alc268_adc_nids[2] = {
11280 static hda_nid_t alc268_adc_nids_alt[1] = {
11285 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11287 static struct snd_kcontrol_new alc268_base_mixer[] = {
11288 /* output mixer control */
11289 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11291 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11293 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11295 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11299 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11300 /* output mixer control */
11301 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11302 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11303 ALC262_HIPPO_MASTER_SWITCH,
11304 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11305 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11306 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11310 /* bind Beep switches of both NID 0x0f and 0x10 */
11311 static struct hda_bind_ctls alc268_bind_beep_sw = {
11312 .ops = &snd_hda_bind_sw,
11314 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11315 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11320 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11321 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11322 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11326 static struct hda_verb alc268_eapd_verbs[] = {
11327 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11328 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11332 /* Toshiba specific */
11333 static struct hda_verb alc268_toshiba_verbs[] = {
11334 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11338 static struct hda_input_mux alc268_acer_lc_capture_source = {
11346 /* Acer specific */
11347 /* bind volumes of both NID 0x02 and 0x03 */
11348 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11349 .ops = &snd_hda_bind_vol,
11351 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11352 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11357 /* mute/unmute internal speaker according to the hp jack and mute state */
11358 static void alc268_acer_automute(struct hda_codec *codec, int force)
11360 struct alc_spec *spec = codec->spec;
11363 if (force || !spec->sense_updated) {
11364 unsigned int present;
11365 present = snd_hda_codec_read(codec, 0x14, 0,
11366 AC_VERB_GET_PIN_SENSE, 0);
11367 spec->jack_present = (present & 0x80000000) != 0;
11368 spec->sense_updated = 1;
11370 if (spec->jack_present)
11371 mute = HDA_AMP_MUTE; /* mute internal speaker */
11372 else /* unmute internal speaker if necessary */
11373 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11374 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11375 HDA_AMP_MUTE, mute);
11379 /* bind hp and internal speaker mute (with plug check) */
11380 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11381 struct snd_ctl_elem_value *ucontrol)
11383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11384 long *valp = ucontrol->value.integer.value;
11387 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11389 valp[0] ? 0 : HDA_AMP_MUTE);
11390 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11392 valp[1] ? 0 : HDA_AMP_MUTE);
11394 alc268_acer_automute(codec, 0);
11398 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11399 /* output mixer control */
11400 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11403 .name = "Master Playback Switch",
11404 .info = snd_hda_mixer_amp_switch_info,
11405 .get = snd_hda_mixer_amp_switch_get,
11406 .put = alc268_acer_master_sw_put,
11407 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11409 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11413 static struct snd_kcontrol_new alc268_acer_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", 0x18, 0, HDA_INPUT),
11425 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11426 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11430 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11431 /* output mixer control */
11432 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11435 .name = "Master Playback Switch",
11436 .info = snd_hda_mixer_amp_switch_info,
11437 .get = snd_hda_mixer_amp_switch_get,
11438 .put = alc268_acer_master_sw_put,
11439 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11441 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11442 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11446 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11447 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11448 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11449 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11450 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11451 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11456 static struct hda_verb alc268_acer_verbs[] = {
11457 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11458 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11460 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11461 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11462 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11463 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11467 /* unsolicited event for HP jack sensing */
11468 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11469 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11471 static void alc268_acer_unsol_event(struct hda_codec *codec,
11474 if ((res >> 26) != ALC880_HP_EVENT)
11476 alc268_acer_automute(codec, 1);
11479 static void alc268_acer_init_hook(struct hda_codec *codec)
11481 alc268_acer_automute(codec, 1);
11484 /* toggle speaker-output according to the hp-jack state */
11485 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11487 unsigned int present;
11488 unsigned char bits;
11490 present = snd_hda_codec_read(codec, 0x15, 0,
11491 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11492 bits = present ? AMP_IN_MUTE(0) : 0;
11493 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11494 AMP_IN_MUTE(0), bits);
11495 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11496 AMP_IN_MUTE(0), bits);
11500 static void alc268_acer_mic_automute(struct hda_codec *codec)
11502 unsigned int present;
11504 present = snd_hda_codec_read(codec, 0x18, 0,
11505 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11506 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11507 present ? 0x0 : 0x6);
11510 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11513 if ((res >> 26) == ALC880_HP_EVENT)
11514 alc268_aspire_one_speaker_automute(codec);
11515 if ((res >> 26) == ALC880_MIC_EVENT)
11516 alc268_acer_mic_automute(codec);
11519 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11521 alc268_aspire_one_speaker_automute(codec);
11522 alc268_acer_mic_automute(codec);
11525 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11526 /* output mixer control */
11527 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11528 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11529 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11530 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11531 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11532 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11536 static struct hda_verb alc268_dell_verbs[] = {
11537 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11538 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11539 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11543 /* mute/unmute internal speaker according to the hp jack and mute state */
11544 static void alc268_dell_init_hook(struct hda_codec *codec)
11546 struct alc_spec *spec = codec->spec;
11548 spec->autocfg.hp_pins[0] = 0x15;
11549 spec->autocfg.speaker_pins[0] = 0x14;
11550 alc_automute_pin(codec);
11553 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11554 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11555 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11556 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11557 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11558 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11559 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11560 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11561 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11565 static struct hda_verb alc267_quanta_il1_verbs[] = {
11566 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11567 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11571 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11573 unsigned int present;
11575 present = snd_hda_codec_read(codec, 0x18, 0,
11576 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11577 snd_hda_codec_write(codec, 0x23, 0,
11578 AC_VERB_SET_CONNECT_SEL,
11579 present ? 0x00 : 0x01);
11582 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11584 struct alc_spec *spec = codec->spec;
11586 spec->autocfg.hp_pins[0] = 0x15;
11587 spec->autocfg.speaker_pins[0] = 0x14;
11588 alc_automute_pin(codec);
11589 alc267_quanta_il1_mic_automute(codec);
11592 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11595 switch (res >> 26) {
11596 case ALC880_MIC_EVENT:
11597 alc267_quanta_il1_mic_automute(codec);
11600 alc_sku_unsol_event(codec, res);
11606 * generic initialization of ADC, input mixers and output mixers
11608 static struct hda_verb alc268_base_init_verbs[] = {
11609 /* Unmute DAC0-1 and set vol = 0 */
11610 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11611 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11614 * Set up output mixers (0x0c - 0x0e)
11616 /* set vol=0 to output mixers */
11617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11618 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11620 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11621 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11624 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11625 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11626 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11627 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11629 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11630 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11632 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11634 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11635 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11636 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11638 /* set PCBEEP vol = 0, mute connections */
11639 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11640 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11641 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11643 /* Unmute Selector 23h,24h and set the default input to mic-in */
11645 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11646 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11647 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11654 * generic initialization of ADC, input mixers and output mixers
11656 static struct hda_verb alc268_volume_init_verbs[] = {
11657 /* set output DAC */
11658 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11659 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11661 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11662 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11663 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11664 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11665 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11667 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11668 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11669 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11671 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11672 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11674 /* set PCBEEP vol = 0, mute connections */
11675 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11676 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11677 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11682 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11683 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11684 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11687 /* The multiple "Capture Source" controls confuse alsamixer
11688 * So call somewhat different..
11690 /* .name = "Capture Source", */
11691 .name = "Input Source",
11693 .info = alc_mux_enum_info,
11694 .get = alc_mux_enum_get,
11695 .put = alc_mux_enum_put,
11700 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11701 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11702 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11703 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11704 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11706 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11707 /* The multiple "Capture Source" controls confuse alsamixer
11708 * So call somewhat different..
11710 /* .name = "Capture Source", */
11711 .name = "Input Source",
11713 .info = alc_mux_enum_info,
11714 .get = alc_mux_enum_get,
11715 .put = alc_mux_enum_put,
11720 static struct hda_input_mux alc268_capture_source = {
11724 { "Front Mic", 0x1 },
11730 static struct hda_input_mux alc268_acer_capture_source = {
11734 { "Internal Mic", 0x1 },
11739 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11743 { "Internal Mic", 0x6 },
11748 #ifdef CONFIG_SND_DEBUG
11749 static struct snd_kcontrol_new alc268_test_mixer[] = {
11750 /* Volume widgets */
11751 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11752 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11753 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11754 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11755 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11756 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11757 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11758 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11759 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11760 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11761 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11762 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11763 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11764 /* The below appears problematic on some hardwares */
11765 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11766 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11767 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11768 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11769 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11771 /* Modes for retasking pin widgets */
11772 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11773 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11774 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11775 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11777 /* Controls for GPIO pins, assuming they are configured as outputs */
11778 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11779 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11780 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11781 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11783 /* Switches to allow the digital SPDIF output pin to be enabled.
11784 * The ALC268 does not have an SPDIF input.
11786 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11788 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11789 * this output to turn on an external amplifier.
11791 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11792 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11798 /* create input playback/capture controls for the given pin */
11799 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11800 const char *ctlname, int idx)
11805 sprintf(name, "%s Playback Volume", ctlname);
11807 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11808 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11812 } else if (nid == 0x15) {
11813 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11814 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11820 sprintf(name, "%s Playback Switch", ctlname);
11821 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11822 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11828 /* add playback controls from the parsed DAC table */
11829 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11830 const struct auto_pin_cfg *cfg)
11835 spec->multiout.num_dacs = 2; /* only use one dac */
11836 spec->multiout.dac_nids = spec->private_dac_nids;
11837 spec->multiout.dac_nids[0] = 2;
11838 spec->multiout.dac_nids[1] = 3;
11840 nid = cfg->line_out_pins[0];
11842 alc268_new_analog_output(spec, nid, "Front", 0);
11844 nid = cfg->speaker_pins[0];
11846 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11847 "Speaker Playback Volume",
11848 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11852 nid = cfg->hp_pins[0];
11854 alc268_new_analog_output(spec, nid, "Headphone", 0);
11856 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11858 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11859 "Mono Playback Switch",
11860 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11867 /* create playback/capture controls for input pins */
11868 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11869 const struct auto_pin_cfg *cfg)
11871 struct hda_input_mux *imux = &spec->private_imux[0];
11874 for (i = 0; i < AUTO_PIN_LAST; i++) {
11875 switch(cfg->input_pins[i]) {
11877 idx1 = 0; /* Mic 1 */
11880 idx1 = 1; /* Mic 2 */
11883 idx1 = 2; /* Line In */
11890 idx1 = 6; /* digital mics */
11895 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11896 imux->items[imux->num_items].index = idx1;
11902 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11904 struct alc_spec *spec = codec->spec;
11905 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11906 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11907 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11908 unsigned int dac_vol1, dac_vol2;
11911 snd_hda_codec_write(codec, speaker_nid, 0,
11912 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11913 snd_hda_codec_write(codec, 0x0f, 0,
11914 AC_VERB_SET_AMP_GAIN_MUTE,
11916 snd_hda_codec_write(codec, 0x10, 0,
11917 AC_VERB_SET_AMP_GAIN_MUTE,
11920 snd_hda_codec_write(codec, 0x0f, 0,
11921 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11922 snd_hda_codec_write(codec, 0x10, 0,
11923 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11926 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11927 if (line_nid == 0x14)
11928 dac_vol2 = AMP_OUT_ZERO;
11929 else if (line_nid == 0x15)
11930 dac_vol1 = AMP_OUT_ZERO;
11931 if (hp_nid == 0x14)
11932 dac_vol2 = AMP_OUT_ZERO;
11933 else if (hp_nid == 0x15)
11934 dac_vol1 = AMP_OUT_ZERO;
11935 if (line_nid != 0x16 || hp_nid != 0x16 ||
11936 spec->autocfg.line_out_pins[1] != 0x16 ||
11937 spec->autocfg.line_out_pins[2] != 0x16)
11938 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11940 snd_hda_codec_write(codec, 0x02, 0,
11941 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11942 snd_hda_codec_write(codec, 0x03, 0,
11943 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11946 /* pcm configuration: identiacal with ALC880 */
11947 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11948 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11949 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11950 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11953 * BIOS auto configuration
11955 static int alc268_parse_auto_config(struct hda_codec *codec)
11957 struct alc_spec *spec = codec->spec;
11959 static hda_nid_t alc268_ignore[] = { 0 };
11961 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11965 if (!spec->autocfg.line_outs) {
11966 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11967 spec->multiout.max_channels = 2;
11968 spec->no_analog = 1;
11971 return 0; /* can't find valid BIOS pin config */
11973 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11976 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11980 spec->multiout.max_channels = 2;
11983 /* digital only support output */
11984 if (spec->autocfg.dig_outs) {
11985 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11986 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11988 if (spec->kctls.list)
11989 add_mixer(spec, spec->kctls.list);
11991 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
11992 add_mixer(spec, alc268_beep_mixer);
11994 add_verb(spec, alc268_volume_init_verbs);
11995 spec->num_mux_defs = 1;
11996 spec->input_mux = &spec->private_imux[0];
11998 err = alc_auto_add_mic_boost(codec);
12005 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12006 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12007 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12009 /* init callback for auto-configuration model -- overriding the default init */
12010 static void alc268_auto_init(struct hda_codec *codec)
12012 struct alc_spec *spec = codec->spec;
12013 alc268_auto_init_multi_out(codec);
12014 alc268_auto_init_hp_out(codec);
12015 alc268_auto_init_mono_speaker_out(codec);
12016 alc268_auto_init_analog_input(codec);
12017 if (spec->unsol_event)
12018 alc_inithook(codec);
12022 * configuration and preset
12024 static const char *alc268_models[ALC268_MODEL_LAST] = {
12025 [ALC267_QUANTA_IL1] = "quanta-il1",
12026 [ALC268_3ST] = "3stack",
12027 [ALC268_TOSHIBA] = "toshiba",
12028 [ALC268_ACER] = "acer",
12029 [ALC268_ACER_DMIC] = "acer-dmic",
12030 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12031 [ALC268_DELL] = "dell",
12032 [ALC268_ZEPTO] = "zepto",
12033 #ifdef CONFIG_SND_DEBUG
12034 [ALC268_TEST] = "test",
12036 [ALC268_AUTO] = "auto",
12039 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12040 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12041 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12042 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12043 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12044 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12045 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12046 ALC268_ACER_ASPIRE_ONE),
12047 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12048 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12049 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
12050 SND_PCI_QUIRK(0x103c, 0x30f1, "HP TX25xx series", ALC268_TOSHIBA),
12051 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12052 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
12053 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
12054 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
12055 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12056 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12057 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12058 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12062 static struct alc_config_preset alc268_presets[] = {
12063 [ALC267_QUANTA_IL1] = {
12064 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12065 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12066 alc267_quanta_il1_verbs },
12067 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12068 .dac_nids = alc268_dac_nids,
12069 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12070 .adc_nids = alc268_adc_nids_alt,
12072 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12073 .channel_mode = alc268_modes,
12074 .input_mux = &alc268_capture_source,
12075 .unsol_event = alc267_quanta_il1_unsol_event,
12076 .init_hook = alc267_quanta_il1_init_hook,
12079 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12080 alc268_beep_mixer },
12081 .init_verbs = { alc268_base_init_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,
12086 .capsrc_nids = alc268_capsrc_nids,
12088 .dig_out_nid = ALC268_DIGOUT_NID,
12089 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12090 .channel_mode = alc268_modes,
12091 .input_mux = &alc268_capture_source,
12093 [ALC268_TOSHIBA] = {
12094 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12095 alc268_beep_mixer },
12096 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12097 alc268_toshiba_verbs },
12098 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12099 .dac_nids = alc268_dac_nids,
12100 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12101 .adc_nids = alc268_adc_nids_alt,
12102 .capsrc_nids = alc268_capsrc_nids,
12104 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12105 .channel_mode = alc268_modes,
12106 .input_mux = &alc268_capture_source,
12107 .unsol_event = alc268_toshiba_unsol_event,
12108 .init_hook = alc268_toshiba_init_hook,
12111 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12112 alc268_beep_mixer },
12113 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12114 alc268_acer_verbs },
12115 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12116 .dac_nids = alc268_dac_nids,
12117 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12118 .adc_nids = alc268_adc_nids_alt,
12119 .capsrc_nids = alc268_capsrc_nids,
12121 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12122 .channel_mode = alc268_modes,
12123 .input_mux = &alc268_acer_capture_source,
12124 .unsol_event = alc268_acer_unsol_event,
12125 .init_hook = alc268_acer_init_hook,
12127 [ALC268_ACER_DMIC] = {
12128 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12129 alc268_beep_mixer },
12130 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12131 alc268_acer_verbs },
12132 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12133 .dac_nids = alc268_dac_nids,
12134 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12135 .adc_nids = alc268_adc_nids_alt,
12136 .capsrc_nids = alc268_capsrc_nids,
12138 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12139 .channel_mode = alc268_modes,
12140 .input_mux = &alc268_acer_dmic_capture_source,
12141 .unsol_event = alc268_acer_unsol_event,
12142 .init_hook = alc268_acer_init_hook,
12144 [ALC268_ACER_ASPIRE_ONE] = {
12145 .mixers = { alc268_acer_aspire_one_mixer,
12147 alc268_capture_alt_mixer },
12148 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12149 alc268_acer_aspire_one_verbs },
12150 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12151 .dac_nids = alc268_dac_nids,
12152 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12153 .adc_nids = alc268_adc_nids_alt,
12154 .capsrc_nids = alc268_capsrc_nids,
12156 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12157 .channel_mode = alc268_modes,
12158 .input_mux = &alc268_acer_lc_capture_source,
12159 .unsol_event = alc268_acer_lc_unsol_event,
12160 .init_hook = alc268_acer_lc_init_hook,
12163 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12164 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12165 alc268_dell_verbs },
12166 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12167 .dac_nids = alc268_dac_nids,
12169 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12170 .channel_mode = alc268_modes,
12171 .unsol_event = alc_sku_unsol_event,
12172 .init_hook = alc268_dell_init_hook,
12173 .input_mux = &alc268_capture_source,
12176 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12177 alc268_beep_mixer },
12178 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12179 alc268_toshiba_verbs },
12180 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12181 .dac_nids = alc268_dac_nids,
12182 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12183 .adc_nids = alc268_adc_nids_alt,
12184 .capsrc_nids = alc268_capsrc_nids,
12186 .dig_out_nid = ALC268_DIGOUT_NID,
12187 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12188 .channel_mode = alc268_modes,
12189 .input_mux = &alc268_capture_source,
12190 .unsol_event = alc268_toshiba_unsol_event,
12191 .init_hook = alc268_toshiba_init_hook
12193 #ifdef CONFIG_SND_DEBUG
12195 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12196 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12197 alc268_volume_init_verbs },
12198 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12199 .dac_nids = alc268_dac_nids,
12200 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12201 .adc_nids = alc268_adc_nids_alt,
12202 .capsrc_nids = alc268_capsrc_nids,
12204 .dig_out_nid = ALC268_DIGOUT_NID,
12205 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12206 .channel_mode = alc268_modes,
12207 .input_mux = &alc268_capture_source,
12212 static int patch_alc268(struct hda_codec *codec)
12214 struct alc_spec *spec;
12216 int i, has_beep, err;
12218 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12222 codec->spec = spec;
12224 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12228 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12229 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12230 "trying auto-probe from BIOS...\n", codec->chip_name);
12231 board_config = ALC268_AUTO;
12234 if (board_config == ALC268_AUTO) {
12235 /* automatic parse from the BIOS config */
12236 err = alc268_parse_auto_config(codec);
12242 "hda_codec: Cannot set up configuration "
12243 "from BIOS. Using base mode...\n");
12244 board_config = ALC268_3ST;
12248 if (board_config != ALC268_AUTO)
12249 setup_preset(spec, &alc268_presets[board_config]);
12251 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12252 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12253 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12255 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12258 for (i = 0; i < spec->num_mixers; i++) {
12259 if (spec->mixers[i] == alc268_beep_mixer) {
12266 err = snd_hda_attach_beep_device(codec, 0x1);
12271 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12272 /* override the amp caps for beep generator */
12273 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12274 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12275 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12276 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12277 (0 << AC_AMPCAP_MUTE_SHIFT));
12280 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12281 /* check whether NID 0x07 is valid */
12282 unsigned int wcap = get_wcaps(codec, 0x07);
12286 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12287 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12288 spec->adc_nids = alc268_adc_nids_alt;
12289 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12290 add_mixer(spec, alc268_capture_alt_mixer);
12292 spec->adc_nids = alc268_adc_nids;
12293 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12294 add_mixer(spec, alc268_capture_mixer);
12296 spec->capsrc_nids = alc268_capsrc_nids;
12297 /* set default input source */
12298 for (i = 0; i < spec->num_adc_nids; i++)
12299 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12300 0, AC_VERB_SET_CONNECT_SEL,
12301 spec->input_mux->items[0].index);
12304 spec->vmaster_nid = 0x02;
12306 codec->patch_ops = alc_patch_ops;
12307 if (board_config == ALC268_AUTO)
12308 spec->init_hook = alc268_auto_init;
12310 codec->proc_widget_hook = print_realtek_coef;
12316 * ALC269 channel source setting (2 channel)
12318 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12320 #define alc269_dac_nids alc260_dac_nids
12322 static hda_nid_t alc269_adc_nids[1] = {
12327 static hda_nid_t alc269_capsrc_nids[1] = {
12331 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12335 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12343 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12351 #define alc269_modes alc260_modes
12352 #define alc269_capture_source alc880_lg_lw_capture_source
12354 static struct snd_kcontrol_new alc269_base_mixer[] = {
12355 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12356 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12361 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12362 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12363 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12364 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12366 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12370 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12371 /* output mixer control */
12372 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12374 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12375 .name = "Master Playback Switch",
12376 .info = snd_hda_mixer_amp_switch_info,
12377 .get = snd_hda_mixer_amp_switch_get,
12378 .put = alc268_acer_master_sw_put,
12379 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12384 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12385 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12386 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12390 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12391 /* output mixer control */
12392 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12394 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12395 .name = "Master Playback Switch",
12396 .info = snd_hda_mixer_amp_switch_info,
12397 .get = snd_hda_mixer_amp_switch_get,
12398 .put = alc268_acer_master_sw_put,
12399 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12401 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12402 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12404 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12405 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12406 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12407 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12408 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12409 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12413 /* bind volumes of both NID 0x0c and 0x0d */
12414 static struct hda_bind_ctls alc269_epc_bind_vol = {
12415 .ops = &snd_hda_bind_vol,
12417 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12418 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12423 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12424 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12425 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12426 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12430 /* capture mixer elements */
12431 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12432 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12433 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12434 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12439 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12440 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12441 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12442 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12446 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12447 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12448 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12449 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12450 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12451 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12452 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12456 static struct hda_verb alc269_lifebook_verbs[] = {
12457 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12458 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12459 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12460 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12461 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12463 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12464 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12465 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12466 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12470 /* toggle speaker-output according to the hp-jack state */
12471 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12473 unsigned int present;
12474 unsigned char bits;
12476 present = snd_hda_codec_read(codec, 0x15, 0,
12477 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12478 bits = present ? AMP_IN_MUTE(0) : 0;
12479 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12480 AMP_IN_MUTE(0), bits);
12481 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12482 AMP_IN_MUTE(0), bits);
12484 snd_hda_codec_write(codec, 0x20, 0,
12485 AC_VERB_SET_COEF_INDEX, 0x0c);
12486 snd_hda_codec_write(codec, 0x20, 0,
12487 AC_VERB_SET_PROC_COEF, 0x680);
12489 snd_hda_codec_write(codec, 0x20, 0,
12490 AC_VERB_SET_COEF_INDEX, 0x0c);
12491 snd_hda_codec_write(codec, 0x20, 0,
12492 AC_VERB_SET_PROC_COEF, 0x480);
12495 /* toggle speaker-output according to the hp-jacks state */
12496 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12498 unsigned int present;
12499 unsigned char bits;
12501 /* Check laptop headphone socket */
12502 present = snd_hda_codec_read(codec, 0x15, 0,
12503 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12505 /* Check port replicator headphone socket */
12506 present |= snd_hda_codec_read(codec, 0x1a, 0,
12507 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12509 bits = present ? AMP_IN_MUTE(0) : 0;
12510 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12511 AMP_IN_MUTE(0), bits);
12512 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12513 AMP_IN_MUTE(0), bits);
12515 snd_hda_codec_write(codec, 0x20, 0,
12516 AC_VERB_SET_COEF_INDEX, 0x0c);
12517 snd_hda_codec_write(codec, 0x20, 0,
12518 AC_VERB_SET_PROC_COEF, 0x680);
12520 snd_hda_codec_write(codec, 0x20, 0,
12521 AC_VERB_SET_COEF_INDEX, 0x0c);
12522 snd_hda_codec_write(codec, 0x20, 0,
12523 AC_VERB_SET_PROC_COEF, 0x480);
12526 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12528 unsigned int present;
12530 present = snd_hda_codec_read(codec, 0x18, 0,
12531 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12532 snd_hda_codec_write(codec, 0x23, 0,
12533 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12536 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12538 unsigned int present_laptop;
12539 unsigned int present_dock;
12541 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12542 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12544 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12545 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12547 /* Laptop mic port overrides dock mic port, design decision */
12549 snd_hda_codec_write(codec, 0x23, 0,
12550 AC_VERB_SET_CONNECT_SEL, 0x3);
12551 if (present_laptop)
12552 snd_hda_codec_write(codec, 0x23, 0,
12553 AC_VERB_SET_CONNECT_SEL, 0x0);
12554 if (!present_dock && !present_laptop)
12555 snd_hda_codec_write(codec, 0x23, 0,
12556 AC_VERB_SET_CONNECT_SEL, 0x1);
12559 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12562 if ((res >> 26) == ALC880_HP_EVENT)
12563 alc269_quanta_fl1_speaker_automute(codec);
12564 if ((res >> 26) == ALC880_MIC_EVENT)
12565 alc269_quanta_fl1_mic_automute(codec);
12568 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12571 if ((res >> 26) == ALC880_HP_EVENT)
12572 alc269_lifebook_speaker_automute(codec);
12573 if ((res >> 26) == ALC880_MIC_EVENT)
12574 alc269_lifebook_mic_autoswitch(codec);
12577 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12579 alc269_quanta_fl1_speaker_automute(codec);
12580 alc269_quanta_fl1_mic_automute(codec);
12583 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12585 alc269_lifebook_speaker_automute(codec);
12586 alc269_lifebook_mic_autoswitch(codec);
12589 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12591 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12592 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12593 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12594 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12595 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12596 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12600 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12602 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12603 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12605 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12606 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12610 /* toggle speaker-output according to the hp-jack state */
12611 static void alc269_speaker_automute(struct hda_codec *codec)
12613 unsigned int present;
12614 unsigned char bits;
12616 present = snd_hda_codec_read(codec, 0x15, 0,
12617 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12618 bits = present ? AMP_IN_MUTE(0) : 0;
12619 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12620 AMP_IN_MUTE(0), bits);
12621 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12622 AMP_IN_MUTE(0), bits);
12625 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12627 unsigned int present;
12629 present = snd_hda_codec_read(codec, 0x18, 0,
12630 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12631 snd_hda_codec_write(codec, 0x23, 0,
12632 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12635 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12637 unsigned int present;
12639 present = snd_hda_codec_read(codec, 0x18, 0,
12640 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12641 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12642 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12643 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12644 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12647 /* unsolicited event for HP jack sensing */
12648 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12651 if ((res >> 26) == ALC880_HP_EVENT)
12652 alc269_speaker_automute(codec);
12654 if ((res >> 26) == ALC880_MIC_EVENT)
12655 alc269_eeepc_dmic_automute(codec);
12658 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12660 alc269_speaker_automute(codec);
12661 alc269_eeepc_dmic_automute(codec);
12664 /* unsolicited event for HP jack sensing */
12665 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12668 if ((res >> 26) == ALC880_HP_EVENT)
12669 alc269_speaker_automute(codec);
12671 if ((res >> 26) == ALC880_MIC_EVENT)
12672 alc269_eeepc_amic_automute(codec);
12675 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12677 alc269_speaker_automute(codec);
12678 alc269_eeepc_amic_automute(codec);
12682 * generic initialization of ADC, input mixers and output mixers
12684 static struct hda_verb alc269_init_verbs[] = {
12686 * Unmute ADC0 and set the default input to mic-in
12688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12690 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12691 * analog-loopback mixer widget
12692 * Note: PASD motherboards uses the Line In 2 as the input for
12693 * front panel mic (mic 2)
12695 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12698 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12699 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12700 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12703 * Set up output mixers (0x0c - 0x0e)
12705 /* set vol=0 to output mixers */
12706 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12707 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12709 /* set up input amps for analog loopback */
12710 /* Amp Indices: DAC = 0, mixer = 1 */
12711 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12713 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12714 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12715 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12716 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12718 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12719 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12720 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12721 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12722 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12724 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12727 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12728 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12729 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12731 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12732 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12734 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12735 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12737 /* FIXME: use matrix-type input source selection */
12738 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12739 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12743 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12746 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12747 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12751 /* add playback controls from the parsed DAC table */
12752 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12753 const struct auto_pin_cfg *cfg)
12758 spec->multiout.num_dacs = 1; /* only use one dac */
12759 spec->multiout.dac_nids = spec->private_dac_nids;
12760 spec->multiout.dac_nids[0] = 2;
12762 nid = cfg->line_out_pins[0];
12764 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12765 "Front Playback Volume",
12766 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12769 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12770 "Front Playback Switch",
12771 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12776 nid = cfg->speaker_pins[0];
12778 if (!cfg->line_out_pins[0]) {
12779 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12780 "Speaker Playback Volume",
12781 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12787 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12788 "Speaker Playback Switch",
12789 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12794 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12795 "Speaker Playback Switch",
12796 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12802 nid = cfg->hp_pins[0];
12804 /* spec->multiout.hp_nid = 2; */
12805 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12806 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12807 "Headphone Playback Volume",
12808 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12814 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12815 "Headphone Playback Switch",
12816 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12821 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12822 "Headphone Playback Switch",
12823 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12832 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12833 const struct auto_pin_cfg *cfg)
12837 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12840 /* digital-mic input pin is excluded in alc880_auto_create..()
12841 * because it's under 0x18
12843 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12844 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12845 struct hda_input_mux *imux = &spec->private_imux[0];
12846 imux->items[imux->num_items].label = "Int Mic";
12847 imux->items[imux->num_items].index = 0x05;
12853 #ifdef CONFIG_SND_HDA_POWER_SAVE
12854 #define alc269_loopbacks alc880_loopbacks
12857 /* pcm configuration: identiacal with ALC880 */
12858 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12859 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12860 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12861 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12863 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12867 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12868 /* NID is set in alc_build_pcms */
12870 .open = alc880_playback_pcm_open,
12871 .prepare = alc880_playback_pcm_prepare,
12872 .cleanup = alc880_playback_pcm_cleanup
12876 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12880 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12881 /* NID is set in alc_build_pcms */
12885 * BIOS auto configuration
12887 static int alc269_parse_auto_config(struct hda_codec *codec)
12889 struct alc_spec *spec = codec->spec;
12891 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12893 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12898 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12901 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12905 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12907 if (spec->autocfg.dig_outs)
12908 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12910 if (spec->kctls.list)
12911 add_mixer(spec, spec->kctls.list);
12913 add_verb(spec, alc269_init_verbs);
12914 spec->num_mux_defs = 1;
12915 spec->input_mux = &spec->private_imux[0];
12916 /* set default input source */
12917 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12918 0, AC_VERB_SET_CONNECT_SEL,
12919 spec->input_mux->items[0].index);
12921 err = alc_auto_add_mic_boost(codec);
12925 if (!spec->cap_mixer && !spec->no_analog)
12926 set_capture_mixer(spec);
12931 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12932 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12933 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12936 /* init callback for auto-configuration model -- overriding the default init */
12937 static void alc269_auto_init(struct hda_codec *codec)
12939 struct alc_spec *spec = codec->spec;
12940 alc269_auto_init_multi_out(codec);
12941 alc269_auto_init_hp_out(codec);
12942 alc269_auto_init_analog_input(codec);
12943 if (spec->unsol_event)
12944 alc_inithook(codec);
12948 * configuration and preset
12950 static const char *alc269_models[ALC269_MODEL_LAST] = {
12951 [ALC269_BASIC] = "basic",
12952 [ALC269_QUANTA_FL1] = "quanta",
12953 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12954 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12955 [ALC269_FUJITSU] = "fujitsu",
12956 [ALC269_LIFEBOOK] = "lifebook"
12959 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12960 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12961 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12962 ALC269_ASUS_EEEPC_P703),
12963 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12964 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12965 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12966 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12967 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12968 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12969 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12970 ALC269_ASUS_EEEPC_P901),
12971 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12972 ALC269_ASUS_EEEPC_P901),
12973 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12974 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12975 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12979 static struct alc_config_preset alc269_presets[] = {
12981 .mixers = { alc269_base_mixer },
12982 .init_verbs = { alc269_init_verbs },
12983 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12984 .dac_nids = alc269_dac_nids,
12986 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12987 .channel_mode = alc269_modes,
12988 .input_mux = &alc269_capture_source,
12990 [ALC269_QUANTA_FL1] = {
12991 .mixers = { alc269_quanta_fl1_mixer },
12992 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12993 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12994 .dac_nids = alc269_dac_nids,
12996 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12997 .channel_mode = alc269_modes,
12998 .input_mux = &alc269_capture_source,
12999 .unsol_event = alc269_quanta_fl1_unsol_event,
13000 .init_hook = alc269_quanta_fl1_init_hook,
13002 [ALC269_ASUS_EEEPC_P703] = {
13003 .mixers = { alc269_eeepc_mixer },
13004 .cap_mixer = alc269_epc_capture_mixer,
13005 .init_verbs = { alc269_init_verbs,
13006 alc269_eeepc_amic_init_verbs },
13007 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13008 .dac_nids = alc269_dac_nids,
13010 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13011 .channel_mode = alc269_modes,
13012 .input_mux = &alc269_eeepc_amic_capture_source,
13013 .unsol_event = alc269_eeepc_amic_unsol_event,
13014 .init_hook = alc269_eeepc_amic_inithook,
13016 [ALC269_ASUS_EEEPC_P901] = {
13017 .mixers = { alc269_eeepc_mixer },
13018 .cap_mixer = alc269_epc_capture_mixer,
13019 .init_verbs = { alc269_init_verbs,
13020 alc269_eeepc_dmic_init_verbs },
13021 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13022 .dac_nids = alc269_dac_nids,
13024 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13025 .channel_mode = alc269_modes,
13026 .input_mux = &alc269_eeepc_dmic_capture_source,
13027 .unsol_event = alc269_eeepc_dmic_unsol_event,
13028 .init_hook = alc269_eeepc_dmic_inithook,
13030 [ALC269_FUJITSU] = {
13031 .mixers = { alc269_fujitsu_mixer },
13032 .cap_mixer = alc269_epc_capture_mixer,
13033 .init_verbs = { alc269_init_verbs,
13034 alc269_eeepc_dmic_init_verbs },
13035 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13036 .dac_nids = alc269_dac_nids,
13038 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13039 .channel_mode = alc269_modes,
13040 .input_mux = &alc269_eeepc_dmic_capture_source,
13041 .unsol_event = alc269_eeepc_dmic_unsol_event,
13042 .init_hook = alc269_eeepc_dmic_inithook,
13044 [ALC269_LIFEBOOK] = {
13045 .mixers = { alc269_lifebook_mixer },
13046 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13047 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13048 .dac_nids = alc269_dac_nids,
13050 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13051 .channel_mode = alc269_modes,
13052 .input_mux = &alc269_capture_source,
13053 .unsol_event = alc269_lifebook_unsol_event,
13054 .init_hook = alc269_lifebook_init_hook,
13058 static int patch_alc269(struct hda_codec *codec)
13060 struct alc_spec *spec;
13064 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13068 codec->spec = spec;
13070 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13072 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13076 if (board_config < 0) {
13077 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13078 "trying auto-probe from BIOS...\n", codec->chip_name);
13079 board_config = ALC269_AUTO;
13082 if (board_config == ALC269_AUTO) {
13083 /* automatic parse from the BIOS config */
13084 err = alc269_parse_auto_config(codec);
13090 "hda_codec: Cannot set up configuration "
13091 "from BIOS. Using base mode...\n");
13092 board_config = ALC269_BASIC;
13096 err = snd_hda_attach_beep_device(codec, 0x1);
13102 if (board_config != ALC269_AUTO)
13103 setup_preset(spec, &alc269_presets[board_config]);
13105 if (codec->subsystem_id == 0x17aa3bf8) {
13106 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13107 * fix the sample rate of analog I/O to 44.1kHz
13109 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13110 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13112 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13113 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13115 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13116 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13118 spec->adc_nids = alc269_adc_nids;
13119 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13120 spec->capsrc_nids = alc269_capsrc_nids;
13121 if (!spec->cap_mixer)
13122 set_capture_mixer(spec);
13123 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13125 codec->patch_ops = alc_patch_ops;
13126 if (board_config == ALC269_AUTO)
13127 spec->init_hook = alc269_auto_init;
13128 #ifdef CONFIG_SND_HDA_POWER_SAVE
13129 if (!spec->loopback.amplist)
13130 spec->loopback.amplist = alc269_loopbacks;
13132 codec->proc_widget_hook = print_realtek_coef;
13138 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13142 * set the path ways for 2 channel output
13143 * need to set the codec line out and mic 1 pin widgets to inputs
13145 static struct hda_verb alc861_threestack_ch2_init[] = {
13146 /* set pin widget 1Ah (line in) for input */
13147 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13148 /* set pin widget 18h (mic1/2) for input, for mic also enable
13151 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13153 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13155 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13156 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13162 * need to set the codec line out and mic 1 pin widgets to outputs
13164 static struct hda_verb alc861_threestack_ch6_init[] = {
13165 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13166 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13167 /* set pin widget 18h (mic1) for output (CLFE)*/
13168 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13170 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13171 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13173 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13175 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13176 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13181 static struct hda_channel_mode alc861_threestack_modes[2] = {
13182 { 2, alc861_threestack_ch2_init },
13183 { 6, alc861_threestack_ch6_init },
13185 /* Set mic1 as input and unmute the mixer */
13186 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13187 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13188 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13191 /* Set mic1 as output and mute mixer */
13192 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13193 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13194 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13198 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13199 { 2, alc861_uniwill_m31_ch2_init },
13200 { 4, alc861_uniwill_m31_ch4_init },
13203 /* Set mic1 and line-in as input and unmute the mixer */
13204 static struct hda_verb alc861_asus_ch2_init[] = {
13205 /* set pin widget 1Ah (line in) for input */
13206 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13207 /* set pin widget 18h (mic1/2) for input, for mic also enable
13210 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13212 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13214 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13215 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13219 /* Set mic1 nad line-in as output and mute mixer */
13220 static struct hda_verb alc861_asus_ch6_init[] = {
13221 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13222 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13223 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13224 /* set pin widget 18h (mic1) for output (CLFE)*/
13225 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13226 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13227 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13228 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13230 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13232 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13233 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13238 static struct hda_channel_mode alc861_asus_modes[2] = {
13239 { 2, alc861_asus_ch2_init },
13240 { 6, alc861_asus_ch6_init },
13245 static struct snd_kcontrol_new alc861_base_mixer[] = {
13246 /* output mixer control */
13247 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13248 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13249 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13250 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13251 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13253 /*Input mixer control */
13254 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13255 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13256 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13257 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13258 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13259 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13260 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13261 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13262 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13268 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13269 /* output mixer control */
13270 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13271 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13272 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13273 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13274 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13276 /* Input mixer control */
13277 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13278 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13279 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13280 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13281 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13282 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13283 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13284 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13285 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13289 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13290 .name = "Channel Mode",
13291 .info = alc_ch_mode_info,
13292 .get = alc_ch_mode_get,
13293 .put = alc_ch_mode_put,
13294 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13299 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13300 /* output mixer control */
13301 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13303 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13308 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13309 /* output mixer control */
13310 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13311 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13312 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13313 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13314 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13316 /* Input mixer control */
13317 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13318 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13319 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13320 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13321 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13322 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13324 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13325 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13329 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13330 .name = "Channel Mode",
13331 .info = alc_ch_mode_info,
13332 .get = alc_ch_mode_get,
13333 .put = alc_ch_mode_put,
13334 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13339 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13340 /* output mixer control */
13341 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13342 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13343 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13344 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13345 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13347 /* Input mixer control */
13348 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13349 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13350 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13351 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13352 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13353 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13354 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13355 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13356 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13357 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13360 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13361 .name = "Channel Mode",
13362 .info = alc_ch_mode_info,
13363 .get = alc_ch_mode_get,
13364 .put = alc_ch_mode_put,
13365 .private_value = ARRAY_SIZE(alc861_asus_modes),
13370 /* additional mixer */
13371 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13372 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13373 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13378 * generic initialization of ADC, input mixers and output mixers
13380 static struct hda_verb alc861_base_init_verbs[] = {
13382 * Unmute ADC0 and set the default input to mic-in
13384 /* port-A for surround (rear panel) */
13385 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13386 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13387 /* port-B for mic-in (rear panel) with vref */
13388 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13389 /* port-C for line-in (rear panel) */
13390 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13391 /* port-D for Front */
13392 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13393 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13394 /* port-E for HP out (front panel) */
13395 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13396 /* route front PCM to HP */
13397 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13398 /* port-F for mic-in (front panel) with vref */
13399 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13400 /* port-G for CLFE (rear panel) */
13401 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13402 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13403 /* port-H for side (rear panel) */
13404 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13405 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13407 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13408 /* route front mic to ADC1*/
13409 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13412 /* Unmute DAC0~3 & spdif out*/
13413 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13414 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13415 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13416 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13419 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13420 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13421 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13422 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13423 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13425 /* Unmute Stereo Mixer 15 */
13426 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13427 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13428 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13431 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13432 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13433 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13434 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13435 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13436 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13437 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13438 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13439 /* hp used DAC 3 (Front) */
13440 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13441 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13446 static struct hda_verb alc861_threestack_init_verbs[] = {
13448 * Unmute ADC0 and set the default input to mic-in
13450 /* port-A for surround (rear panel) */
13451 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13452 /* port-B for mic-in (rear panel) with vref */
13453 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13454 /* port-C for line-in (rear panel) */
13455 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13456 /* port-D for Front */
13457 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13458 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13459 /* port-E for HP out (front panel) */
13460 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13461 /* route front PCM to HP */
13462 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13463 /* port-F for mic-in (front panel) with vref */
13464 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13465 /* port-G for CLFE (rear panel) */
13466 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13467 /* port-H for side (rear panel) */
13468 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13470 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13471 /* route front mic to ADC1*/
13472 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13473 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13474 /* Unmute DAC0~3 & spdif out*/
13475 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13476 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13477 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13478 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13481 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13482 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13483 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13484 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13485 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13487 /* Unmute Stereo Mixer 15 */
13488 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13490 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13491 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13493 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13494 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13495 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13496 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13497 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13498 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13499 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13500 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13501 /* hp used DAC 3 (Front) */
13502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13507 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13509 * Unmute ADC0 and set the default input to mic-in
13511 /* port-A for surround (rear panel) */
13512 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13513 /* port-B for mic-in (rear panel) with vref */
13514 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13515 /* port-C for line-in (rear panel) */
13516 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13517 /* port-D for Front */
13518 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13519 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13520 /* port-E for HP out (front panel) */
13521 /* this has to be set to VREF80 */
13522 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13523 /* route front PCM to HP */
13524 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13525 /* port-F for mic-in (front panel) with vref */
13526 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13527 /* port-G for CLFE (rear panel) */
13528 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13529 /* port-H for side (rear panel) */
13530 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13532 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13533 /* route front mic to ADC1*/
13534 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13536 /* Unmute DAC0~3 & spdif out*/
13537 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13538 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13539 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13540 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13541 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13543 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13544 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13545 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13546 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13547 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13549 /* Unmute Stereo Mixer 15 */
13550 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13551 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13553 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13555 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13556 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13557 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13558 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13559 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13561 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13562 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13563 /* hp used DAC 3 (Front) */
13564 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13565 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13569 static struct hda_verb alc861_asus_init_verbs[] = {
13571 * Unmute ADC0 and set the default input to mic-in
13573 /* port-A for surround (rear panel)
13574 * according to codec#0 this is the HP jack
13576 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13577 /* route front PCM to HP */
13578 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13579 /* port-B for mic-in (rear panel) with vref */
13580 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13581 /* port-C for line-in (rear panel) */
13582 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13583 /* port-D for Front */
13584 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13585 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13586 /* port-E for HP out (front panel) */
13587 /* this has to be set to VREF80 */
13588 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13589 /* route front PCM to HP */
13590 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13591 /* port-F for mic-in (front panel) with vref */
13592 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13593 /* port-G for CLFE (rear panel) */
13594 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13595 /* port-H for side (rear panel) */
13596 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13598 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13599 /* route front mic to ADC1*/
13600 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13601 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13602 /* Unmute DAC0~3 & spdif out*/
13603 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13604 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13605 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13606 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13607 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13608 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13609 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13610 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13611 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13612 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13614 /* Unmute Stereo Mixer 15 */
13615 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13616 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13617 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13618 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13620 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13621 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13622 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13623 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13624 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13626 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13627 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13628 /* hp used DAC 3 (Front) */
13629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13634 /* additional init verbs for ASUS laptops */
13635 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13636 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13637 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13642 * generic initialization of ADC, input mixers and output mixers
13644 static struct hda_verb alc861_auto_init_verbs[] = {
13646 * Unmute ADC0 and set the default input to mic-in
13648 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13649 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13651 /* Unmute DAC0~3 & spdif out*/
13652 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13653 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13654 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13655 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13656 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13658 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13659 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13660 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13661 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13662 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13664 /* Unmute Stereo Mixer 15 */
13665 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13666 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13668 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13670 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13671 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13672 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13673 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13674 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13675 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13676 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13677 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13679 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13680 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13682 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13683 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13684 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13685 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13686 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13688 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13693 static struct hda_verb alc861_toshiba_init_verbs[] = {
13694 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13699 /* toggle speaker-output according to the hp-jack state */
13700 static void alc861_toshiba_automute(struct hda_codec *codec)
13702 unsigned int present;
13704 present = snd_hda_codec_read(codec, 0x0f, 0,
13705 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13706 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13707 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13708 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13709 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13712 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13715 if ((res >> 26) == ALC880_HP_EVENT)
13716 alc861_toshiba_automute(codec);
13719 /* pcm configuration: identiacal with ALC880 */
13720 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13721 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13722 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13723 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13726 #define ALC861_DIGOUT_NID 0x07
13728 static struct hda_channel_mode alc861_8ch_modes[1] = {
13732 static hda_nid_t alc861_dac_nids[4] = {
13733 /* front, surround, clfe, side */
13734 0x03, 0x06, 0x05, 0x04
13737 static hda_nid_t alc660_dac_nids[3] = {
13738 /* front, clfe, surround */
13742 static hda_nid_t alc861_adc_nids[1] = {
13747 static struct hda_input_mux alc861_capture_source = {
13751 { "Front Mic", 0x3 },
13758 /* fill in the dac_nids table from the parsed pin configuration */
13759 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13760 const struct auto_pin_cfg *cfg)
13765 spec->multiout.dac_nids = spec->private_dac_nids;
13766 for (i = 0; i < cfg->line_outs; i++) {
13767 nid = cfg->line_out_pins[i];
13769 if (i >= ARRAY_SIZE(alc861_dac_nids))
13771 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13774 spec->multiout.num_dacs = cfg->line_outs;
13778 /* add playback controls from the parsed DAC table */
13779 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13780 const struct auto_pin_cfg *cfg)
13783 static const char *chname[4] = {
13784 "Front", "Surround", NULL /*CLFE*/, "Side"
13789 for (i = 0; i < cfg->line_outs; i++) {
13790 nid = spec->multiout.dac_nids[i];
13795 err = add_control(spec, ALC_CTL_BIND_MUTE,
13796 "Center Playback Switch",
13797 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13801 err = add_control(spec, ALC_CTL_BIND_MUTE,
13802 "LFE Playback Switch",
13803 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13808 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13810 if (nid == alc861_dac_nids[idx])
13812 sprintf(name, "%s Playback Switch", chname[idx]);
13813 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13814 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13823 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13831 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13833 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13834 "Headphone Playback Switch",
13835 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13838 spec->multiout.hp_nid = nid;
13843 /* create playback/capture controls for input pins */
13844 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13845 const struct auto_pin_cfg *cfg)
13847 struct hda_input_mux *imux = &spec->private_imux[0];
13848 int i, err, idx, idx1;
13850 for (i = 0; i < AUTO_PIN_LAST; i++) {
13851 switch (cfg->input_pins[i]) {
13854 idx = 2; /* Line In */
13858 idx = 2; /* Line In */
13862 idx = 1; /* Mic In */
13866 idx = 1; /* Mic In */
13876 err = new_analog_input(spec, cfg->input_pins[i],
13877 auto_pin_cfg_labels[i], idx, 0x15);
13881 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13882 imux->items[imux->num_items].index = idx1;
13888 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13890 int pin_type, int dac_idx)
13892 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13894 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13898 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13900 struct alc_spec *spec = codec->spec;
13903 for (i = 0; i < spec->autocfg.line_outs; i++) {
13904 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13905 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13907 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13908 spec->multiout.dac_nids[i]);
13912 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13914 struct alc_spec *spec = codec->spec;
13917 pin = spec->autocfg.hp_pins[0];
13918 if (pin) /* connect to front */
13919 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13920 spec->multiout.dac_nids[0]);
13921 pin = spec->autocfg.speaker_pins[0];
13923 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13926 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13928 struct alc_spec *spec = codec->spec;
13931 for (i = 0; i < AUTO_PIN_LAST; i++) {
13932 hda_nid_t nid = spec->autocfg.input_pins[i];
13933 if (nid >= 0x0c && nid <= 0x11)
13934 alc_set_input_pin(codec, nid, i);
13938 /* parse the BIOS configuration and set up the alc_spec */
13939 /* return 1 if successful, 0 if the proper config is not found,
13940 * or a negative error code
13942 static int alc861_parse_auto_config(struct hda_codec *codec)
13944 struct alc_spec *spec = codec->spec;
13946 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13948 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13952 if (!spec->autocfg.line_outs)
13953 return 0; /* can't find valid BIOS pin config */
13955 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13958 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13961 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13964 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13968 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13970 if (spec->autocfg.dig_outs)
13971 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13973 if (spec->kctls.list)
13974 add_mixer(spec, spec->kctls.list);
13976 add_verb(spec, alc861_auto_init_verbs);
13978 spec->num_mux_defs = 1;
13979 spec->input_mux = &spec->private_imux[0];
13981 spec->adc_nids = alc861_adc_nids;
13982 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13983 set_capture_mixer(spec);
13985 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
13990 /* additional initialization for auto-configuration model */
13991 static void alc861_auto_init(struct hda_codec *codec)
13993 struct alc_spec *spec = codec->spec;
13994 alc861_auto_init_multi_out(codec);
13995 alc861_auto_init_hp_out(codec);
13996 alc861_auto_init_analog_input(codec);
13997 if (spec->unsol_event)
13998 alc_inithook(codec);
14001 #ifdef CONFIG_SND_HDA_POWER_SAVE
14002 static struct hda_amp_list alc861_loopbacks[] = {
14003 { 0x15, HDA_INPUT, 0 },
14004 { 0x15, HDA_INPUT, 1 },
14005 { 0x15, HDA_INPUT, 2 },
14006 { 0x15, HDA_INPUT, 3 },
14013 * configuration and preset
14015 static const char *alc861_models[ALC861_MODEL_LAST] = {
14016 [ALC861_3ST] = "3stack",
14017 [ALC660_3ST] = "3stack-660",
14018 [ALC861_3ST_DIG] = "3stack-dig",
14019 [ALC861_6ST_DIG] = "6stack-dig",
14020 [ALC861_UNIWILL_M31] = "uniwill-m31",
14021 [ALC861_TOSHIBA] = "toshiba",
14022 [ALC861_ASUS] = "asus",
14023 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14024 [ALC861_AUTO] = "auto",
14027 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14028 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14029 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14030 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14031 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14032 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14033 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14034 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14035 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14036 * Any other models that need this preset?
14038 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14039 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14040 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14041 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14042 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14043 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14044 /* FIXME: the below seems conflict */
14045 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14046 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14047 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14051 static struct alc_config_preset alc861_presets[] = {
14053 .mixers = { alc861_3ST_mixer },
14054 .init_verbs = { alc861_threestack_init_verbs },
14055 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14056 .dac_nids = alc861_dac_nids,
14057 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14058 .channel_mode = alc861_threestack_modes,
14060 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14061 .adc_nids = alc861_adc_nids,
14062 .input_mux = &alc861_capture_source,
14064 [ALC861_3ST_DIG] = {
14065 .mixers = { alc861_base_mixer },
14066 .init_verbs = { alc861_threestack_init_verbs },
14067 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14068 .dac_nids = alc861_dac_nids,
14069 .dig_out_nid = ALC861_DIGOUT_NID,
14070 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14071 .channel_mode = alc861_threestack_modes,
14073 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14074 .adc_nids = alc861_adc_nids,
14075 .input_mux = &alc861_capture_source,
14077 [ALC861_6ST_DIG] = {
14078 .mixers = { alc861_base_mixer },
14079 .init_verbs = { alc861_base_init_verbs },
14080 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14081 .dac_nids = alc861_dac_nids,
14082 .dig_out_nid = ALC861_DIGOUT_NID,
14083 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14084 .channel_mode = alc861_8ch_modes,
14085 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14086 .adc_nids = alc861_adc_nids,
14087 .input_mux = &alc861_capture_source,
14090 .mixers = { alc861_3ST_mixer },
14091 .init_verbs = { alc861_threestack_init_verbs },
14092 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14093 .dac_nids = alc660_dac_nids,
14094 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14095 .channel_mode = alc861_threestack_modes,
14097 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14098 .adc_nids = alc861_adc_nids,
14099 .input_mux = &alc861_capture_source,
14101 [ALC861_UNIWILL_M31] = {
14102 .mixers = { alc861_uniwill_m31_mixer },
14103 .init_verbs = { alc861_uniwill_m31_init_verbs },
14104 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14105 .dac_nids = alc861_dac_nids,
14106 .dig_out_nid = ALC861_DIGOUT_NID,
14107 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14108 .channel_mode = alc861_uniwill_m31_modes,
14110 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14111 .adc_nids = alc861_adc_nids,
14112 .input_mux = &alc861_capture_source,
14114 [ALC861_TOSHIBA] = {
14115 .mixers = { alc861_toshiba_mixer },
14116 .init_verbs = { alc861_base_init_verbs,
14117 alc861_toshiba_init_verbs },
14118 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14119 .dac_nids = alc861_dac_nids,
14120 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14121 .channel_mode = alc883_3ST_2ch_modes,
14122 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14123 .adc_nids = alc861_adc_nids,
14124 .input_mux = &alc861_capture_source,
14125 .unsol_event = alc861_toshiba_unsol_event,
14126 .init_hook = alc861_toshiba_automute,
14129 .mixers = { alc861_asus_mixer },
14130 .init_verbs = { alc861_asus_init_verbs },
14131 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14132 .dac_nids = alc861_dac_nids,
14133 .dig_out_nid = ALC861_DIGOUT_NID,
14134 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14135 .channel_mode = alc861_asus_modes,
14138 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14139 .adc_nids = alc861_adc_nids,
14140 .input_mux = &alc861_capture_source,
14142 [ALC861_ASUS_LAPTOP] = {
14143 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14144 .init_verbs = { alc861_asus_init_verbs,
14145 alc861_asus_laptop_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(alc883_3ST_2ch_modes),
14150 .channel_mode = alc883_3ST_2ch_modes,
14152 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14153 .adc_nids = alc861_adc_nids,
14154 .input_mux = &alc861_capture_source,
14159 static int patch_alc861(struct hda_codec *codec)
14161 struct alc_spec *spec;
14165 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14169 codec->spec = spec;
14171 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14175 if (board_config < 0) {
14176 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14177 "trying auto-probe from BIOS...\n", codec->chip_name);
14178 board_config = ALC861_AUTO;
14181 if (board_config == ALC861_AUTO) {
14182 /* automatic parse from the BIOS config */
14183 err = alc861_parse_auto_config(codec);
14189 "hda_codec: Cannot set up configuration "
14190 "from BIOS. Using base mode...\n");
14191 board_config = ALC861_3ST_DIG;
14195 err = snd_hda_attach_beep_device(codec, 0x23);
14201 if (board_config != ALC861_AUTO)
14202 setup_preset(spec, &alc861_presets[board_config]);
14204 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14205 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14207 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14208 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14210 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14212 spec->vmaster_nid = 0x03;
14214 codec->patch_ops = alc_patch_ops;
14215 if (board_config == ALC861_AUTO)
14216 spec->init_hook = alc861_auto_init;
14217 #ifdef CONFIG_SND_HDA_POWER_SAVE
14218 if (!spec->loopback.amplist)
14219 spec->loopback.amplist = alc861_loopbacks;
14221 codec->proc_widget_hook = print_realtek_coef;
14227 * ALC861-VD support
14231 * In addition, an independent DAC
14233 #define ALC861VD_DIGOUT_NID 0x06
14235 static hda_nid_t alc861vd_dac_nids[4] = {
14236 /* front, surr, clfe, side surr */
14237 0x02, 0x03, 0x04, 0x05
14240 /* dac_nids for ALC660vd are in a different order - according to
14241 * Realtek's driver.
14242 * This should probably tesult in a different mixer for 6stack models
14243 * of ALC660vd codecs, but for now there is only 3stack mixer
14244 * - and it is the same as in 861vd.
14245 * adc_nids in ALC660vd are (is) the same as in 861vd
14247 static hda_nid_t alc660vd_dac_nids[3] = {
14248 /* front, rear, clfe, rear_surr */
14252 static hda_nid_t alc861vd_adc_nids[1] = {
14257 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14260 /* FIXME: should be a matrix-type input source selection */
14261 static struct hda_input_mux alc861vd_capture_source = {
14265 { "Front Mic", 0x1 },
14271 static struct hda_input_mux alc861vd_dallas_capture_source = {
14274 { "Ext Mic", 0x0 },
14275 { "Int Mic", 0x1 },
14279 static struct hda_input_mux alc861vd_hp_capture_source = {
14282 { "Front Mic", 0x0 },
14283 { "ATAPI Mic", 0x1 },
14290 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14297 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14298 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14299 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14300 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14301 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14308 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14309 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14310 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14311 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14312 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14316 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14317 { 6, alc861vd_6stack_ch6_init },
14318 { 8, alc861vd_6stack_ch8_init },
14321 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14324 .name = "Channel Mode",
14325 .info = alc_ch_mode_info,
14326 .get = alc_ch_mode_get,
14327 .put = alc_ch_mode_put,
14332 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14333 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14335 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14336 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14337 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14339 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14340 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14342 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14344 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14346 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14347 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14349 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14350 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14354 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14355 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14356 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14358 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14359 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14360 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14362 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14363 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14365 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14366 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14371 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14372 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14373 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14377 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14378 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14379 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14381 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14382 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14388 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14389 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14394 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14395 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14396 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14397 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14401 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14405 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14409 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14410 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14415 /* Pin assignment: Speaker=0x14, HP = 0x15,
14416 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14418 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14419 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14420 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14421 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14422 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14423 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14424 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14425 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14426 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14427 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14428 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14432 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14433 * Front Mic=0x18, ATAPI Mic = 0x19,
14435 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14436 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14437 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14439 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14440 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14441 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14442 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14443 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14449 * generic initialization of ADC, input mixers and output mixers
14451 static struct hda_verb alc861vd_volume_init_verbs[] = {
14453 * Unmute ADC0 and set the default input to mic-in
14455 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14456 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14458 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14459 * the analog-loopback mixer widget
14461 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14462 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14463 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14464 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14465 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14466 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14468 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14475 * Set up output mixers (0x02 - 0x05)
14477 /* set vol=0 to output mixers */
14478 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14479 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14480 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14481 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14483 /* set up input amps for analog loopback */
14484 /* Amp Indices: DAC = 0, mixer = 1 */
14485 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14487 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14488 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14491 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14492 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14498 * 3-stack pin configuration:
14499 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14501 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14503 * Set pin mode and muting
14505 /* set front pin widgets 0x14 for output */
14506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14507 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14508 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14510 /* Mic (rear) pin: input vref at 80% */
14511 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14512 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14513 /* Front Mic pin: input vref at 80% */
14514 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14516 /* Line In pin: input */
14517 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14519 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14520 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14521 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14522 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14523 /* CD pin widget for input */
14524 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14530 * 6-stack pin configuration:
14532 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14534 * Set pin mode and muting
14536 /* set front pin widgets 0x14 for output */
14537 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14539 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14541 /* Rear Pin: output 1 (0x0d) */
14542 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14545 /* CLFE Pin: output 2 (0x0e) */
14546 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14547 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14548 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14549 /* Side Pin: output 3 (0x0f) */
14550 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14551 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14552 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14554 /* Mic (rear) pin: input vref at 80% */
14555 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14556 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14557 /* Front Mic pin: input vref at 80% */
14558 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14559 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14560 /* Line In pin: input */
14561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14562 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14563 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14564 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14565 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14566 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14567 /* CD pin widget for input */
14568 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14573 static struct hda_verb alc861vd_eapd_verbs[] = {
14574 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14578 static struct hda_verb alc660vd_eapd_verbs[] = {
14579 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14580 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14584 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14585 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14586 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14587 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14588 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14589 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14593 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14595 unsigned int present;
14596 unsigned char bits;
14598 present = snd_hda_codec_read(codec, 0x18, 0,
14599 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14600 bits = present ? HDA_AMP_MUTE : 0;
14601 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14602 HDA_AMP_MUTE, bits);
14605 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14607 struct alc_spec *spec = codec->spec;
14609 spec->autocfg.hp_pins[0] = 0x1b;
14610 spec->autocfg.speaker_pins[0] = 0x14;
14611 alc_automute_amp(codec);
14612 alc861vd_lenovo_mic_automute(codec);
14615 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14618 switch (res >> 26) {
14619 case ALC880_MIC_EVENT:
14620 alc861vd_lenovo_mic_automute(codec);
14623 alc_automute_amp_unsol_event(codec, res);
14628 static struct hda_verb alc861vd_dallas_verbs[] = {
14629 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14630 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14631 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14632 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14637 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14638 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14639 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14640 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14641 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14643 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14644 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14645 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14646 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14647 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14648 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14649 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14650 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14652 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14653 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14654 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14655 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14656 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14657 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14658 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14659 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14661 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14666 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14667 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14668 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14673 /* toggle speaker-output according to the hp-jack state */
14674 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14676 struct alc_spec *spec = codec->spec;
14678 spec->autocfg.hp_pins[0] = 0x15;
14679 spec->autocfg.speaker_pins[0] = 0x14;
14680 alc_automute_amp(codec);
14683 #ifdef CONFIG_SND_HDA_POWER_SAVE
14684 #define alc861vd_loopbacks alc880_loopbacks
14687 /* pcm configuration: identiacal with ALC880 */
14688 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14689 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14690 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14691 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14694 * configuration and preset
14696 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14697 [ALC660VD_3ST] = "3stack-660",
14698 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14699 [ALC660VD_ASUS_V1S] = "asus-v1s",
14700 [ALC861VD_3ST] = "3stack",
14701 [ALC861VD_3ST_DIG] = "3stack-digout",
14702 [ALC861VD_6ST_DIG] = "6stack-digout",
14703 [ALC861VD_LENOVO] = "lenovo",
14704 [ALC861VD_DALLAS] = "dallas",
14705 [ALC861VD_HP] = "hp",
14706 [ALC861VD_AUTO] = "auto",
14709 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14710 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14711 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14712 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14713 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14714 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14715 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14716 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14717 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14718 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14719 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14720 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14721 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14722 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14723 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14724 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14728 static struct alc_config_preset alc861vd_presets[] = {
14730 .mixers = { alc861vd_3st_mixer },
14731 .init_verbs = { alc861vd_volume_init_verbs,
14732 alc861vd_3stack_init_verbs },
14733 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14734 .dac_nids = alc660vd_dac_nids,
14735 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14736 .channel_mode = alc861vd_3stack_2ch_modes,
14737 .input_mux = &alc861vd_capture_source,
14739 [ALC660VD_3ST_DIG] = {
14740 .mixers = { alc861vd_3st_mixer },
14741 .init_verbs = { alc861vd_volume_init_verbs,
14742 alc861vd_3stack_init_verbs },
14743 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14744 .dac_nids = alc660vd_dac_nids,
14745 .dig_out_nid = ALC861VD_DIGOUT_NID,
14746 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14747 .channel_mode = alc861vd_3stack_2ch_modes,
14748 .input_mux = &alc861vd_capture_source,
14751 .mixers = { alc861vd_3st_mixer },
14752 .init_verbs = { alc861vd_volume_init_verbs,
14753 alc861vd_3stack_init_verbs },
14754 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14755 .dac_nids = alc861vd_dac_nids,
14756 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14757 .channel_mode = alc861vd_3stack_2ch_modes,
14758 .input_mux = &alc861vd_capture_source,
14760 [ALC861VD_3ST_DIG] = {
14761 .mixers = { alc861vd_3st_mixer },
14762 .init_verbs = { alc861vd_volume_init_verbs,
14763 alc861vd_3stack_init_verbs },
14764 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14765 .dac_nids = alc861vd_dac_nids,
14766 .dig_out_nid = ALC861VD_DIGOUT_NID,
14767 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14768 .channel_mode = alc861vd_3stack_2ch_modes,
14769 .input_mux = &alc861vd_capture_source,
14771 [ALC861VD_6ST_DIG] = {
14772 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14773 .init_verbs = { alc861vd_volume_init_verbs,
14774 alc861vd_6stack_init_verbs },
14775 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14776 .dac_nids = alc861vd_dac_nids,
14777 .dig_out_nid = ALC861VD_DIGOUT_NID,
14778 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14779 .channel_mode = alc861vd_6stack_modes,
14780 .input_mux = &alc861vd_capture_source,
14782 [ALC861VD_LENOVO] = {
14783 .mixers = { alc861vd_lenovo_mixer },
14784 .init_verbs = { alc861vd_volume_init_verbs,
14785 alc861vd_3stack_init_verbs,
14786 alc861vd_eapd_verbs,
14787 alc861vd_lenovo_unsol_verbs },
14788 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14789 .dac_nids = alc660vd_dac_nids,
14790 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14791 .channel_mode = alc861vd_3stack_2ch_modes,
14792 .input_mux = &alc861vd_capture_source,
14793 .unsol_event = alc861vd_lenovo_unsol_event,
14794 .init_hook = alc861vd_lenovo_init_hook,
14796 [ALC861VD_DALLAS] = {
14797 .mixers = { alc861vd_dallas_mixer },
14798 .init_verbs = { alc861vd_dallas_verbs },
14799 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14800 .dac_nids = alc861vd_dac_nids,
14801 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14802 .channel_mode = alc861vd_3stack_2ch_modes,
14803 .input_mux = &alc861vd_dallas_capture_source,
14804 .unsol_event = alc_automute_amp_unsol_event,
14805 .init_hook = alc861vd_dallas_init_hook,
14808 .mixers = { alc861vd_hp_mixer },
14809 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14810 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14811 .dac_nids = alc861vd_dac_nids,
14812 .dig_out_nid = ALC861VD_DIGOUT_NID,
14813 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14814 .channel_mode = alc861vd_3stack_2ch_modes,
14815 .input_mux = &alc861vd_hp_capture_source,
14816 .unsol_event = alc_automute_amp_unsol_event,
14817 .init_hook = alc861vd_dallas_init_hook,
14819 [ALC660VD_ASUS_V1S] = {
14820 .mixers = { alc861vd_lenovo_mixer },
14821 .init_verbs = { alc861vd_volume_init_verbs,
14822 alc861vd_3stack_init_verbs,
14823 alc861vd_eapd_verbs,
14824 alc861vd_lenovo_unsol_verbs },
14825 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14826 .dac_nids = alc660vd_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_capture_source,
14831 .unsol_event = alc861vd_lenovo_unsol_event,
14832 .init_hook = alc861vd_lenovo_init_hook,
14837 * BIOS auto configuration
14839 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14840 hda_nid_t nid, int pin_type, int dac_idx)
14842 alc_set_pin_output(codec, nid, pin_type);
14845 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14847 struct alc_spec *spec = codec->spec;
14850 for (i = 0; i <= HDA_SIDE; i++) {
14851 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14852 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14854 alc861vd_auto_set_output_and_unmute(codec, nid,
14860 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14862 struct alc_spec *spec = codec->spec;
14865 pin = spec->autocfg.hp_pins[0];
14866 if (pin) /* connect to front and use dac 0 */
14867 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14868 pin = spec->autocfg.speaker_pins[0];
14870 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14873 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14874 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14876 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14878 struct alc_spec *spec = codec->spec;
14881 for (i = 0; i < AUTO_PIN_LAST; i++) {
14882 hda_nid_t nid = spec->autocfg.input_pins[i];
14883 if (alc861vd_is_input_pin(nid)) {
14884 alc_set_input_pin(codec, nid, i);
14885 if (nid != ALC861VD_PIN_CD_NID &&
14886 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14887 snd_hda_codec_write(codec, nid, 0,
14888 AC_VERB_SET_AMP_GAIN_MUTE,
14894 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14896 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14897 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14899 /* add playback controls from the parsed DAC table */
14900 /* Based on ALC880 version. But ALC861VD has separate,
14901 * different NIDs for mute/unmute switch and volume control */
14902 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14903 const struct auto_pin_cfg *cfg)
14906 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14907 hda_nid_t nid_v, nid_s;
14910 for (i = 0; i < cfg->line_outs; i++) {
14911 if (!spec->multiout.dac_nids[i])
14913 nid_v = alc861vd_idx_to_mixer_vol(
14915 spec->multiout.dac_nids[i]));
14916 nid_s = alc861vd_idx_to_mixer_switch(
14918 spec->multiout.dac_nids[i]));
14922 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14923 "Center Playback Volume",
14924 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14928 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14929 "LFE Playback Volume",
14930 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14934 err = add_control(spec, ALC_CTL_BIND_MUTE,
14935 "Center Playback Switch",
14936 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14940 err = add_control(spec, ALC_CTL_BIND_MUTE,
14941 "LFE Playback Switch",
14942 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14947 sprintf(name, "%s Playback Volume", chname[i]);
14948 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14949 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14953 sprintf(name, "%s Playback Switch", chname[i]);
14954 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14955 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14964 /* add playback controls for speaker and HP outputs */
14965 /* Based on ALC880 version. But ALC861VD has separate,
14966 * different NIDs for mute/unmute switch and volume control */
14967 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14968 hda_nid_t pin, const char *pfx)
14970 hda_nid_t nid_v, nid_s;
14977 if (alc880_is_fixed_pin(pin)) {
14978 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14979 /* specify the DAC as the extra output */
14980 if (!spec->multiout.hp_nid)
14981 spec->multiout.hp_nid = nid_v;
14983 spec->multiout.extra_out_nid[0] = nid_v;
14984 /* control HP volume/switch on the output mixer amp */
14985 nid_v = alc861vd_idx_to_mixer_vol(
14986 alc880_fixed_pin_idx(pin));
14987 nid_s = alc861vd_idx_to_mixer_switch(
14988 alc880_fixed_pin_idx(pin));
14990 sprintf(name, "%s Playback Volume", pfx);
14991 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14992 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14995 sprintf(name, "%s Playback Switch", pfx);
14996 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14997 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15000 } else if (alc880_is_multi_pin(pin)) {
15001 /* set manual connection */
15002 /* we have only a switch on HP-out PIN */
15003 sprintf(name, "%s Playback Switch", pfx);
15004 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15005 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15012 /* parse the BIOS configuration and set up the alc_spec
15013 * return 1 if successful, 0 if the proper config is not found,
15014 * or a negative error code
15015 * Based on ALC880 version - had to change it to override
15016 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15017 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15019 struct alc_spec *spec = codec->spec;
15021 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15023 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15027 if (!spec->autocfg.line_outs)
15028 return 0; /* can't find valid BIOS pin config */
15030 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15033 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15036 err = alc861vd_auto_create_extra_out(spec,
15037 spec->autocfg.speaker_pins[0],
15041 err = alc861vd_auto_create_extra_out(spec,
15042 spec->autocfg.hp_pins[0],
15046 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15050 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15052 if (spec->autocfg.dig_outs)
15053 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15055 if (spec->kctls.list)
15056 add_mixer(spec, spec->kctls.list);
15058 add_verb(spec, alc861vd_volume_init_verbs);
15060 spec->num_mux_defs = 1;
15061 spec->input_mux = &spec->private_imux[0];
15063 err = alc_auto_add_mic_boost(codec);
15067 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15072 /* additional initialization for auto-configuration model */
15073 static void alc861vd_auto_init(struct hda_codec *codec)
15075 struct alc_spec *spec = codec->spec;
15076 alc861vd_auto_init_multi_out(codec);
15077 alc861vd_auto_init_hp_out(codec);
15078 alc861vd_auto_init_analog_input(codec);
15079 alc861vd_auto_init_input_src(codec);
15080 if (spec->unsol_event)
15081 alc_inithook(codec);
15084 static int patch_alc861vd(struct hda_codec *codec)
15086 struct alc_spec *spec;
15087 int err, board_config;
15089 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15093 codec->spec = spec;
15095 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15099 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15100 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15101 "trying auto-probe from BIOS...\n", codec->chip_name);
15102 board_config = ALC861VD_AUTO;
15105 if (board_config == ALC861VD_AUTO) {
15106 /* automatic parse from the BIOS config */
15107 err = alc861vd_parse_auto_config(codec);
15113 "hda_codec: Cannot set up configuration "
15114 "from BIOS. Using base mode...\n");
15115 board_config = ALC861VD_3ST;
15119 err = snd_hda_attach_beep_device(codec, 0x23);
15125 if (board_config != ALC861VD_AUTO)
15126 setup_preset(spec, &alc861vd_presets[board_config]);
15128 if (codec->vendor_id == 0x10ec0660) {
15129 /* always turn on EAPD */
15130 add_verb(spec, alc660vd_eapd_verbs);
15133 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15134 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15136 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15137 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15139 spec->adc_nids = alc861vd_adc_nids;
15140 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15141 spec->capsrc_nids = alc861vd_capsrc_nids;
15142 spec->capture_style = CAPT_MIX;
15144 set_capture_mixer(spec);
15145 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15147 spec->vmaster_nid = 0x02;
15149 codec->patch_ops = alc_patch_ops;
15151 if (board_config == ALC861VD_AUTO)
15152 spec->init_hook = alc861vd_auto_init;
15153 #ifdef CONFIG_SND_HDA_POWER_SAVE
15154 if (!spec->loopback.amplist)
15155 spec->loopback.amplist = alc861vd_loopbacks;
15157 codec->proc_widget_hook = print_realtek_coef;
15165 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15166 * configuration. Each pin widget can choose any input DACs and a mixer.
15167 * Each ADC is connected from a mixer of all inputs. This makes possible
15168 * 6-channel independent captures.
15170 * In addition, an independent DAC for the multi-playback (not used in this
15173 #define ALC662_DIGOUT_NID 0x06
15174 #define ALC662_DIGIN_NID 0x0a
15176 static hda_nid_t alc662_dac_nids[4] = {
15177 /* front, rear, clfe, rear_surr */
15181 static hda_nid_t alc272_dac_nids[2] = {
15185 static hda_nid_t alc662_adc_nids[1] = {
15190 static hda_nid_t alc272_adc_nids[1] = {
15195 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15196 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15200 /* FIXME: should be a matrix-type input source selection */
15201 static struct hda_input_mux alc662_capture_source = {
15205 { "Front Mic", 0x1 },
15211 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15219 static struct hda_input_mux alc662_eeepc_capture_source = {
15227 static struct hda_input_mux alc663_capture_source = {
15231 { "Front Mic", 0x1 },
15236 static struct hda_input_mux alc663_m51va_capture_source = {
15239 { "Ext-Mic", 0x0 },
15244 #if 1 /* set to 0 for testing other input sources below */
15245 static struct hda_input_mux alc272_nc10_capture_source = {
15248 { "Autoselect Mic", 0x0 },
15249 { "Internal Mic", 0x1 },
15253 static struct hda_input_mux alc272_nc10_capture_source = {
15256 { "Autoselect Mic", 0x0 },
15257 { "Internal Mic", 0x1 },
15258 { "In-0x02", 0x2 },
15259 { "In-0x03", 0x3 },
15260 { "In-0x04", 0x4 },
15261 { "In-0x05", 0x5 },
15262 { "In-0x06", 0x6 },
15263 { "In-0x07", 0x7 },
15264 { "In-0x08", 0x8 },
15265 { "In-0x09", 0x9 },
15266 { "In-0x0a", 0x0a },
15267 { "In-0x0b", 0x0b },
15268 { "In-0x0c", 0x0c },
15269 { "In-0x0d", 0x0d },
15270 { "In-0x0e", 0x0e },
15271 { "In-0x0f", 0x0f },
15279 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15286 static struct hda_verb alc662_3ST_ch2_init[] = {
15287 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15288 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15289 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15290 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15297 static struct hda_verb alc662_3ST_ch6_init[] = {
15298 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15299 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15300 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15301 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15302 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15303 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15307 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15308 { 2, alc662_3ST_ch2_init },
15309 { 6, alc662_3ST_ch6_init },
15315 static struct hda_verb alc662_sixstack_ch6_init[] = {
15316 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15317 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15318 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15325 static struct hda_verb alc662_sixstack_ch8_init[] = {
15326 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15327 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15328 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15332 static struct hda_channel_mode alc662_5stack_modes[2] = {
15333 { 2, alc662_sixstack_ch6_init },
15334 { 6, alc662_sixstack_ch8_init },
15337 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15338 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15341 static struct snd_kcontrol_new alc662_base_mixer[] = {
15342 /* output mixer control */
15343 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15344 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15345 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15346 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15347 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15348 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15349 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15350 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15353 /*Input mixer control */
15354 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15355 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15356 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15357 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15358 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15359 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15360 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15361 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15365 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15366 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15367 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15368 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15369 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15370 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15371 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15372 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15375 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15376 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15380 static struct snd_kcontrol_new alc662_3ST_6ch_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_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15384 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15385 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15386 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15387 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15388 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15389 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15390 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15391 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15392 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15393 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15395 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15396 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15397 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15401 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15402 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15403 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15404 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15405 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
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, 0x1, HDA_INPUT),
15410 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15414 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15415 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15416 ALC262_HIPPO_MASTER_SWITCH,
15418 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15419 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15420 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15422 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15423 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15424 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15428 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15429 ALC262_HIPPO_MASTER_SWITCH,
15430 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15431 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15432 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15433 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15434 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15442 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15443 .ops = &snd_hda_bind_vol,
15445 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15446 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15451 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15452 .ops = &snd_hda_bind_sw,
15454 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15455 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15460 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15461 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15462 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15464 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15468 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15469 .ops = &snd_hda_bind_sw,
15471 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15472 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15473 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15478 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15479 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15480 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15481 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15482 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15483 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15484 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15489 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15490 .ops = &snd_hda_bind_sw,
15492 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15493 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15494 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15499 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15500 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15501 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15502 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15503 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15504 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15505 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15509 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15510 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15511 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15515 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15516 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15520 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15521 .ops = &snd_hda_bind_vol,
15523 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15524 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15529 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15530 .ops = &snd_hda_bind_sw,
15532 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15533 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15538 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15539 HDA_BIND_VOL("Master Playback Volume",
15540 &alc663_asus_two_bind_master_vol),
15541 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15544 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15549 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15550 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15551 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15552 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15553 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15559 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15560 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15561 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15562 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15563 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15564 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15568 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15569 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15573 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15574 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15575 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15580 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15581 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15582 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15583 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15587 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15589 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15590 .name = "Channel Mode",
15591 .info = alc_ch_mode_info,
15592 .get = alc_ch_mode_get,
15593 .put = alc_ch_mode_put,
15598 static struct hda_verb alc662_init_verbs[] = {
15599 /* ADC: mute amp left and right */
15600 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15601 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15602 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15607 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15608 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15612 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15614 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15615 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15617 /* Front Pin: output 0 (0x0c) */
15618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15621 /* Rear Pin: output 1 (0x0d) */
15622 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15625 /* CLFE Pin: output 2 (0x0e) */
15626 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15627 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15629 /* Mic (rear) pin: input vref at 80% */
15630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15632 /* Front Mic pin: input vref at 80% */
15633 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15635 /* Line In pin: input */
15636 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15638 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15639 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15640 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15641 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15642 /* CD pin widget for input */
15643 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15645 /* FIXME: use matrix-type input source selection */
15646 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15648 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15649 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15651 /* always trun on EAPD */
15652 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15653 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15658 static struct hda_verb alc662_sue_init_verbs[] = {
15659 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15660 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15664 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15665 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15666 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15670 /* Set Unsolicited Event*/
15671 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15673 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15678 * generic initialization of ADC, input mixers and output mixers
15680 static struct hda_verb alc662_auto_init_verbs[] = {
15682 * Unmute ADC and set the default input to mic-in
15684 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15685 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15687 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15689 * Note: PASD motherboards uses the Line In 2 as the input for front
15690 * panel mic (mic 2)
15692 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15700 * Set up output mixers (0x0c - 0x0f)
15702 /* set vol=0 to output mixers */
15703 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15704 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15705 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15707 /* set up input amps for analog loopback */
15708 /* Amp Indices: DAC = 0, mixer = 1 */
15709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15710 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15712 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15717 /* FIXME: use matrix-type input source selection */
15718 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15720 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15725 /* additional verbs for ALC663 */
15726 static struct hda_verb alc663_auto_init_verbs[] = {
15727 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15728 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15732 static struct hda_verb alc663_m51va_init_verbs[] = {
15733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15734 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15735 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15736 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15737 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15738 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15739 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15740 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15741 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15745 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15746 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15747 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15748 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15749 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15750 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15751 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15752 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15756 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15757 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15758 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15759 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15760 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15763 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15768 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15769 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15771 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15774 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15775 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15779 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15780 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15781 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15782 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15783 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
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, 0x0}, /* 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 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15795 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15796 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15799 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15801 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15803 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15804 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15805 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15806 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15807 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15811 static struct hda_verb alc663_g71v_init_verbs[] = {
15812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15813 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15814 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15816 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15817 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15818 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15821 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15822 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15826 static struct hda_verb alc663_g50v_init_verbs[] = {
15827 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15828 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15829 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15831 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15832 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15836 static struct hda_verb alc662_ecs_init_verbs[] = {
15837 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15838 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15839 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15840 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15844 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15845 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15846 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15848 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15849 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15850 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15851 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15852 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15853 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15854 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15855 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15859 static struct hda_verb alc272_dell_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 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15868 {0x23, 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 snd_kcontrol_new alc662_auto_capture_mixer[] = {
15875 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15876 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15880 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15881 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15882 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15886 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15888 unsigned int present;
15889 unsigned char bits;
15891 present = snd_hda_codec_read(codec, 0x14, 0,
15892 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15893 bits = present ? HDA_AMP_MUTE : 0;
15894 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15895 HDA_AMP_MUTE, bits);
15898 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15900 unsigned int present;
15901 unsigned char bits;
15903 present = snd_hda_codec_read(codec, 0x1b, 0,
15904 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15905 bits = present ? HDA_AMP_MUTE : 0;
15906 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15907 HDA_AMP_MUTE, bits);
15908 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15909 HDA_AMP_MUTE, bits);
15912 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15915 if ((res >> 26) == ALC880_HP_EVENT)
15916 alc662_lenovo_101e_all_automute(codec);
15917 if ((res >> 26) == ALC880_FRONT_EVENT)
15918 alc662_lenovo_101e_ispeaker_automute(codec);
15921 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15923 unsigned int present;
15925 present = snd_hda_codec_read(codec, 0x18, 0,
15926 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15927 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15928 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15929 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15930 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15931 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15932 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15933 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15934 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15937 /* unsolicited event for HP jack sensing */
15938 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15941 if ((res >> 26) == ALC880_MIC_EVENT)
15942 alc662_eeepc_mic_automute(codec);
15944 alc262_hippo_unsol_event(codec, res);
15947 static void alc662_eeepc_inithook(struct hda_codec *codec)
15949 alc262_hippo1_init_hook(codec);
15950 alc662_eeepc_mic_automute(codec);
15953 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15955 struct alc_spec *spec = codec->spec;
15957 spec->autocfg.hp_pins[0] = 0x14;
15958 spec->autocfg.speaker_pins[0] = 0x1b;
15959 alc262_hippo_master_update(codec);
15962 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15964 unsigned int present;
15965 unsigned char bits;
15967 present = snd_hda_codec_read(codec, 0x21, 0,
15968 AC_VERB_GET_PIN_SENSE, 0)
15969 & AC_PINSENSE_PRESENCE;
15970 bits = present ? HDA_AMP_MUTE : 0;
15971 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15972 AMP_IN_MUTE(0), bits);
15973 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15974 AMP_IN_MUTE(0), bits);
15977 static void alc663_21jd_two_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);
15990 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15991 AMP_IN_MUTE(0), bits);
15992 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15993 AMP_IN_MUTE(0), bits);
15996 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15998 unsigned int present;
15999 unsigned char bits;
16001 present = snd_hda_codec_read(codec, 0x15, 0,
16002 AC_VERB_GET_PIN_SENSE, 0)
16003 & AC_PINSENSE_PRESENCE;
16004 bits = present ? HDA_AMP_MUTE : 0;
16005 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16006 AMP_IN_MUTE(0), bits);
16007 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16008 AMP_IN_MUTE(0), bits);
16009 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16010 AMP_IN_MUTE(0), bits);
16011 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16012 AMP_IN_MUTE(0), bits);
16015 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16017 unsigned int present;
16018 unsigned char bits;
16020 present = snd_hda_codec_read(codec, 0x1b, 0,
16021 AC_VERB_GET_PIN_SENSE, 0)
16022 & AC_PINSENSE_PRESENCE;
16023 bits = present ? 0 : PIN_OUT;
16024 snd_hda_codec_write(codec, 0x14, 0,
16025 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16028 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16030 unsigned int present1, present2;
16032 present1 = snd_hda_codec_read(codec, 0x21, 0,
16033 AC_VERB_GET_PIN_SENSE, 0)
16034 & AC_PINSENSE_PRESENCE;
16035 present2 = snd_hda_codec_read(codec, 0x15, 0,
16036 AC_VERB_GET_PIN_SENSE, 0)
16037 & AC_PINSENSE_PRESENCE;
16039 if (present1 || present2) {
16040 snd_hda_codec_write_cache(codec, 0x14, 0,
16041 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16043 snd_hda_codec_write_cache(codec, 0x14, 0,
16044 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16048 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16050 unsigned int present1, present2;
16052 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16053 AC_VERB_GET_PIN_SENSE, 0)
16054 & AC_PINSENSE_PRESENCE;
16055 present2 = snd_hda_codec_read(codec, 0x15, 0,
16056 AC_VERB_GET_PIN_SENSE, 0)
16057 & AC_PINSENSE_PRESENCE;
16059 if (present1 || present2) {
16060 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16061 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16062 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16063 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16065 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16066 AMP_IN_MUTE(0), 0);
16067 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16068 AMP_IN_MUTE(0), 0);
16072 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16074 unsigned int present;
16076 present = snd_hda_codec_read(codec, 0x18, 0,
16077 AC_VERB_GET_PIN_SENSE, 0)
16078 & AC_PINSENSE_PRESENCE;
16079 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16080 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16081 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16082 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16083 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16084 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16085 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16086 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16089 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16092 switch (res >> 26) {
16093 case ALC880_HP_EVENT:
16094 alc663_m51va_speaker_automute(codec);
16096 case ALC880_MIC_EVENT:
16097 alc663_m51va_mic_automute(codec);
16102 static void alc663_m51va_inithook(struct hda_codec *codec)
16104 alc663_m51va_speaker_automute(codec);
16105 alc663_m51va_mic_automute(codec);
16108 /* ***************** Mode1 ******************************/
16109 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16112 switch (res >> 26) {
16113 case ALC880_HP_EVENT:
16114 alc663_m51va_speaker_automute(codec);
16116 case ALC880_MIC_EVENT:
16117 alc662_eeepc_mic_automute(codec);
16122 static void alc663_mode1_inithook(struct hda_codec *codec)
16124 alc663_m51va_speaker_automute(codec);
16125 alc662_eeepc_mic_automute(codec);
16127 /* ***************** Mode2 ******************************/
16128 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16131 switch (res >> 26) {
16132 case ALC880_HP_EVENT:
16133 alc662_f5z_speaker_automute(codec);
16135 case ALC880_MIC_EVENT:
16136 alc662_eeepc_mic_automute(codec);
16141 static void alc662_mode2_inithook(struct hda_codec *codec)
16143 alc662_f5z_speaker_automute(codec);
16144 alc662_eeepc_mic_automute(codec);
16146 /* ***************** Mode3 ******************************/
16147 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16150 switch (res >> 26) {
16151 case ALC880_HP_EVENT:
16152 alc663_two_hp_m1_speaker_automute(codec);
16154 case ALC880_MIC_EVENT:
16155 alc662_eeepc_mic_automute(codec);
16160 static void alc663_mode3_inithook(struct hda_codec *codec)
16162 alc663_two_hp_m1_speaker_automute(codec);
16163 alc662_eeepc_mic_automute(codec);
16165 /* ***************** Mode4 ******************************/
16166 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16169 switch (res >> 26) {
16170 case ALC880_HP_EVENT:
16171 alc663_21jd_two_speaker_automute(codec);
16173 case ALC880_MIC_EVENT:
16174 alc662_eeepc_mic_automute(codec);
16179 static void alc663_mode4_inithook(struct hda_codec *codec)
16181 alc663_21jd_two_speaker_automute(codec);
16182 alc662_eeepc_mic_automute(codec);
16184 /* ***************** Mode5 ******************************/
16185 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16188 switch (res >> 26) {
16189 case ALC880_HP_EVENT:
16190 alc663_15jd_two_speaker_automute(codec);
16192 case ALC880_MIC_EVENT:
16193 alc662_eeepc_mic_automute(codec);
16198 static void alc663_mode5_inithook(struct hda_codec *codec)
16200 alc663_15jd_two_speaker_automute(codec);
16201 alc662_eeepc_mic_automute(codec);
16203 /* ***************** Mode6 ******************************/
16204 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16207 switch (res >> 26) {
16208 case ALC880_HP_EVENT:
16209 alc663_two_hp_m2_speaker_automute(codec);
16211 case ALC880_MIC_EVENT:
16212 alc662_eeepc_mic_automute(codec);
16217 static void alc663_mode6_inithook(struct hda_codec *codec)
16219 alc663_two_hp_m2_speaker_automute(codec);
16220 alc662_eeepc_mic_automute(codec);
16223 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16225 unsigned int present;
16226 unsigned char bits;
16228 present = snd_hda_codec_read(codec, 0x21, 0,
16229 AC_VERB_GET_PIN_SENSE, 0)
16230 & AC_PINSENSE_PRESENCE;
16231 bits = present ? HDA_AMP_MUTE : 0;
16232 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16233 HDA_AMP_MUTE, bits);
16234 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16235 HDA_AMP_MUTE, bits);
16238 static void alc663_g71v_front_automute(struct hda_codec *codec)
16240 unsigned int present;
16241 unsigned char bits;
16243 present = snd_hda_codec_read(codec, 0x15, 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, 0x14, HDA_OUTPUT, 0,
16248 HDA_AMP_MUTE, bits);
16251 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16254 switch (res >> 26) {
16255 case ALC880_HP_EVENT:
16256 alc663_g71v_hp_automute(codec);
16258 case ALC880_FRONT_EVENT:
16259 alc663_g71v_front_automute(codec);
16261 case ALC880_MIC_EVENT:
16262 alc662_eeepc_mic_automute(codec);
16267 static void alc663_g71v_inithook(struct hda_codec *codec)
16269 alc663_g71v_front_automute(codec);
16270 alc663_g71v_hp_automute(codec);
16271 alc662_eeepc_mic_automute(codec);
16274 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16277 switch (res >> 26) {
16278 case ALC880_HP_EVENT:
16279 alc663_m51va_speaker_automute(codec);
16281 case ALC880_MIC_EVENT:
16282 alc662_eeepc_mic_automute(codec);
16287 static void alc663_g50v_inithook(struct hda_codec *codec)
16289 alc663_m51va_speaker_automute(codec);
16290 alc662_eeepc_mic_automute(codec);
16293 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16294 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16295 ALC262_HIPPO_MASTER_SWITCH,
16297 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16298 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16299 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16301 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16302 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16303 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16307 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16308 /* Master Playback automatically created from Speaker and Headphone */
16309 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16310 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16311 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16312 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16314 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16315 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16316 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16318 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16319 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16320 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16324 #ifdef CONFIG_SND_HDA_POWER_SAVE
16325 #define alc662_loopbacks alc880_loopbacks
16329 /* pcm configuration: identiacal with ALC880 */
16330 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16331 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16332 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16333 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16336 * configuration and preset
16338 static const char *alc662_models[ALC662_MODEL_LAST] = {
16339 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16340 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16341 [ALC662_3ST_6ch] = "3stack-6ch",
16342 [ALC662_5ST_DIG] = "6stack-dig",
16343 [ALC662_LENOVO_101E] = "lenovo-101e",
16344 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16345 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16346 [ALC662_ECS] = "ecs",
16347 [ALC663_ASUS_M51VA] = "m51va",
16348 [ALC663_ASUS_G71V] = "g71v",
16349 [ALC663_ASUS_H13] = "h13",
16350 [ALC663_ASUS_G50V] = "g50v",
16351 [ALC663_ASUS_MODE1] = "asus-mode1",
16352 [ALC662_ASUS_MODE2] = "asus-mode2",
16353 [ALC663_ASUS_MODE3] = "asus-mode3",
16354 [ALC663_ASUS_MODE4] = "asus-mode4",
16355 [ALC663_ASUS_MODE5] = "asus-mode5",
16356 [ALC663_ASUS_MODE6] = "asus-mode6",
16357 [ALC272_DELL] = "dell",
16358 [ALC272_DELL_ZM1] = "dell-zm1",
16359 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16360 [ALC662_AUTO] = "auto",
16363 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16364 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16365 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16366 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16367 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16368 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16369 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16370 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16371 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16372 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16373 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16374 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16375 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16376 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16377 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16378 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16379 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16380 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16381 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16382 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16383 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16384 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16385 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16386 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16387 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16388 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16389 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16390 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16391 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16392 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16393 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16394 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16395 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16396 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16397 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16398 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16399 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16400 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16401 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16402 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16403 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16404 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16405 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16406 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16407 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16408 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16409 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16410 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16411 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16412 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16413 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16414 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16415 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16416 ALC662_3ST_6ch_DIG),
16417 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16418 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16419 ALC662_3ST_6ch_DIG),
16420 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16421 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16422 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16423 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16424 ALC662_3ST_6ch_DIG),
16425 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16430 static struct alc_config_preset alc662_presets[] = {
16431 [ALC662_3ST_2ch_DIG] = {
16432 .mixers = { alc662_3ST_2ch_mixer },
16433 .init_verbs = { alc662_init_verbs },
16434 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16435 .dac_nids = alc662_dac_nids,
16436 .dig_out_nid = ALC662_DIGOUT_NID,
16437 .dig_in_nid = ALC662_DIGIN_NID,
16438 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16439 .channel_mode = alc662_3ST_2ch_modes,
16440 .input_mux = &alc662_capture_source,
16442 [ALC662_3ST_6ch_DIG] = {
16443 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16444 .init_verbs = { alc662_init_verbs },
16445 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16446 .dac_nids = alc662_dac_nids,
16447 .dig_out_nid = ALC662_DIGOUT_NID,
16448 .dig_in_nid = ALC662_DIGIN_NID,
16449 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16450 .channel_mode = alc662_3ST_6ch_modes,
16452 .input_mux = &alc662_capture_source,
16454 [ALC662_3ST_6ch] = {
16455 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16456 .init_verbs = { alc662_init_verbs },
16457 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16458 .dac_nids = alc662_dac_nids,
16459 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16460 .channel_mode = alc662_3ST_6ch_modes,
16462 .input_mux = &alc662_capture_source,
16464 [ALC662_5ST_DIG] = {
16465 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16466 .init_verbs = { alc662_init_verbs },
16467 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16468 .dac_nids = alc662_dac_nids,
16469 .dig_out_nid = ALC662_DIGOUT_NID,
16470 .dig_in_nid = ALC662_DIGIN_NID,
16471 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16472 .channel_mode = alc662_5stack_modes,
16473 .input_mux = &alc662_capture_source,
16475 [ALC662_LENOVO_101E] = {
16476 .mixers = { alc662_lenovo_101e_mixer },
16477 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16478 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16479 .dac_nids = alc662_dac_nids,
16480 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16481 .channel_mode = alc662_3ST_2ch_modes,
16482 .input_mux = &alc662_lenovo_101e_capture_source,
16483 .unsol_event = alc662_lenovo_101e_unsol_event,
16484 .init_hook = alc662_lenovo_101e_all_automute,
16486 [ALC662_ASUS_EEEPC_P701] = {
16487 .mixers = { alc662_eeepc_p701_mixer },
16488 .init_verbs = { alc662_init_verbs,
16489 alc662_eeepc_sue_init_verbs },
16490 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16491 .dac_nids = alc662_dac_nids,
16492 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16493 .channel_mode = alc662_3ST_2ch_modes,
16494 .input_mux = &alc662_eeepc_capture_source,
16495 .unsol_event = alc662_eeepc_unsol_event,
16496 .init_hook = alc662_eeepc_inithook,
16498 [ALC662_ASUS_EEEPC_EP20] = {
16499 .mixers = { alc662_eeepc_ep20_mixer,
16500 alc662_chmode_mixer },
16501 .init_verbs = { alc662_init_verbs,
16502 alc662_eeepc_ep20_sue_init_verbs },
16503 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16504 .dac_nids = alc662_dac_nids,
16505 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16506 .channel_mode = alc662_3ST_6ch_modes,
16507 .input_mux = &alc662_lenovo_101e_capture_source,
16508 .unsol_event = alc662_eeepc_unsol_event,
16509 .init_hook = alc662_eeepc_ep20_inithook,
16512 .mixers = { alc662_ecs_mixer },
16513 .init_verbs = { alc662_init_verbs,
16514 alc662_ecs_init_verbs },
16515 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16516 .dac_nids = alc662_dac_nids,
16517 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16518 .channel_mode = alc662_3ST_2ch_modes,
16519 .input_mux = &alc662_eeepc_capture_source,
16520 .unsol_event = alc662_eeepc_unsol_event,
16521 .init_hook = alc662_eeepc_inithook,
16523 [ALC663_ASUS_M51VA] = {
16524 .mixers = { alc663_m51va_mixer },
16525 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16526 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16527 .dac_nids = alc662_dac_nids,
16528 .dig_out_nid = ALC662_DIGOUT_NID,
16529 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16530 .channel_mode = alc662_3ST_2ch_modes,
16531 .input_mux = &alc663_m51va_capture_source,
16532 .unsol_event = alc663_m51va_unsol_event,
16533 .init_hook = alc663_m51va_inithook,
16535 [ALC663_ASUS_G71V] = {
16536 .mixers = { alc663_g71v_mixer },
16537 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16538 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16539 .dac_nids = alc662_dac_nids,
16540 .dig_out_nid = ALC662_DIGOUT_NID,
16541 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16542 .channel_mode = alc662_3ST_2ch_modes,
16543 .input_mux = &alc662_eeepc_capture_source,
16544 .unsol_event = alc663_g71v_unsol_event,
16545 .init_hook = alc663_g71v_inithook,
16547 [ALC663_ASUS_H13] = {
16548 .mixers = { alc663_m51va_mixer },
16549 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16550 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16551 .dac_nids = alc662_dac_nids,
16552 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16553 .channel_mode = alc662_3ST_2ch_modes,
16554 .input_mux = &alc663_m51va_capture_source,
16555 .unsol_event = alc663_m51va_unsol_event,
16556 .init_hook = alc663_m51va_inithook,
16558 [ALC663_ASUS_G50V] = {
16559 .mixers = { alc663_g50v_mixer },
16560 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16561 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16562 .dac_nids = alc662_dac_nids,
16563 .dig_out_nid = ALC662_DIGOUT_NID,
16564 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16565 .channel_mode = alc662_3ST_6ch_modes,
16566 .input_mux = &alc663_capture_source,
16567 .unsol_event = alc663_g50v_unsol_event,
16568 .init_hook = alc663_g50v_inithook,
16570 [ALC663_ASUS_MODE1] = {
16571 .mixers = { alc663_m51va_mixer },
16572 .cap_mixer = alc662_auto_capture_mixer,
16573 .init_verbs = { alc662_init_verbs,
16574 alc663_21jd_amic_init_verbs },
16575 .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_2ch_modes),
16580 .channel_mode = alc662_3ST_2ch_modes,
16581 .input_mux = &alc662_eeepc_capture_source,
16582 .unsol_event = alc663_mode1_unsol_event,
16583 .init_hook = alc663_mode1_inithook,
16585 [ALC662_ASUS_MODE2] = {
16586 .mixers = { alc662_1bjd_mixer },
16587 .cap_mixer = alc662_auto_capture_mixer,
16588 .init_verbs = { alc662_init_verbs,
16589 alc662_1bjd_amic_init_verbs },
16590 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16591 .dac_nids = alc662_dac_nids,
16592 .dig_out_nid = ALC662_DIGOUT_NID,
16593 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16594 .channel_mode = alc662_3ST_2ch_modes,
16595 .input_mux = &alc662_eeepc_capture_source,
16596 .unsol_event = alc662_mode2_unsol_event,
16597 .init_hook = alc662_mode2_inithook,
16599 [ALC663_ASUS_MODE3] = {
16600 .mixers = { alc663_two_hp_m1_mixer },
16601 .cap_mixer = alc662_auto_capture_mixer,
16602 .init_verbs = { alc662_init_verbs,
16603 alc663_two_hp_amic_m1_init_verbs },
16604 .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 = alc663_mode3_unsol_event,
16612 .init_hook = alc663_mode3_inithook,
16614 [ALC663_ASUS_MODE4] = {
16615 .mixers = { alc663_asus_21jd_clfe_mixer },
16616 .cap_mixer = alc662_auto_capture_mixer,
16617 .init_verbs = { alc662_init_verbs,
16618 alc663_21jd_amic_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_mode4_unsol_event,
16627 .init_hook = alc663_mode4_inithook,
16629 [ALC663_ASUS_MODE5] = {
16630 .mixers = { alc663_asus_15jd_clfe_mixer },
16631 .cap_mixer = alc662_auto_capture_mixer,
16632 .init_verbs = { alc662_init_verbs,
16633 alc663_15jd_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_mode5_unsol_event,
16642 .init_hook = alc663_mode5_inithook,
16644 [ALC663_ASUS_MODE6] = {
16645 .mixers = { alc663_two_hp_m2_mixer },
16646 .cap_mixer = alc662_auto_capture_mixer,
16647 .init_verbs = { alc662_init_verbs,
16648 alc663_two_hp_amic_m2_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_mode6_unsol_event,
16657 .init_hook = alc663_mode6_inithook,
16660 .mixers = { alc663_m51va_mixer },
16661 .cap_mixer = alc272_auto_capture_mixer,
16662 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16663 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16664 .dac_nids = alc662_dac_nids,
16665 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16666 .adc_nids = alc272_adc_nids,
16667 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16668 .capsrc_nids = alc272_capsrc_nids,
16669 .channel_mode = alc662_3ST_2ch_modes,
16670 .input_mux = &alc663_m51va_capture_source,
16671 .unsol_event = alc663_m51va_unsol_event,
16672 .init_hook = alc663_m51va_inithook,
16674 [ALC272_DELL_ZM1] = {
16675 .mixers = { alc663_m51va_mixer },
16676 .cap_mixer = alc662_auto_capture_mixer,
16677 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_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 = alc662_adc_nids,
16682 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16683 .capsrc_nids = alc662_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_SAMSUNG_NC10] = {
16690 .mixers = { alc272_nc10_mixer },
16691 .init_verbs = { alc662_init_verbs,
16692 alc663_21jd_amic_init_verbs },
16693 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16694 .dac_nids = alc272_dac_nids,
16695 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16696 .channel_mode = alc662_3ST_2ch_modes,
16697 .input_mux = &alc272_nc10_capture_source,
16698 .unsol_event = alc663_mode4_unsol_event,
16699 .init_hook = alc663_mode4_inithook,
16705 * BIOS auto configuration
16708 /* add playback controls from the parsed DAC table */
16709 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16710 const struct auto_pin_cfg *cfg)
16713 static const char *chname[4] = {
16714 "Front", "Surround", NULL /*CLFE*/, "Side"
16719 for (i = 0; i < cfg->line_outs; i++) {
16720 if (!spec->multiout.dac_nids[i])
16722 nid = alc880_idx_to_dac(i);
16725 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16726 "Center Playback Volume",
16727 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16731 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16732 "LFE Playback Volume",
16733 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16737 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16738 "Center Playback Switch",
16739 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16743 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16744 "LFE Playback Switch",
16745 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16750 sprintf(name, "%s Playback Volume", chname[i]);
16751 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16752 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16756 sprintf(name, "%s Playback Switch", chname[i]);
16757 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16758 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16767 /* add playback controls for speaker and HP outputs */
16768 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16779 /* ALC663 has a mono output pin on 0x17 */
16780 sprintf(name, "%s Playback Switch", pfx);
16781 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16782 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16786 if (alc880_is_fixed_pin(pin)) {
16787 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16788 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16789 /* specify the DAC as the extra output */
16790 if (!spec->multiout.hp_nid)
16791 spec->multiout.hp_nid = nid;
16793 spec->multiout.extra_out_nid[0] = nid;
16794 /* control HP volume/switch on the output mixer amp */
16795 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16796 sprintf(name, "%s Playback Volume", pfx);
16797 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16798 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16801 sprintf(name, "%s Playback Switch", pfx);
16802 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16803 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16806 } else if (alc880_is_multi_pin(pin)) {
16807 /* set manual connection */
16808 /* we have only a switch on HP-out PIN */
16809 sprintf(name, "%s Playback Switch", pfx);
16810 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16811 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16818 /* return the index of the src widget from the connection list of the nid.
16819 * return -1 if not found
16821 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16824 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16827 conns = snd_hda_get_connections(codec, nid, conn_list,
16828 ARRAY_SIZE(conn_list));
16831 for (i = 0; i < conns; i++)
16832 if (conn_list[i] == src)
16837 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16839 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16840 return (pincap & AC_PINCAP_IN) != 0;
16843 /* create playback/capture controls for input pins */
16844 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16845 const struct auto_pin_cfg *cfg)
16847 struct alc_spec *spec = codec->spec;
16848 struct hda_input_mux *imux = &spec->private_imux[0];
16851 for (i = 0; i < AUTO_PIN_LAST; i++) {
16852 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16853 idx = alc662_input_pin_idx(codec, 0x0b,
16854 cfg->input_pins[i]);
16856 err = new_analog_input(spec, cfg->input_pins[i],
16857 auto_pin_cfg_labels[i],
16862 idx = alc662_input_pin_idx(codec, 0x22,
16863 cfg->input_pins[i]);
16865 imux->items[imux->num_items].label =
16866 auto_pin_cfg_labels[i];
16867 imux->items[imux->num_items].index = idx;
16875 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16876 hda_nid_t nid, int pin_type,
16879 alc_set_pin_output(codec, nid, pin_type);
16880 /* need the manual connection? */
16881 if (alc880_is_multi_pin(nid)) {
16882 struct alc_spec *spec = codec->spec;
16883 int idx = alc880_multi_pin_idx(nid);
16884 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16885 AC_VERB_SET_CONNECT_SEL,
16886 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16890 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16892 struct alc_spec *spec = codec->spec;
16895 for (i = 0; i <= HDA_SIDE; i++) {
16896 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16897 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16899 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16904 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16906 struct alc_spec *spec = codec->spec;
16909 pin = spec->autocfg.hp_pins[0];
16910 if (pin) /* connect to front */
16912 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16913 pin = spec->autocfg.speaker_pins[0];
16915 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16918 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16920 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16922 struct alc_spec *spec = codec->spec;
16925 for (i = 0; i < AUTO_PIN_LAST; i++) {
16926 hda_nid_t nid = spec->autocfg.input_pins[i];
16927 if (alc662_is_input_pin(codec, nid)) {
16928 alc_set_input_pin(codec, nid, i);
16929 if (nid != ALC662_PIN_CD_NID &&
16930 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16931 snd_hda_codec_write(codec, nid, 0,
16932 AC_VERB_SET_AMP_GAIN_MUTE,
16938 #define alc662_auto_init_input_src alc882_auto_init_input_src
16940 static int alc662_parse_auto_config(struct hda_codec *codec)
16942 struct alc_spec *spec = codec->spec;
16944 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16946 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16950 if (!spec->autocfg.line_outs)
16951 return 0; /* can't find valid BIOS pin config */
16953 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16956 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16959 err = alc662_auto_create_extra_out(spec,
16960 spec->autocfg.speaker_pins[0],
16964 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16968 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
16972 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16974 if (spec->autocfg.dig_outs)
16975 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16977 if (spec->kctls.list)
16978 add_mixer(spec, spec->kctls.list);
16980 spec->num_mux_defs = 1;
16981 spec->input_mux = &spec->private_imux[0];
16983 add_verb(spec, alc662_auto_init_verbs);
16984 if (codec->vendor_id == 0x10ec0663)
16985 add_verb(spec, alc663_auto_init_verbs);
16987 err = alc_auto_add_mic_boost(codec);
16991 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
16996 /* additional initialization for auto-configuration model */
16997 static void alc662_auto_init(struct hda_codec *codec)
16999 struct alc_spec *spec = codec->spec;
17000 alc662_auto_init_multi_out(codec);
17001 alc662_auto_init_hp_out(codec);
17002 alc662_auto_init_analog_input(codec);
17003 alc662_auto_init_input_src(codec);
17004 if (spec->unsol_event)
17005 alc_inithook(codec);
17008 static int patch_alc662(struct hda_codec *codec)
17010 struct alc_spec *spec;
17011 int err, board_config;
17013 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17017 codec->spec = spec;
17019 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17021 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17024 if (board_config < 0) {
17025 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17026 "trying auto-probe from BIOS...\n", codec->chip_name);
17027 board_config = ALC662_AUTO;
17030 if (board_config == ALC662_AUTO) {
17031 /* automatic parse from the BIOS config */
17032 err = alc662_parse_auto_config(codec);
17038 "hda_codec: Cannot set up configuration "
17039 "from BIOS. Using base mode...\n");
17040 board_config = ALC662_3ST_2ch_DIG;
17044 err = snd_hda_attach_beep_device(codec, 0x1);
17050 if (board_config != ALC662_AUTO)
17051 setup_preset(spec, &alc662_presets[board_config]);
17053 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17054 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17056 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17057 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17059 spec->adc_nids = alc662_adc_nids;
17060 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17061 spec->capsrc_nids = alc662_capsrc_nids;
17062 spec->capture_style = CAPT_MIX;
17064 if (!spec->cap_mixer)
17065 set_capture_mixer(spec);
17066 if (codec->vendor_id == 0x10ec0662)
17067 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17069 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17071 spec->vmaster_nid = 0x02;
17073 codec->patch_ops = alc_patch_ops;
17074 if (board_config == ALC662_AUTO)
17075 spec->init_hook = alc662_auto_init;
17076 #ifdef CONFIG_SND_HDA_POWER_SAVE
17077 if (!spec->loopback.amplist)
17078 spec->loopback.amplist = alc662_loopbacks;
17080 codec->proc_widget_hook = print_realtek_coef;
17088 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17089 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17090 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17091 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17092 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17093 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17094 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17095 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17096 .patch = patch_alc861 },
17097 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17098 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17099 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17100 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17101 .patch = patch_alc883 },
17102 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17103 .patch = patch_alc662 },
17104 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17105 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17106 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17107 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17108 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17109 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17110 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17111 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17112 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17113 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17114 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17115 .patch = patch_alc883 },
17116 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17117 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17118 {} /* terminator */
17121 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17123 MODULE_LICENSE("GPL");
17124 MODULE_DESCRIPTION("Realtek HD-audio codec");
17126 static struct hda_codec_preset_list realtek_list = {
17127 .preset = snd_hda_preset_realtek,
17128 .owner = THIS_MODULE,
17131 static int __init patch_realtek_init(void)
17133 return snd_hda_add_codec_preset(&realtek_list);
17136 static void __exit patch_realtek_exit(void)
17138 snd_hda_delete_codec_preset(&realtek_list);
17141 module_init(patch_realtek_init)
17142 module_exit(patch_realtek_exit)