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,
220 ALC883_TARGA_2ch_DIG,
223 ALC888_ACER_ASPIRE_4930G,
227 ALC883_LENOVO_101E_2ch,
228 ALC883_LENOVO_NB0763,
229 ALC888_LENOVO_MS7195_DIG,
236 ALC883_FUJITSU_PI2515,
237 ALC888_FUJITSU_XA3530,
238 ALC883_3ST_6ch_INTEL,
246 /* styles of capture selection */
248 CAPT_MUX = 0, /* only mux based */
249 CAPT_MIX, /* only mixer based */
250 CAPT_1MUX_MIX, /* first mux and other mixers */
254 #define GPIO_MASK 0x03
256 /* extra amp-initialization sequence types */
266 /* codec parameterization */
267 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
268 unsigned int num_mixers;
269 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
270 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
272 const struct hda_verb *init_verbs[5]; /* initialization verbs
276 unsigned int num_init_verbs;
278 char *stream_name_analog; /* analog PCM stream */
279 struct hda_pcm_stream *stream_analog_playback;
280 struct hda_pcm_stream *stream_analog_capture;
281 struct hda_pcm_stream *stream_analog_alt_playback;
282 struct hda_pcm_stream *stream_analog_alt_capture;
284 char *stream_name_digital; /* digital PCM stream */
285 struct hda_pcm_stream *stream_digital_playback;
286 struct hda_pcm_stream *stream_digital_capture;
289 struct hda_multi_out multiout; /* playback set-up
290 * max_channels, dacs must be set
291 * dig_out_nid and hp_nid are optional
293 hda_nid_t alt_dac_nid;
294 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
298 unsigned int num_adc_nids;
300 hda_nid_t *capsrc_nids;
301 hda_nid_t dig_in_nid; /* digital-in NID; optional */
302 int capture_style; /* capture style (CAPT_*) */
305 unsigned int num_mux_defs;
306 const struct hda_input_mux *input_mux;
307 unsigned int cur_mux[3];
310 const struct hda_channel_mode *channel_mode;
311 int num_channel_mode;
314 /* PCM information */
315 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
317 /* dynamic controls, init_verbs and input_mux */
318 struct auto_pin_cfg autocfg;
319 struct snd_array kctls;
320 struct hda_input_mux private_imux[3];
321 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
324 void (*init_hook)(struct hda_codec *codec);
325 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
327 /* for pin sensing */
328 unsigned int sense_updated: 1;
329 unsigned int jack_present: 1;
330 unsigned int master_sw: 1;
333 unsigned int no_analog :1; /* digital I/O only */
336 /* for virtual master */
337 hda_nid_t vmaster_nid;
338 #ifdef CONFIG_SND_HDA_POWER_SAVE
339 struct hda_loopback_check loopback;
344 unsigned int pll_coef_idx, pll_coef_bit;
348 * configuration template - to be copied to the spec instance
350 struct alc_config_preset {
351 struct snd_kcontrol_new *mixers[5]; /* should be identical size
354 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
355 const struct hda_verb *init_verbs[5];
356 unsigned int num_dacs;
358 hda_nid_t dig_out_nid; /* optional */
359 hda_nid_t hp_nid; /* optional */
360 hda_nid_t *slave_dig_outs;
361 unsigned int num_adc_nids;
363 hda_nid_t *capsrc_nids;
364 hda_nid_t dig_in_nid;
365 unsigned int num_channel_mode;
366 const struct hda_channel_mode *channel_mode;
368 unsigned int num_mux_defs;
369 const struct hda_input_mux *input_mux;
370 void (*unsol_event)(struct hda_codec *, unsigned int);
371 void (*init_hook)(struct hda_codec *);
372 #ifdef CONFIG_SND_HDA_POWER_SAVE
373 struct hda_amp_list *loopbacks;
381 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_info *uinfo)
384 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
385 struct alc_spec *spec = codec->spec;
386 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
387 if (mux_idx >= spec->num_mux_defs)
389 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
392 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
393 struct snd_ctl_elem_value *ucontrol)
395 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
396 struct alc_spec *spec = codec->spec;
397 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
399 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
403 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
404 struct snd_ctl_elem_value *ucontrol)
406 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
407 struct alc_spec *spec = codec->spec;
408 const struct hda_input_mux *imux;
409 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
410 unsigned int mux_idx;
411 hda_nid_t nid = spec->capsrc_nids ?
412 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
414 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
415 imux = &spec->input_mux[mux_idx];
417 if (spec->capture_style &&
418 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
419 /* Matrix-mixer style (e.g. ALC882) */
420 unsigned int *cur_val = &spec->cur_mux[adc_idx];
423 idx = ucontrol->value.enumerated.item[0];
424 if (idx >= imux->num_items)
425 idx = imux->num_items - 1;
428 for (i = 0; i < imux->num_items; i++) {
429 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
430 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
431 imux->items[i].index,
437 /* MUX style (e.g. ALC880) */
438 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
439 &spec->cur_mux[adc_idx]);
444 * channel mode setting
446 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
447 struct snd_ctl_elem_info *uinfo)
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 struct alc_spec *spec = codec->spec;
451 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
452 spec->num_channel_mode);
455 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
456 struct snd_ctl_elem_value *ucontrol)
458 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
459 struct alc_spec *spec = codec->spec;
460 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
461 spec->num_channel_mode,
462 spec->multiout.max_channels);
465 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
466 struct snd_ctl_elem_value *ucontrol)
468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
469 struct alc_spec *spec = codec->spec;
470 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
471 spec->num_channel_mode,
472 &spec->multiout.max_channels);
473 if (err >= 0 && spec->need_dac_fix)
474 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
479 * Control the mode of pin widget settings via the mixer. "pc" is used
480 * instead of "%" to avoid consequences of accidently treating the % as
481 * being part of a format specifier. Maximum allowed length of a value is
482 * 63 characters plus NULL terminator.
484 * Note: some retasking pin complexes seem to ignore requests for input
485 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
486 * are requested. Therefore order this list so that this behaviour will not
487 * cause problems when mixer clients move through the enum sequentially.
488 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
491 static char *alc_pin_mode_names[] = {
492 "Mic 50pc bias", "Mic 80pc bias",
493 "Line in", "Line out", "Headphone out",
495 static unsigned char alc_pin_mode_values[] = {
496 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
498 /* The control can present all 5 options, or it can limit the options based
499 * in the pin being assumed to be exclusively an input or an output pin. In
500 * addition, "input" pins may or may not process the mic bias option
501 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
502 * accept requests for bias as of chip versions up to March 2006) and/or
503 * wiring in the computer.
505 #define ALC_PIN_DIR_IN 0x00
506 #define ALC_PIN_DIR_OUT 0x01
507 #define ALC_PIN_DIR_INOUT 0x02
508 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
509 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
511 /* Info about the pin modes supported by the different pin direction modes.
512 * For each direction the minimum and maximum values are given.
514 static signed char alc_pin_mode_dir_info[5][2] = {
515 { 0, 2 }, /* ALC_PIN_DIR_IN */
516 { 3, 4 }, /* ALC_PIN_DIR_OUT */
517 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
518 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
519 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
521 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
522 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
523 #define alc_pin_mode_n_items(_dir) \
524 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
526 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
527 struct snd_ctl_elem_info *uinfo)
529 unsigned int item_num = uinfo->value.enumerated.item;
530 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
532 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
534 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
536 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
537 item_num = alc_pin_mode_min(dir);
538 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
542 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_value *ucontrol)
546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
547 hda_nid_t nid = kcontrol->private_value & 0xffff;
548 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
549 long *valp = ucontrol->value.integer.value;
550 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
551 AC_VERB_GET_PIN_WIDGET_CONTROL,
554 /* Find enumerated value for current pinctl setting */
555 i = alc_pin_mode_min(dir);
556 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
558 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
562 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
566 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
567 hda_nid_t nid = kcontrol->private_value & 0xffff;
568 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
569 long val = *ucontrol->value.integer.value;
570 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
571 AC_VERB_GET_PIN_WIDGET_CONTROL,
574 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
575 val = alc_pin_mode_min(dir);
577 change = pinctl != alc_pin_mode_values[val];
579 /* Set pin mode to that requested */
580 snd_hda_codec_write_cache(codec, nid, 0,
581 AC_VERB_SET_PIN_WIDGET_CONTROL,
582 alc_pin_mode_values[val]);
584 /* Also enable the retasking pin's input/output as required
585 * for the requested pin mode. Enum values of 2 or less are
588 * Dynamically switching the input/output buffers probably
589 * reduces noise slightly (particularly on input) so we'll
590 * do it. However, having both input and output buffers
591 * enabled simultaneously doesn't seem to be problematic if
592 * this turns out to be necessary in the future.
595 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
596 HDA_AMP_MUTE, HDA_AMP_MUTE);
597 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
600 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
601 HDA_AMP_MUTE, HDA_AMP_MUTE);
602 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
609 #define ALC_PIN_MODE(xname, nid, dir) \
610 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
611 .info = alc_pin_mode_info, \
612 .get = alc_pin_mode_get, \
613 .put = alc_pin_mode_put, \
614 .private_value = nid | (dir<<16) }
616 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
617 * together using a mask with more than one bit set. This control is
618 * currently used only by the ALC260 test model. At this stage they are not
619 * needed for any "production" models.
621 #ifdef CONFIG_SND_DEBUG
622 #define alc_gpio_data_info snd_ctl_boolean_mono_info
624 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_value *ucontrol)
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628 hda_nid_t nid = kcontrol->private_value & 0xffff;
629 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
630 long *valp = ucontrol->value.integer.value;
631 unsigned int val = snd_hda_codec_read(codec, nid, 0,
632 AC_VERB_GET_GPIO_DATA, 0x00);
634 *valp = (val & mask) != 0;
637 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_value *ucontrol)
641 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
642 hda_nid_t nid = kcontrol->private_value & 0xffff;
643 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
644 long val = *ucontrol->value.integer.value;
645 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
646 AC_VERB_GET_GPIO_DATA,
649 /* Set/unset the masked GPIO bit(s) as needed */
650 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
655 snd_hda_codec_write_cache(codec, nid, 0,
656 AC_VERB_SET_GPIO_DATA, gpio_data);
660 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
661 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
662 .info = alc_gpio_data_info, \
663 .get = alc_gpio_data_get, \
664 .put = alc_gpio_data_put, \
665 .private_value = nid | (mask<<16) }
666 #endif /* CONFIG_SND_DEBUG */
668 /* A switch control to allow the enabling of the digital IO pins on the
669 * ALC260. This is incredibly simplistic; the intention of this control is
670 * to provide something in the test model allowing digital outputs to be
671 * identified if present. If models are found which can utilise these
672 * outputs a more complete mixer control can be devised for those models if
675 #ifdef CONFIG_SND_DEBUG
676 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
678 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
679 struct snd_ctl_elem_value *ucontrol)
681 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
682 hda_nid_t nid = kcontrol->private_value & 0xffff;
683 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
684 long *valp = ucontrol->value.integer.value;
685 unsigned int val = snd_hda_codec_read(codec, nid, 0,
686 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
688 *valp = (val & mask) != 0;
691 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
692 struct snd_ctl_elem_value *ucontrol)
695 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
696 hda_nid_t nid = kcontrol->private_value & 0xffff;
697 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
698 long val = *ucontrol->value.integer.value;
699 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
700 AC_VERB_GET_DIGI_CONVERT_1,
703 /* Set/unset the masked control bit(s) as needed */
704 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
709 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
714 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
715 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
716 .info = alc_spdif_ctrl_info, \
717 .get = alc_spdif_ctrl_get, \
718 .put = alc_spdif_ctrl_put, \
719 .private_value = nid | (mask<<16) }
720 #endif /* CONFIG_SND_DEBUG */
722 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
723 * Again, this is only used in the ALC26x test models to help identify when
724 * the EAPD line must be asserted for features to work.
726 #ifdef CONFIG_SND_DEBUG
727 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
729 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
730 struct snd_ctl_elem_value *ucontrol)
732 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
733 hda_nid_t nid = kcontrol->private_value & 0xffff;
734 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
735 long *valp = ucontrol->value.integer.value;
736 unsigned int val = snd_hda_codec_read(codec, nid, 0,
737 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
739 *valp = (val & mask) != 0;
743 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
744 struct snd_ctl_elem_value *ucontrol)
747 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
748 hda_nid_t nid = kcontrol->private_value & 0xffff;
749 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
750 long val = *ucontrol->value.integer.value;
751 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
752 AC_VERB_GET_EAPD_BTLENABLE,
755 /* Set/unset the masked control bit(s) as needed */
756 change = (!val ? 0 : mask) != (ctrl_data & mask);
761 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
767 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
768 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
769 .info = alc_eapd_ctrl_info, \
770 .get = alc_eapd_ctrl_get, \
771 .put = alc_eapd_ctrl_put, \
772 .private_value = nid | (mask<<16) }
773 #endif /* CONFIG_SND_DEBUG */
776 * set up the input pin config (depending on the given auto-pin type)
778 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
781 unsigned int val = PIN_IN;
783 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
785 pincap = snd_hda_query_pin_caps(codec, nid);
786 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
787 if (pincap & AC_PINCAP_VREF_80)
790 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
795 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
797 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
799 spec->mixers[spec->num_mixers++] = mix;
802 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
804 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
806 spec->init_verbs[spec->num_init_verbs++] = verb;
809 #ifdef CONFIG_PROC_FS
813 static void print_realtek_coef(struct snd_info_buffer *buffer,
814 struct hda_codec *codec, hda_nid_t nid)
820 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
821 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
822 coeff = snd_hda_codec_read(codec, nid, 0,
823 AC_VERB_GET_COEF_INDEX, 0);
824 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
827 #define print_realtek_coef NULL
831 * set up from the preset table
833 static void setup_preset(struct alc_spec *spec,
834 const struct alc_config_preset *preset)
838 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
839 add_mixer(spec, preset->mixers[i]);
840 spec->cap_mixer = preset->cap_mixer;
841 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
843 add_verb(spec, preset->init_verbs[i]);
845 spec->channel_mode = preset->channel_mode;
846 spec->num_channel_mode = preset->num_channel_mode;
847 spec->need_dac_fix = preset->need_dac_fix;
849 spec->multiout.max_channels = spec->channel_mode[0].channels;
851 spec->multiout.num_dacs = preset->num_dacs;
852 spec->multiout.dac_nids = preset->dac_nids;
853 spec->multiout.dig_out_nid = preset->dig_out_nid;
854 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
855 spec->multiout.hp_nid = preset->hp_nid;
857 spec->num_mux_defs = preset->num_mux_defs;
858 if (!spec->num_mux_defs)
859 spec->num_mux_defs = 1;
860 spec->input_mux = preset->input_mux;
862 spec->num_adc_nids = preset->num_adc_nids;
863 spec->adc_nids = preset->adc_nids;
864 spec->capsrc_nids = preset->capsrc_nids;
865 spec->dig_in_nid = preset->dig_in_nid;
867 spec->unsol_event = preset->unsol_event;
868 spec->init_hook = preset->init_hook;
869 #ifdef CONFIG_SND_HDA_POWER_SAVE
870 spec->loopback.amplist = preset->loopbacks;
874 /* Enable GPIO mask and set output */
875 static struct hda_verb alc_gpio1_init_verbs[] = {
876 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
877 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
878 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
882 static struct hda_verb alc_gpio2_init_verbs[] = {
883 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
884 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
885 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
889 static struct hda_verb alc_gpio3_init_verbs[] = {
890 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
891 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
892 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
897 * Fix hardware PLL issue
898 * On some codecs, the analog PLL gating control must be off while
899 * the default value is 1.
901 static void alc_fix_pll(struct hda_codec *codec)
903 struct alc_spec *spec = codec->spec;
908 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
910 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
911 AC_VERB_GET_PROC_COEF, 0);
912 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
914 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
915 val & ~(1 << spec->pll_coef_bit));
918 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
919 unsigned int coef_idx, unsigned int coef_bit)
921 struct alc_spec *spec = codec->spec;
923 spec->pll_coef_idx = coef_idx;
924 spec->pll_coef_bit = coef_bit;
928 static void alc_sku_automute(struct hda_codec *codec)
930 struct alc_spec *spec = codec->spec;
931 unsigned int present;
932 unsigned int hp_nid = spec->autocfg.hp_pins[0];
933 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
935 /* need to execute and sync at first */
936 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
937 present = snd_hda_codec_read(codec, hp_nid, 0,
938 AC_VERB_GET_PIN_SENSE, 0);
939 spec->jack_present = (present & 0x80000000) != 0;
940 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
941 spec->jack_present ? 0 : PIN_OUT);
944 #if 0 /* it's broken in some acses -- temporarily disabled */
945 static void alc_mic_automute(struct hda_codec *codec)
947 struct alc_spec *spec = codec->spec;
948 unsigned int present;
949 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
950 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
951 unsigned int mix_nid = spec->capsrc_nids[0];
952 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
954 capsrc_idx_mic = mic_nid - 0x18;
955 capsrc_idx_fmic = fmic_nid - 0x18;
956 present = snd_hda_codec_read(codec, mic_nid, 0,
957 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
958 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
959 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
960 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
961 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
962 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
963 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
966 #define alc_mic_automute(codec) do {} while(0) /* NOP */
967 #endif /* disabled */
969 /* unsolicited event for HP jack sensing */
970 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
972 if (codec->vendor_id == 0x10ec0880)
976 if (res == ALC880_HP_EVENT)
977 alc_sku_automute(codec);
979 if (res == ALC880_MIC_EVENT)
980 alc_mic_automute(codec);
983 static void alc_inithook(struct hda_codec *codec)
985 alc_sku_automute(codec);
986 alc_mic_automute(codec);
989 /* additional initialization for ALC888 variants */
990 static void alc888_coef_init(struct hda_codec *codec)
994 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
995 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
996 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
997 if ((tmp & 0xf0) == 0x20)
999 snd_hda_codec_read(codec, 0x20, 0,
1000 AC_VERB_SET_PROC_COEF, 0x830);
1003 snd_hda_codec_read(codec, 0x20, 0,
1004 AC_VERB_SET_PROC_COEF, 0x3030);
1007 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1012 case ALC_INIT_GPIO1:
1013 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1015 case ALC_INIT_GPIO2:
1016 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1018 case ALC_INIT_GPIO3:
1019 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1021 case ALC_INIT_DEFAULT:
1022 switch (codec->vendor_id) {
1024 snd_hda_codec_write(codec, 0x0f, 0,
1025 AC_VERB_SET_EAPD_BTLENABLE, 2);
1026 snd_hda_codec_write(codec, 0x10, 0,
1027 AC_VERB_SET_EAPD_BTLENABLE, 2);
1039 snd_hda_codec_write(codec, 0x14, 0,
1040 AC_VERB_SET_EAPD_BTLENABLE, 2);
1041 snd_hda_codec_write(codec, 0x15, 0,
1042 AC_VERB_SET_EAPD_BTLENABLE, 2);
1045 switch (codec->vendor_id) {
1047 snd_hda_codec_write(codec, 0x1a, 0,
1048 AC_VERB_SET_COEF_INDEX, 7);
1049 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1050 AC_VERB_GET_PROC_COEF, 0);
1051 snd_hda_codec_write(codec, 0x1a, 0,
1052 AC_VERB_SET_COEF_INDEX, 7);
1053 snd_hda_codec_write(codec, 0x1a, 0,
1054 AC_VERB_SET_PROC_COEF,
1064 snd_hda_codec_write(codec, 0x20, 0,
1065 AC_VERB_SET_COEF_INDEX, 7);
1066 tmp = snd_hda_codec_read(codec, 0x20, 0,
1067 AC_VERB_GET_PROC_COEF, 0);
1068 snd_hda_codec_write(codec, 0x20, 0,
1069 AC_VERB_SET_COEF_INDEX, 7);
1070 snd_hda_codec_write(codec, 0x20, 0,
1071 AC_VERB_SET_PROC_COEF,
1075 alc888_coef_init(codec);
1079 snd_hda_codec_write(codec, 0x20, 0,
1080 AC_VERB_SET_COEF_INDEX, 7);
1081 tmp = snd_hda_codec_read(codec, 0x20, 0,
1082 AC_VERB_GET_PROC_COEF, 0);
1083 snd_hda_codec_write(codec, 0x20, 0,
1084 AC_VERB_SET_COEF_INDEX, 7);
1085 snd_hda_codec_write(codec, 0x20, 0,
1086 AC_VERB_SET_PROC_COEF,
1094 static void alc_init_auto_hp(struct hda_codec *codec)
1096 struct alc_spec *spec = codec->spec;
1098 if (!spec->autocfg.hp_pins[0])
1101 if (!spec->autocfg.speaker_pins[0]) {
1102 if (spec->autocfg.line_out_pins[0])
1103 spec->autocfg.speaker_pins[0] =
1104 spec->autocfg.line_out_pins[0];
1109 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1110 AC_VERB_SET_UNSOLICITED_ENABLE,
1111 AC_USRSP_EN | ALC880_HP_EVENT);
1112 spec->unsol_event = alc_sku_unsol_event;
1115 /* check subsystem ID and set up device-specific initialization;
1116 * return 1 if initialized, 0 if invalid SSID
1118 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1119 * 31 ~ 16 : Manufacture ID
1121 * 7 ~ 0 : Assembly ID
1122 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1124 static int alc_subsystem_id(struct hda_codec *codec,
1125 hda_nid_t porta, hda_nid_t porte,
1128 unsigned int ass, tmp, i;
1130 struct alc_spec *spec = codec->spec;
1132 ass = codec->subsystem_id & 0xffff;
1133 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1136 /* invalid SSID, check the special NID pin defcfg instead */
1138 * 31~30 : port conetcivity
1141 * 19~16 : Check sum (15:1)
1146 if (codec->vendor_id == 0x10ec0260)
1148 ass = snd_hda_codec_get_pincfg(codec, nid);
1149 snd_printd("realtek: No valid SSID, "
1150 "checking pincfg 0x%08x for NID 0x%x\n",
1152 if (!(ass & 1) && !(ass & 0x100000))
1154 if ((ass >> 30) != 1) /* no physical connection */
1159 for (i = 1; i < 16; i++) {
1163 if (((ass >> 16) & 0xf) != tmp)
1166 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1167 ass & 0xffff, codec->vendor_id);
1171 * 2 : 0 --> Desktop, 1 --> Laptop
1172 * 3~5 : External Amplifier control
1175 tmp = (ass & 0x38) >> 3; /* external Amp control */
1178 spec->init_amp = ALC_INIT_GPIO1;
1181 spec->init_amp = ALC_INIT_GPIO2;
1184 spec->init_amp = ALC_INIT_GPIO3;
1187 spec->init_amp = ALC_INIT_DEFAULT;
1191 /* is laptop or Desktop and enable the function "Mute internal speaker
1192 * when the external headphone out jack is plugged"
1194 if (!(ass & 0x8000))
1197 * 10~8 : Jack location
1198 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1200 * 15 : 1 --> enable the function "Mute internal speaker
1201 * when the external headphone out jack is plugged"
1203 if (!spec->autocfg.hp_pins[0]) {
1204 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1206 spec->autocfg.hp_pins[0] = porta;
1208 spec->autocfg.hp_pins[0] = porte;
1210 spec->autocfg.hp_pins[0] = portd;
1215 alc_init_auto_hp(codec);
1219 static void alc_ssid_check(struct hda_codec *codec,
1220 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1222 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1223 struct alc_spec *spec = codec->spec;
1224 snd_printd("realtek: "
1225 "Enable default setup for auto mode as fallback\n");
1226 spec->init_amp = ALC_INIT_DEFAULT;
1227 alc_init_auto_hp(codec);
1232 * Fix-up pin default configurations
1240 static void alc_fix_pincfg(struct hda_codec *codec,
1241 const struct snd_pci_quirk *quirk,
1242 const struct alc_pincfg **pinfix)
1244 const struct alc_pincfg *cfg;
1246 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1250 cfg = pinfix[quirk->value];
1251 for (; cfg->nid; cfg++)
1252 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1262 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1263 /* Mic-in jack as mic in */
1264 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1265 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1266 /* Line-in jack as Line in */
1267 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1268 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1269 /* Line-Out as Front */
1270 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1277 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1278 /* Mic-in jack as mic in */
1279 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1280 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1281 /* Line-in jack as Surround */
1282 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1283 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1284 /* Line-Out as Front */
1285 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1292 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1293 /* Mic-in jack as CLFE */
1294 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1295 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1296 /* Line-in jack as Surround */
1297 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1298 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1299 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1300 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1307 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1308 /* Mic-in jack as CLFE */
1309 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1310 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1311 /* Line-in jack as Surround */
1312 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1313 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1314 /* Line-Out as Side */
1315 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1319 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1320 { 2, alc888_4ST_ch2_intel_init },
1321 { 4, alc888_4ST_ch4_intel_init },
1322 { 6, alc888_4ST_ch6_intel_init },
1323 { 8, alc888_4ST_ch8_intel_init },
1327 * ALC888 Fujitsu Siemens Amillo xa3530
1330 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1331 /* Front Mic: set to PIN_IN (empty by default) */
1332 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1333 /* Connect Internal HP to Front */
1334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1335 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1336 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1337 /* Connect Bass HP to Front */
1338 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1339 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1340 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1341 /* Connect Line-Out side jack (SPDIF) to Side */
1342 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1343 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1344 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1345 /* Connect Mic jack to CLFE */
1346 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1347 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1348 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1349 /* Connect Line-in jack to Surround */
1350 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1351 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1352 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1353 /* Connect HP out jack to Front */
1354 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1355 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1356 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1357 /* Enable unsolicited event for HP jack and Line-out jack */
1358 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1359 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1363 static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1365 unsigned int present;
1367 /* Line out presence */
1368 present = snd_hda_codec_read(codec, 0x17, 0,
1369 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1370 /* HP out presence */
1371 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1372 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1373 bits = present ? HDA_AMP_MUTE : 0;
1374 /* Toggle internal speakers muting */
1375 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1376 HDA_AMP_MUTE, bits);
1377 /* Toggle internal bass muting */
1378 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1379 HDA_AMP_MUTE, bits);
1382 static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1385 if (res >> 26 == ALC880_HP_EVENT)
1386 alc888_fujitsu_xa3530_automute(codec);
1391 * ALC888 Acer Aspire 4930G model
1394 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1395 /* Front Mic: set to PIN_IN (empty by default) */
1396 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1397 /* Unselect Front Mic by default in input mixer 3 */
1398 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1399 /* Enable unsolicited event for HP jack */
1400 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1401 /* Connect Internal HP to front */
1402 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1403 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1404 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1405 /* Connect HP out to front */
1406 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1407 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1408 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1412 static struct hda_input_mux alc888_2_capture_sources[2] = {
1413 /* Front mic only available on one ADC */
1420 { "Front Mic", 0xb },
1433 static struct snd_kcontrol_new alc888_base_mixer[] = {
1434 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1435 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1436 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1437 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1438 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1440 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1441 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1442 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1443 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1444 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1445 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1446 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1447 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1448 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1449 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1450 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1451 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1455 static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1457 unsigned int present;
1459 present = snd_hda_codec_read(codec, 0x15, 0,
1460 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1461 bits = present ? HDA_AMP_MUTE : 0;
1462 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1463 HDA_AMP_MUTE, bits);
1466 static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1469 if (res >> 26 == ALC880_HP_EVENT)
1470 alc888_acer_aspire_4930g_automute(codec);
1474 * ALC880 3-stack model
1476 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1477 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1478 * F-Mic = 0x1b, HP = 0x19
1481 static hda_nid_t alc880_dac_nids[4] = {
1482 /* front, rear, clfe, rear_surr */
1483 0x02, 0x05, 0x04, 0x03
1486 static hda_nid_t alc880_adc_nids[3] = {
1491 /* The datasheet says the node 0x07 is connected from inputs,
1492 * but it shows zero connection in the real implementation on some devices.
1493 * Note: this is a 915GAV bug, fixed on 915GLV
1495 static hda_nid_t alc880_adc_nids_alt[2] = {
1500 #define ALC880_DIGOUT_NID 0x06
1501 #define ALC880_DIGIN_NID 0x0a
1503 static struct hda_input_mux alc880_capture_source = {
1507 { "Front Mic", 0x3 },
1513 /* channel source setting (2/6 channel selection for 3-stack) */
1515 static struct hda_verb alc880_threestack_ch2_init[] = {
1516 /* set line-in to input, mute it */
1517 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1518 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1519 /* set mic-in to input vref 80%, mute it */
1520 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1521 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1526 static struct hda_verb alc880_threestack_ch6_init[] = {
1527 /* set line-in to output, unmute it */
1528 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1529 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1530 /* set mic-in to output, unmute it */
1531 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1532 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1536 static struct hda_channel_mode alc880_threestack_modes[2] = {
1537 { 2, alc880_threestack_ch2_init },
1538 { 6, alc880_threestack_ch6_init },
1541 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1542 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1543 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1544 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1545 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1546 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1547 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1548 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1550 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1551 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1560 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1561 .name = "Channel Mode",
1562 .info = alc_ch_mode_info,
1563 .get = alc_ch_mode_get,
1564 .put = alc_ch_mode_put,
1569 /* capture mixer elements */
1570 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1571 struct snd_ctl_elem_info *uinfo)
1573 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1574 struct alc_spec *spec = codec->spec;
1577 mutex_lock(&codec->control_mutex);
1578 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1580 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1581 mutex_unlock(&codec->control_mutex);
1585 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1586 unsigned int size, unsigned int __user *tlv)
1588 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1589 struct alc_spec *spec = codec->spec;
1592 mutex_lock(&codec->control_mutex);
1593 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1595 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1596 mutex_unlock(&codec->control_mutex);
1600 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1601 struct snd_ctl_elem_value *ucontrol);
1603 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1604 struct snd_ctl_elem_value *ucontrol,
1607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1608 struct alc_spec *spec = codec->spec;
1609 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1612 mutex_lock(&codec->control_mutex);
1613 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1615 err = func(kcontrol, ucontrol);
1616 mutex_unlock(&codec->control_mutex);
1620 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1621 struct snd_ctl_elem_value *ucontrol)
1623 return alc_cap_getput_caller(kcontrol, ucontrol,
1624 snd_hda_mixer_amp_volume_get);
1627 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1628 struct snd_ctl_elem_value *ucontrol)
1630 return alc_cap_getput_caller(kcontrol, ucontrol,
1631 snd_hda_mixer_amp_volume_put);
1634 /* capture mixer elements */
1635 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1637 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1638 struct snd_ctl_elem_value *ucontrol)
1640 return alc_cap_getput_caller(kcontrol, ucontrol,
1641 snd_hda_mixer_amp_switch_get);
1644 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1645 struct snd_ctl_elem_value *ucontrol)
1647 return alc_cap_getput_caller(kcontrol, ucontrol,
1648 snd_hda_mixer_amp_switch_put);
1651 #define _DEFINE_CAPMIX(num) \
1653 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1654 .name = "Capture Switch", \
1655 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1657 .info = alc_cap_sw_info, \
1658 .get = alc_cap_sw_get, \
1659 .put = alc_cap_sw_put, \
1662 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1663 .name = "Capture Volume", \
1664 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1665 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1666 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1668 .info = alc_cap_vol_info, \
1669 .get = alc_cap_vol_get, \
1670 .put = alc_cap_vol_put, \
1671 .tlv = { .c = alc_cap_vol_tlv }, \
1674 #define _DEFINE_CAPSRC(num) \
1676 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1677 /* .name = "Capture Source", */ \
1678 .name = "Input Source", \
1680 .info = alc_mux_enum_info, \
1681 .get = alc_mux_enum_get, \
1682 .put = alc_mux_enum_put, \
1685 #define DEFINE_CAPMIX(num) \
1686 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1687 _DEFINE_CAPMIX(num), \
1688 _DEFINE_CAPSRC(num), \
1692 #define DEFINE_CAPMIX_NOSRC(num) \
1693 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1694 _DEFINE_CAPMIX(num), \
1698 /* up to three ADCs */
1702 DEFINE_CAPMIX_NOSRC(1);
1703 DEFINE_CAPMIX_NOSRC(2);
1704 DEFINE_CAPMIX_NOSRC(3);
1707 * ALC880 5-stack model
1709 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1711 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1712 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1715 /* additional mixers to alc880_three_stack_mixer */
1716 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1717 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1718 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1722 /* channel source setting (6/8 channel selection for 5-stack) */
1724 static struct hda_verb alc880_fivestack_ch6_init[] = {
1725 /* set line-in to input, mute it */
1726 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1727 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1732 static struct hda_verb alc880_fivestack_ch8_init[] = {
1733 /* set line-in to output, unmute it */
1734 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1735 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1739 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1740 { 6, alc880_fivestack_ch6_init },
1741 { 8, alc880_fivestack_ch8_init },
1746 * ALC880 6-stack model
1748 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1749 * Side = 0x05 (0x0f)
1750 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1751 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1754 static hda_nid_t alc880_6st_dac_nids[4] = {
1755 /* front, rear, clfe, rear_surr */
1756 0x02, 0x03, 0x04, 0x05
1759 static struct hda_input_mux alc880_6stack_capture_source = {
1763 { "Front Mic", 0x1 },
1769 /* fixed 8-channels */
1770 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1774 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1775 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1776 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1777 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1778 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1779 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1780 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1781 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1782 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1783 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1784 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1785 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1786 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1787 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1788 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1791 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1792 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1795 .name = "Channel Mode",
1796 .info = alc_ch_mode_info,
1797 .get = alc_ch_mode_get,
1798 .put = alc_ch_mode_put,
1807 * W810 has rear IO for:
1810 * Center/LFE (DAC 04)
1813 * The system also has a pair of internal speakers, and a headphone jack.
1814 * These are both connected to Line2 on the codec, hence to DAC 02.
1816 * There is a variable resistor to control the speaker or headphone
1817 * volume. This is a hardware-only device without a software API.
1819 * Plugging headphones in will disable the internal speakers. This is
1820 * implemented in hardware, not via the driver using jack sense. In
1821 * a similar fashion, plugging into the rear socket marked "front" will
1822 * disable both the speakers and headphones.
1824 * For input, there's a microphone jack, and an "audio in" jack.
1825 * These may not do anything useful with this driver yet, because I
1826 * haven't setup any initialization verbs for these yet...
1829 static hda_nid_t alc880_w810_dac_nids[3] = {
1830 /* front, rear/surround, clfe */
1834 /* fixed 6 channels */
1835 static struct hda_channel_mode alc880_w810_modes[1] = {
1839 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1840 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1841 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1842 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1843 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1844 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1845 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1846 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1847 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1848 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1849 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1857 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1858 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1862 static hda_nid_t alc880_z71v_dac_nids[1] = {
1865 #define ALC880_Z71V_HP_DAC 0x03
1867 /* fixed 2 channels */
1868 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1872 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1873 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1874 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1875 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1876 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1877 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1878 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1879 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1880 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1886 * ALC880 F1734 model
1888 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1889 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1892 static hda_nid_t alc880_f1734_dac_nids[1] = {
1895 #define ALC880_F1734_HP_DAC 0x02
1897 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1898 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1899 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1900 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1901 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1902 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1903 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1909 static struct hda_input_mux alc880_f1734_capture_source = {
1921 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1922 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1923 * Mic = 0x18, Line = 0x1a
1926 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1927 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1929 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1930 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1931 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1932 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1933 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1934 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1935 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1936 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1937 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1938 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1939 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1940 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1941 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1942 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1943 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1945 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1946 .name = "Channel Mode",
1947 .info = alc_ch_mode_info,
1948 .get = alc_ch_mode_get,
1949 .put = alc_ch_mode_put,
1955 * ALC880 ASUS W1V model
1957 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1958 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1959 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1962 /* additional mixers to alc880_asus_mixer */
1963 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1964 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1965 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1970 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1971 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1972 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1973 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1974 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1975 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1978 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1979 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1984 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1985 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1986 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1987 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1988 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1989 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1990 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1991 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1992 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1993 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1994 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2003 .name = "Channel Mode",
2004 .info = alc_ch_mode_info,
2005 .get = alc_ch_mode_get,
2006 .put = alc_ch_mode_put,
2011 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2012 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2013 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2014 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2015 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2016 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2017 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2018 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2019 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2020 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2021 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2025 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2026 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2027 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2028 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2029 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2030 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2036 * virtual master controls
2040 * slave controls for virtual master
2042 static const char *alc_slave_vols[] = {
2043 "Front Playback Volume",
2044 "Surround Playback Volume",
2045 "Center Playback Volume",
2046 "LFE Playback Volume",
2047 "Side Playback Volume",
2048 "Headphone Playback Volume",
2049 "Speaker Playback Volume",
2050 "Mono Playback Volume",
2051 "Line-Out Playback Volume",
2052 "PCM Playback Volume",
2056 static const char *alc_slave_sws[] = {
2057 "Front Playback Switch",
2058 "Surround Playback Switch",
2059 "Center Playback Switch",
2060 "LFE Playback Switch",
2061 "Side Playback Switch",
2062 "Headphone Playback Switch",
2063 "Speaker Playback Switch",
2064 "Mono Playback Switch",
2065 "IEC958 Playback Switch",
2070 * build control elements
2073 static void alc_free_kctls(struct hda_codec *codec);
2075 /* additional beep mixers; the actual parameters are overwritten at build */
2076 static struct snd_kcontrol_new alc_beep_mixer[] = {
2077 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2078 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2082 static int alc_build_controls(struct hda_codec *codec)
2084 struct alc_spec *spec = codec->spec;
2088 for (i = 0; i < spec->num_mixers; i++) {
2089 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2093 if (spec->cap_mixer) {
2094 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2098 if (spec->multiout.dig_out_nid) {
2099 err = snd_hda_create_spdif_out_ctls(codec,
2100 spec->multiout.dig_out_nid);
2103 if (!spec->no_analog) {
2104 err = snd_hda_create_spdif_share_sw(codec,
2108 spec->multiout.share_spdif = 1;
2111 if (spec->dig_in_nid) {
2112 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2117 /* create beep controls if needed */
2118 if (spec->beep_amp) {
2119 struct snd_kcontrol_new *knew;
2120 for (knew = alc_beep_mixer; knew->name; knew++) {
2121 struct snd_kcontrol *kctl;
2122 kctl = snd_ctl_new1(knew, codec);
2125 kctl->private_value = spec->beep_amp;
2126 err = snd_hda_ctl_add(codec, kctl);
2132 /* if we have no master control, let's create it */
2133 if (!spec->no_analog &&
2134 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2135 unsigned int vmaster_tlv[4];
2136 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2137 HDA_OUTPUT, vmaster_tlv);
2138 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2139 vmaster_tlv, alc_slave_vols);
2143 if (!spec->no_analog &&
2144 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2145 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2146 NULL, alc_slave_sws);
2151 alc_free_kctls(codec); /* no longer needed */
2157 * initialize the codec volumes, etc
2161 * generic initialization of ADC, input mixers and output mixers
2163 static struct hda_verb alc880_volume_init_verbs[] = {
2165 * Unmute ADC0-2 and set the default input to mic-in
2167 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2169 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2170 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2171 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2172 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2174 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2176 * Note: PASD motherboards uses the Line In 2 as the input for front
2179 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2180 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2181 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2182 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2183 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2184 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2185 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2186 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2189 * Set up output mixers (0x0c - 0x0f)
2191 /* set vol=0 to output mixers */
2192 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2193 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2194 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2195 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2196 /* set up input amps for analog loopback */
2197 /* Amp Indices: DAC = 0, mixer = 1 */
2198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2200 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2202 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2203 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2204 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2205 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2211 * 3-stack pin configuration:
2212 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2214 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2216 * preset connection lists of input pins
2217 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2219 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2220 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2221 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2224 * Set pin mode and muting
2226 /* set front pin widgets 0x14 for output */
2227 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2228 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2230 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2231 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2232 /* Mic2 (as headphone out) for HP output */
2233 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2235 /* Line In pin widget for input */
2236 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2238 /* Line2 (as front mic) pin widget for input and vref at 80% */
2239 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2240 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2241 /* CD pin widget for input */
2242 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2248 * 5-stack pin configuration:
2249 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2250 * line-in/side = 0x1a, f-mic = 0x1b
2252 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2254 * preset connection lists of input pins
2255 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2257 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2258 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2261 * Set pin mode and muting
2263 /* set pin widgets 0x14-0x17 for output */
2264 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2265 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2266 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2267 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2268 /* unmute pins for output (no gain on this amp) */
2269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2271 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2272 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2274 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2275 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2276 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2277 /* Mic2 (as headphone out) for HP output */
2278 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2279 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2280 /* Line In pin widget for input */
2281 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2282 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2283 /* Line2 (as front mic) pin widget for input and vref at 80% */
2284 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2285 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2286 /* CD pin widget for input */
2287 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2293 * W810 pin configuration:
2294 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2296 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2297 /* hphone/speaker input selector: front DAC */
2298 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2300 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2301 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2302 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2303 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2304 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2305 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2307 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2308 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2314 * Z71V pin configuration:
2315 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2317 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2318 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2319 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2320 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2321 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2323 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2324 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2325 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2326 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2332 * 6-stack pin configuration:
2333 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2334 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2336 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2337 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2340 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2341 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2342 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2343 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2344 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2345 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2346 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2348 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2349 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2350 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2351 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2352 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2353 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2354 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2355 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2362 * Uniwill pin configuration:
2363 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2366 static struct hda_verb alc880_uniwill_init_verbs[] = {
2367 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2370 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2373 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2374 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2375 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2376 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2377 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2378 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2379 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2380 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2381 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2382 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2384 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2385 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2386 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2387 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2388 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2389 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2390 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2391 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2392 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2394 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2395 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2402 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2404 static struct hda_verb alc880_uniwill_p53_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 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2415 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2417 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2420 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2421 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2422 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2423 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2424 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2427 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2428 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2433 static struct hda_verb alc880_beep_init_verbs[] = {
2434 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2438 /* toggle speaker-output according to the hp-jack state */
2439 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2441 unsigned int present;
2444 present = snd_hda_codec_read(codec, 0x14, 0,
2445 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2446 bits = present ? HDA_AMP_MUTE : 0;
2447 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2448 HDA_AMP_MUTE, bits);
2449 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2450 HDA_AMP_MUTE, bits);
2453 /* auto-toggle front mic */
2454 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2456 unsigned int present;
2459 present = snd_hda_codec_read(codec, 0x18, 0,
2460 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2461 bits = present ? HDA_AMP_MUTE : 0;
2462 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2465 static void alc880_uniwill_automute(struct hda_codec *codec)
2467 alc880_uniwill_hp_automute(codec);
2468 alc880_uniwill_mic_automute(codec);
2471 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2474 /* Looks like the unsol event is incompatible with the standard
2475 * definition. 4bit tag is placed at 28 bit!
2477 switch (res >> 28) {
2478 case ALC880_HP_EVENT:
2479 alc880_uniwill_hp_automute(codec);
2481 case ALC880_MIC_EVENT:
2482 alc880_uniwill_mic_automute(codec);
2487 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2489 unsigned int present;
2492 present = snd_hda_codec_read(codec, 0x14, 0,
2493 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2494 bits = present ? HDA_AMP_MUTE : 0;
2495 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2498 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2500 unsigned int present;
2502 present = snd_hda_codec_read(codec, 0x21, 0,
2503 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2504 present &= HDA_AMP_VOLMASK;
2505 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2506 HDA_AMP_VOLMASK, present);
2507 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2508 HDA_AMP_VOLMASK, present);
2511 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2514 /* Looks like the unsol event is incompatible with the standard
2515 * definition. 4bit tag is placed at 28 bit!
2517 if ((res >> 28) == ALC880_HP_EVENT)
2518 alc880_uniwill_p53_hp_automute(codec);
2519 if ((res >> 28) == ALC880_DCVOL_EVENT)
2520 alc880_uniwill_p53_dcvol_automute(codec);
2524 * F1734 pin configuration:
2525 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2527 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2528 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2529 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2530 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2531 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2532 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2536 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2537 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2539 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2540 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2541 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2542 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2545 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2546 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2549 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2550 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2556 * ASUS pin configuration:
2557 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2559 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2560 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2561 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2562 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2563 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2566 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2567 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2568 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2569 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2570 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2571 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2572 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2574 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2576 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2577 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2578 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2579 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2580 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2581 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2582 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2587 /* Enable GPIO mask and set output */
2588 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2589 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2591 /* Clevo m520g init */
2592 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2593 /* headphone output */
2594 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2596 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2597 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2602 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2603 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2604 /* Mic1 (rear panel) */
2605 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2606 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2607 /* Mic2 (front panel) */
2608 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2609 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2611 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2612 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2613 /* change to EAPD mode */
2614 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2615 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2620 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2621 /* change to EAPD mode */
2622 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2623 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2625 /* Headphone output */
2626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2628 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2629 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2631 /* Line In pin widget for input */
2632 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2633 /* CD pin widget for input */
2634 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2635 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2636 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2638 /* change to EAPD mode */
2639 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2640 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2646 * LG m1 express dual
2649 * Rear Line-In/Out (blue): 0x14
2650 * Build-in Mic-In: 0x15
2652 * HP-Out (green): 0x1b
2653 * Mic-In/Out (red): 0x19
2657 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2658 static hda_nid_t alc880_lg_dac_nids[3] = {
2662 /* seems analog CD is not working */
2663 static struct hda_input_mux alc880_lg_capture_source = {
2668 { "Internal Mic", 0x6 },
2672 /* 2,4,6 channel modes */
2673 static struct hda_verb alc880_lg_ch2_init[] = {
2674 /* set line-in and mic-in to input */
2675 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2676 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2680 static struct hda_verb alc880_lg_ch4_init[] = {
2681 /* set line-in to out and mic-in to input */
2682 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2683 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2687 static struct hda_verb alc880_lg_ch6_init[] = {
2688 /* set line-in and mic-in to output */
2689 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2690 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2694 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2695 { 2, alc880_lg_ch2_init },
2696 { 4, alc880_lg_ch4_init },
2697 { 6, alc880_lg_ch6_init },
2700 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2701 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2702 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2703 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2704 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2705 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2706 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2707 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2708 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2711 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2712 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2713 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2714 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2717 .name = "Channel Mode",
2718 .info = alc_ch_mode_info,
2719 .get = alc_ch_mode_get,
2720 .put = alc_ch_mode_put,
2725 static struct hda_verb alc880_lg_init_verbs[] = {
2726 /* set capture source to mic-in */
2727 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2728 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2729 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2730 /* mute all amp mixer inputs */
2731 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2732 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2733 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2734 /* line-in to input */
2735 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2736 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2738 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2739 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2741 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2742 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2743 /* mic-in to input */
2744 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2745 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2746 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2748 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2749 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2750 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2752 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2756 /* toggle speaker-output according to the hp-jack state */
2757 static void alc880_lg_automute(struct hda_codec *codec)
2759 unsigned int present;
2762 present = snd_hda_codec_read(codec, 0x1b, 0,
2763 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2764 bits = present ? HDA_AMP_MUTE : 0;
2765 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2766 HDA_AMP_MUTE, bits);
2769 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2771 /* Looks like the unsol event is incompatible with the standard
2772 * definition. 4bit tag is placed at 28 bit!
2774 if ((res >> 28) == 0x01)
2775 alc880_lg_automute(codec);
2784 * Built-in Mic-In: 0x19
2790 static struct hda_input_mux alc880_lg_lw_capture_source = {
2794 { "Internal Mic", 0x1 },
2799 #define alc880_lg_lw_modes alc880_threestack_modes
2801 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2802 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2803 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2804 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2805 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2806 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2807 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2808 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2809 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2810 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2811 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2812 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2813 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2814 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2815 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2818 .name = "Channel Mode",
2819 .info = alc_ch_mode_info,
2820 .get = alc_ch_mode_get,
2821 .put = alc_ch_mode_put,
2826 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2827 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2828 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2829 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2831 /* set capture source to mic-in */
2832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2834 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2837 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2838 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2840 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2841 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2842 /* mic-in to input */
2843 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2844 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2846 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2847 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2849 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2853 /* toggle speaker-output according to the hp-jack state */
2854 static void alc880_lg_lw_automute(struct hda_codec *codec)
2856 unsigned int present;
2859 present = snd_hda_codec_read(codec, 0x1b, 0,
2860 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2861 bits = present ? HDA_AMP_MUTE : 0;
2862 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2863 HDA_AMP_MUTE, bits);
2866 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2868 /* Looks like the unsol event is incompatible with the standard
2869 * definition. 4bit tag is placed at 28 bit!
2871 if ((res >> 28) == 0x01)
2872 alc880_lg_lw_automute(codec);
2875 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2876 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2877 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2881 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2885 static struct hda_input_mux alc880_medion_rim_capture_source = {
2889 { "Internal Mic", 0x1 },
2893 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2894 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2896 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2897 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2899 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2900 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2901 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2902 /* Mic2 (as headphone out) for HP output */
2903 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2904 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2905 /* Internal Speaker */
2906 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2907 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2909 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2910 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2912 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2916 /* toggle speaker-output according to the hp-jack state */
2917 static void alc880_medion_rim_automute(struct hda_codec *codec)
2919 unsigned int present;
2922 present = snd_hda_codec_read(codec, 0x14, 0,
2923 AC_VERB_GET_PIN_SENSE, 0)
2924 & AC_PINSENSE_PRESENCE;
2925 bits = present ? HDA_AMP_MUTE : 0;
2926 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2927 HDA_AMP_MUTE, bits);
2929 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2931 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2934 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2937 /* Looks like the unsol event is incompatible with the standard
2938 * definition. 4bit tag is placed at 28 bit!
2940 if ((res >> 28) == ALC880_HP_EVENT)
2941 alc880_medion_rim_automute(codec);
2944 #ifdef CONFIG_SND_HDA_POWER_SAVE
2945 static struct hda_amp_list alc880_loopbacks[] = {
2946 { 0x0b, HDA_INPUT, 0 },
2947 { 0x0b, HDA_INPUT, 1 },
2948 { 0x0b, HDA_INPUT, 2 },
2949 { 0x0b, HDA_INPUT, 3 },
2950 { 0x0b, HDA_INPUT, 4 },
2954 static struct hda_amp_list alc880_lg_loopbacks[] = {
2955 { 0x0b, HDA_INPUT, 1 },
2956 { 0x0b, HDA_INPUT, 6 },
2957 { 0x0b, HDA_INPUT, 7 },
2966 static int alc_init(struct hda_codec *codec)
2968 struct alc_spec *spec = codec->spec;
2972 alc_auto_init_amp(codec, spec->init_amp);
2974 for (i = 0; i < spec->num_init_verbs; i++)
2975 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2977 if (spec->init_hook)
2978 spec->init_hook(codec);
2983 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2985 struct alc_spec *spec = codec->spec;
2987 if (spec->unsol_event)
2988 spec->unsol_event(codec, res);
2991 #ifdef CONFIG_SND_HDA_POWER_SAVE
2992 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2994 struct alc_spec *spec = codec->spec;
2995 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3000 * Analog playback callbacks
3002 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3003 struct hda_codec *codec,
3004 struct snd_pcm_substream *substream)
3006 struct alc_spec *spec = codec->spec;
3007 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3011 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3012 struct hda_codec *codec,
3013 unsigned int stream_tag,
3014 unsigned int format,
3015 struct snd_pcm_substream *substream)
3017 struct alc_spec *spec = codec->spec;
3018 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3019 stream_tag, format, substream);
3022 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3023 struct hda_codec *codec,
3024 struct snd_pcm_substream *substream)
3026 struct alc_spec *spec = codec->spec;
3027 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3033 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3034 struct hda_codec *codec,
3035 struct snd_pcm_substream *substream)
3037 struct alc_spec *spec = codec->spec;
3038 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3041 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3042 struct hda_codec *codec,
3043 unsigned int stream_tag,
3044 unsigned int format,
3045 struct snd_pcm_substream *substream)
3047 struct alc_spec *spec = codec->spec;
3048 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3049 stream_tag, format, substream);
3052 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3053 struct hda_codec *codec,
3054 struct snd_pcm_substream *substream)
3056 struct alc_spec *spec = codec->spec;
3057 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3060 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3061 struct hda_codec *codec,
3062 struct snd_pcm_substream *substream)
3064 struct alc_spec *spec = codec->spec;
3065 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3071 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3072 struct hda_codec *codec,
3073 unsigned int stream_tag,
3074 unsigned int format,
3075 struct snd_pcm_substream *substream)
3077 struct alc_spec *spec = codec->spec;
3079 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3080 stream_tag, 0, format);
3084 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3085 struct hda_codec *codec,
3086 struct snd_pcm_substream *substream)
3088 struct alc_spec *spec = codec->spec;
3090 snd_hda_codec_cleanup_stream(codec,
3091 spec->adc_nids[substream->number + 1]);
3098 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3102 /* NID is set in alc_build_pcms */
3104 .open = alc880_playback_pcm_open,
3105 .prepare = alc880_playback_pcm_prepare,
3106 .cleanup = alc880_playback_pcm_cleanup
3110 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3114 /* NID is set in alc_build_pcms */
3117 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3121 /* NID is set in alc_build_pcms */
3124 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3125 .substreams = 2, /* can be overridden */
3128 /* NID is set in alc_build_pcms */
3130 .prepare = alc880_alt_capture_pcm_prepare,
3131 .cleanup = alc880_alt_capture_pcm_cleanup
3135 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3139 /* NID is set in alc_build_pcms */
3141 .open = alc880_dig_playback_pcm_open,
3142 .close = alc880_dig_playback_pcm_close,
3143 .prepare = alc880_dig_playback_pcm_prepare,
3144 .cleanup = alc880_dig_playback_pcm_cleanup
3148 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3152 /* NID is set in alc_build_pcms */
3155 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3156 static struct hda_pcm_stream alc_pcm_null_stream = {
3162 static int alc_build_pcms(struct hda_codec *codec)
3164 struct alc_spec *spec = codec->spec;
3165 struct hda_pcm *info = spec->pcm_rec;
3168 codec->num_pcms = 1;
3169 codec->pcm_info = info;
3171 if (spec->no_analog)
3174 info->name = spec->stream_name_analog;
3175 if (spec->stream_analog_playback) {
3176 if (snd_BUG_ON(!spec->multiout.dac_nids))
3178 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3179 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3181 if (spec->stream_analog_capture) {
3182 if (snd_BUG_ON(!spec->adc_nids))
3184 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3185 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3188 if (spec->channel_mode) {
3189 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3190 for (i = 0; i < spec->num_channel_mode; i++) {
3191 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3192 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3198 /* SPDIF for stream index #1 */
3199 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3200 codec->num_pcms = 2;
3201 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3202 info = spec->pcm_rec + 1;
3203 info->name = spec->stream_name_digital;
3204 if (spec->dig_out_type)
3205 info->pcm_type = spec->dig_out_type;
3207 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3208 if (spec->multiout.dig_out_nid &&
3209 spec->stream_digital_playback) {
3210 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3211 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3213 if (spec->dig_in_nid &&
3214 spec->stream_digital_capture) {
3215 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3216 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3218 /* FIXME: do we need this for all Realtek codec models? */
3219 codec->spdif_status_reset = 1;
3222 if (spec->no_analog)
3225 /* If the use of more than one ADC is requested for the current
3226 * model, configure a second analog capture-only PCM.
3228 /* Additional Analaog capture for index #2 */
3229 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3230 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3231 codec->num_pcms = 3;
3232 info = spec->pcm_rec + 2;
3233 info->name = spec->stream_name_analog;
3234 if (spec->alt_dac_nid) {
3235 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3236 *spec->stream_analog_alt_playback;
3237 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3240 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3241 alc_pcm_null_stream;
3242 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3244 if (spec->num_adc_nids > 1) {
3245 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3246 *spec->stream_analog_alt_capture;
3247 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3249 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3250 spec->num_adc_nids - 1;
3252 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3253 alc_pcm_null_stream;
3254 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3261 static void alc_free_kctls(struct hda_codec *codec)
3263 struct alc_spec *spec = codec->spec;
3265 if (spec->kctls.list) {
3266 struct snd_kcontrol_new *kctl = spec->kctls.list;
3268 for (i = 0; i < spec->kctls.used; i++)
3269 kfree(kctl[i].name);
3271 snd_array_free(&spec->kctls);
3274 static void alc_free(struct hda_codec *codec)
3276 struct alc_spec *spec = codec->spec;
3281 alc_free_kctls(codec);
3283 snd_hda_detach_beep_device(codec);
3286 #ifdef SND_HDA_NEEDS_RESUME
3287 static int alc_resume(struct hda_codec *codec)
3289 codec->patch_ops.init(codec);
3290 snd_hda_codec_resume_amp(codec);
3291 snd_hda_codec_resume_cache(codec);
3298 static struct hda_codec_ops alc_patch_ops = {
3299 .build_controls = alc_build_controls,
3300 .build_pcms = alc_build_pcms,
3303 .unsol_event = alc_unsol_event,
3304 #ifdef SND_HDA_NEEDS_RESUME
3305 .resume = alc_resume,
3307 #ifdef CONFIG_SND_HDA_POWER_SAVE
3308 .check_power_status = alc_check_power_status,
3314 * Test configuration for debugging
3316 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3319 #ifdef CONFIG_SND_DEBUG
3320 static hda_nid_t alc880_test_dac_nids[4] = {
3321 0x02, 0x03, 0x04, 0x05
3324 static struct hda_input_mux alc880_test_capture_source = {
3333 { "Surround", 0x6 },
3337 static struct hda_channel_mode alc880_test_modes[4] = {
3344 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3345 struct snd_ctl_elem_info *uinfo)
3347 static char *texts[] = {
3348 "N/A", "Line Out", "HP Out",
3349 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3351 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3353 uinfo->value.enumerated.items = 8;
3354 if (uinfo->value.enumerated.item >= 8)
3355 uinfo->value.enumerated.item = 7;
3356 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3360 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3361 struct snd_ctl_elem_value *ucontrol)
3363 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3364 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3365 unsigned int pin_ctl, item = 0;
3367 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3368 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3369 if (pin_ctl & AC_PINCTL_OUT_EN) {
3370 if (pin_ctl & AC_PINCTL_HP_EN)
3374 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3375 switch (pin_ctl & AC_PINCTL_VREFEN) {
3376 case AC_PINCTL_VREF_HIZ: item = 3; break;
3377 case AC_PINCTL_VREF_50: item = 4; break;
3378 case AC_PINCTL_VREF_GRD: item = 5; break;
3379 case AC_PINCTL_VREF_80: item = 6; break;
3380 case AC_PINCTL_VREF_100: item = 7; break;
3383 ucontrol->value.enumerated.item[0] = item;
3387 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3388 struct snd_ctl_elem_value *ucontrol)
3390 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3391 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3392 static unsigned int ctls[] = {
3393 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3394 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3395 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3396 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3397 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3398 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3400 unsigned int old_ctl, new_ctl;
3402 old_ctl = snd_hda_codec_read(codec, nid, 0,
3403 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3404 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3405 if (old_ctl != new_ctl) {
3407 snd_hda_codec_write_cache(codec, nid, 0,
3408 AC_VERB_SET_PIN_WIDGET_CONTROL,
3410 val = ucontrol->value.enumerated.item[0] >= 3 ?
3412 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3419 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3420 struct snd_ctl_elem_info *uinfo)
3422 static char *texts[] = {
3423 "Front", "Surround", "CLFE", "Side"
3425 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3427 uinfo->value.enumerated.items = 4;
3428 if (uinfo->value.enumerated.item >= 4)
3429 uinfo->value.enumerated.item = 3;
3430 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3434 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3435 struct snd_ctl_elem_value *ucontrol)
3437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3438 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3441 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3442 ucontrol->value.enumerated.item[0] = sel & 3;
3446 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3447 struct snd_ctl_elem_value *ucontrol)
3449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3450 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3453 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3454 if (ucontrol->value.enumerated.item[0] != sel) {
3455 sel = ucontrol->value.enumerated.item[0] & 3;
3456 snd_hda_codec_write_cache(codec, nid, 0,
3457 AC_VERB_SET_CONNECT_SEL, sel);
3463 #define PIN_CTL_TEST(xname,nid) { \
3464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3466 .info = alc_test_pin_ctl_info, \
3467 .get = alc_test_pin_ctl_get, \
3468 .put = alc_test_pin_ctl_put, \
3469 .private_value = nid \
3472 #define PIN_SRC_TEST(xname,nid) { \
3473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3475 .info = alc_test_pin_src_info, \
3476 .get = alc_test_pin_src_get, \
3477 .put = alc_test_pin_src_put, \
3478 .private_value = nid \
3481 static struct snd_kcontrol_new alc880_test_mixer[] = {
3482 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3483 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3484 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3485 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3486 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3487 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3488 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3489 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3490 PIN_CTL_TEST("Front Pin Mode", 0x14),
3491 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3492 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3493 PIN_CTL_TEST("Side Pin Mode", 0x17),
3494 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3495 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3496 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3497 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3498 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3499 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3500 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3501 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3502 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3503 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3504 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3505 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3506 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3507 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3508 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3509 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3510 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3511 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3514 .name = "Channel Mode",
3515 .info = alc_ch_mode_info,
3516 .get = alc_ch_mode_get,
3517 .put = alc_ch_mode_put,
3522 static struct hda_verb alc880_test_init_verbs[] = {
3523 /* Unmute inputs of 0x0c - 0x0f */
3524 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3525 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3526 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3527 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3528 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3529 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3530 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3531 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3532 /* Vol output for 0x0c-0x0f */
3533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3535 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3536 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3537 /* Set output pins 0x14-0x17 */
3538 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3540 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3541 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3542 /* Unmute output pins 0x14-0x17 */
3543 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3545 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3546 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3547 /* Set input pins 0x18-0x1c */
3548 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3549 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3550 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3551 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3552 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3553 /* Mute input pins 0x18-0x1b */
3554 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3556 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3559 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3560 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3562 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3563 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3564 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3565 /* Analog input/passthru */
3566 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3568 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3569 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3570 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3578 static const char *alc880_models[ALC880_MODEL_LAST] = {
3579 [ALC880_3ST] = "3stack",
3580 [ALC880_TCL_S700] = "tcl",
3581 [ALC880_3ST_DIG] = "3stack-digout",
3582 [ALC880_CLEVO] = "clevo",
3583 [ALC880_5ST] = "5stack",
3584 [ALC880_5ST_DIG] = "5stack-digout",
3585 [ALC880_W810] = "w810",
3586 [ALC880_Z71V] = "z71v",
3587 [ALC880_6ST] = "6stack",
3588 [ALC880_6ST_DIG] = "6stack-digout",
3589 [ALC880_ASUS] = "asus",
3590 [ALC880_ASUS_W1V] = "asus-w1v",
3591 [ALC880_ASUS_DIG] = "asus-dig",
3592 [ALC880_ASUS_DIG2] = "asus-dig2",
3593 [ALC880_UNIWILL_DIG] = "uniwill",
3594 [ALC880_UNIWILL_P53] = "uniwill-p53",
3595 [ALC880_FUJITSU] = "fujitsu",
3596 [ALC880_F1734] = "F1734",
3598 [ALC880_LG_LW] = "lg-lw",
3599 [ALC880_MEDION_RIM] = "medion",
3600 #ifdef CONFIG_SND_DEBUG
3601 [ALC880_TEST] = "test",
3603 [ALC880_AUTO] = "auto",
3606 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3607 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3608 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3609 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3610 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3611 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3612 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3613 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3614 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3615 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3616 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3617 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3618 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3619 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3620 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3621 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3622 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3623 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3624 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3625 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3626 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3627 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3628 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3629 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3630 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3631 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3632 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3633 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3634 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3635 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3636 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3637 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3638 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3639 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3640 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3641 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3642 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3643 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3644 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3645 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3646 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3647 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3648 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3649 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3650 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3651 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3652 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3653 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3654 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3655 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3656 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3657 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3658 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3659 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3660 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3661 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3662 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3663 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3664 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3665 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3666 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3667 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3668 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3669 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3670 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3671 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3672 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3673 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3674 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3676 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3677 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3678 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3683 * ALC880 codec presets
3685 static struct alc_config_preset alc880_presets[] = {
3687 .mixers = { alc880_three_stack_mixer },
3688 .init_verbs = { alc880_volume_init_verbs,
3689 alc880_pin_3stack_init_verbs },
3690 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3691 .dac_nids = alc880_dac_nids,
3692 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3693 .channel_mode = alc880_threestack_modes,
3695 .input_mux = &alc880_capture_source,
3697 [ALC880_3ST_DIG] = {
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 .dig_out_nid = ALC880_DIGOUT_NID,
3704 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3705 .channel_mode = alc880_threestack_modes,
3707 .input_mux = &alc880_capture_source,
3709 [ALC880_TCL_S700] = {
3710 .mixers = { alc880_tcl_s700_mixer },
3711 .init_verbs = { alc880_volume_init_verbs,
3712 alc880_pin_tcl_S700_init_verbs,
3713 alc880_gpio2_init_verbs },
3714 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3715 .dac_nids = alc880_dac_nids,
3716 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3717 .num_adc_nids = 1, /* single ADC */
3719 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3720 .channel_mode = alc880_2_jack_modes,
3721 .input_mux = &alc880_capture_source,
3724 .mixers = { alc880_three_stack_mixer,
3725 alc880_five_stack_mixer},
3726 .init_verbs = { alc880_volume_init_verbs,
3727 alc880_pin_5stack_init_verbs },
3728 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3729 .dac_nids = alc880_dac_nids,
3730 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3731 .channel_mode = alc880_fivestack_modes,
3732 .input_mux = &alc880_capture_source,
3734 [ALC880_5ST_DIG] = {
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 .dig_out_nid = ALC880_DIGOUT_NID,
3742 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3743 .channel_mode = alc880_fivestack_modes,
3744 .input_mux = &alc880_capture_source,
3747 .mixers = { alc880_six_stack_mixer },
3748 .init_verbs = { alc880_volume_init_verbs,
3749 alc880_pin_6stack_init_verbs },
3750 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3751 .dac_nids = alc880_6st_dac_nids,
3752 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3753 .channel_mode = alc880_sixstack_modes,
3754 .input_mux = &alc880_6stack_capture_source,
3756 [ALC880_6ST_DIG] = {
3757 .mixers = { alc880_six_stack_mixer },
3758 .init_verbs = { alc880_volume_init_verbs,
3759 alc880_pin_6stack_init_verbs },
3760 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3761 .dac_nids = alc880_6st_dac_nids,
3762 .dig_out_nid = ALC880_DIGOUT_NID,
3763 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3764 .channel_mode = alc880_sixstack_modes,
3765 .input_mux = &alc880_6stack_capture_source,
3768 .mixers = { alc880_w810_base_mixer },
3769 .init_verbs = { alc880_volume_init_verbs,
3770 alc880_pin_w810_init_verbs,
3771 alc880_gpio2_init_verbs },
3772 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3773 .dac_nids = alc880_w810_dac_nids,
3774 .dig_out_nid = ALC880_DIGOUT_NID,
3775 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3776 .channel_mode = alc880_w810_modes,
3777 .input_mux = &alc880_capture_source,
3780 .mixers = { alc880_z71v_mixer },
3781 .init_verbs = { alc880_volume_init_verbs,
3782 alc880_pin_z71v_init_verbs },
3783 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3784 .dac_nids = alc880_z71v_dac_nids,
3785 .dig_out_nid = ALC880_DIGOUT_NID,
3787 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3788 .channel_mode = alc880_2_jack_modes,
3789 .input_mux = &alc880_capture_source,
3792 .mixers = { alc880_f1734_mixer },
3793 .init_verbs = { alc880_volume_init_verbs,
3794 alc880_pin_f1734_init_verbs },
3795 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3796 .dac_nids = alc880_f1734_dac_nids,
3798 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3799 .channel_mode = alc880_2_jack_modes,
3800 .input_mux = &alc880_f1734_capture_source,
3801 .unsol_event = alc880_uniwill_p53_unsol_event,
3802 .init_hook = alc880_uniwill_p53_hp_automute,
3805 .mixers = { alc880_asus_mixer },
3806 .init_verbs = { alc880_volume_init_verbs,
3807 alc880_pin_asus_init_verbs,
3808 alc880_gpio1_init_verbs },
3809 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3810 .dac_nids = alc880_asus_dac_nids,
3811 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3812 .channel_mode = alc880_asus_modes,
3814 .input_mux = &alc880_capture_source,
3816 [ALC880_ASUS_DIG] = {
3817 .mixers = { alc880_asus_mixer },
3818 .init_verbs = { alc880_volume_init_verbs,
3819 alc880_pin_asus_init_verbs,
3820 alc880_gpio1_init_verbs },
3821 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3822 .dac_nids = alc880_asus_dac_nids,
3823 .dig_out_nid = ALC880_DIGOUT_NID,
3824 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3825 .channel_mode = alc880_asus_modes,
3827 .input_mux = &alc880_capture_source,
3829 [ALC880_ASUS_DIG2] = {
3830 .mixers = { alc880_asus_mixer },
3831 .init_verbs = { alc880_volume_init_verbs,
3832 alc880_pin_asus_init_verbs,
3833 alc880_gpio2_init_verbs }, /* use GPIO2 */
3834 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3835 .dac_nids = alc880_asus_dac_nids,
3836 .dig_out_nid = ALC880_DIGOUT_NID,
3837 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3838 .channel_mode = alc880_asus_modes,
3840 .input_mux = &alc880_capture_source,
3842 [ALC880_ASUS_W1V] = {
3843 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3844 .init_verbs = { alc880_volume_init_verbs,
3845 alc880_pin_asus_init_verbs,
3846 alc880_gpio1_init_verbs },
3847 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3848 .dac_nids = alc880_asus_dac_nids,
3849 .dig_out_nid = ALC880_DIGOUT_NID,
3850 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3851 .channel_mode = alc880_asus_modes,
3853 .input_mux = &alc880_capture_source,
3855 [ALC880_UNIWILL_DIG] = {
3856 .mixers = { alc880_asus_mixer },
3857 .init_verbs = { alc880_volume_init_verbs,
3858 alc880_pin_asus_init_verbs },
3859 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3860 .dac_nids = alc880_asus_dac_nids,
3861 .dig_out_nid = ALC880_DIGOUT_NID,
3862 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3863 .channel_mode = alc880_asus_modes,
3865 .input_mux = &alc880_capture_source,
3867 [ALC880_UNIWILL] = {
3868 .mixers = { alc880_uniwill_mixer },
3869 .init_verbs = { alc880_volume_init_verbs,
3870 alc880_uniwill_init_verbs },
3871 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3872 .dac_nids = alc880_asus_dac_nids,
3873 .dig_out_nid = ALC880_DIGOUT_NID,
3874 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3875 .channel_mode = alc880_threestack_modes,
3877 .input_mux = &alc880_capture_source,
3878 .unsol_event = alc880_uniwill_unsol_event,
3879 .init_hook = alc880_uniwill_automute,
3881 [ALC880_UNIWILL_P53] = {
3882 .mixers = { alc880_uniwill_p53_mixer },
3883 .init_verbs = { alc880_volume_init_verbs,
3884 alc880_uniwill_p53_init_verbs },
3885 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3886 .dac_nids = alc880_asus_dac_nids,
3887 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3888 .channel_mode = alc880_threestack_modes,
3889 .input_mux = &alc880_capture_source,
3890 .unsol_event = alc880_uniwill_p53_unsol_event,
3891 .init_hook = alc880_uniwill_p53_hp_automute,
3893 [ALC880_FUJITSU] = {
3894 .mixers = { alc880_fujitsu_mixer },
3895 .init_verbs = { alc880_volume_init_verbs,
3896 alc880_uniwill_p53_init_verbs,
3897 alc880_beep_init_verbs },
3898 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3899 .dac_nids = alc880_dac_nids,
3900 .dig_out_nid = ALC880_DIGOUT_NID,
3901 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3902 .channel_mode = alc880_2_jack_modes,
3903 .input_mux = &alc880_capture_source,
3904 .unsol_event = alc880_uniwill_p53_unsol_event,
3905 .init_hook = alc880_uniwill_p53_hp_automute,
3908 .mixers = { alc880_three_stack_mixer },
3909 .init_verbs = { alc880_volume_init_verbs,
3910 alc880_pin_clevo_init_verbs },
3911 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3912 .dac_nids = alc880_dac_nids,
3914 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3915 .channel_mode = alc880_threestack_modes,
3917 .input_mux = &alc880_capture_source,
3920 .mixers = { alc880_lg_mixer },
3921 .init_verbs = { alc880_volume_init_verbs,
3922 alc880_lg_init_verbs },
3923 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3924 .dac_nids = alc880_lg_dac_nids,
3925 .dig_out_nid = ALC880_DIGOUT_NID,
3926 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3927 .channel_mode = alc880_lg_ch_modes,
3929 .input_mux = &alc880_lg_capture_source,
3930 .unsol_event = alc880_lg_unsol_event,
3931 .init_hook = alc880_lg_automute,
3932 #ifdef CONFIG_SND_HDA_POWER_SAVE
3933 .loopbacks = alc880_lg_loopbacks,
3937 .mixers = { alc880_lg_lw_mixer },
3938 .init_verbs = { alc880_volume_init_verbs,
3939 alc880_lg_lw_init_verbs },
3940 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3941 .dac_nids = alc880_dac_nids,
3942 .dig_out_nid = ALC880_DIGOUT_NID,
3943 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3944 .channel_mode = alc880_lg_lw_modes,
3945 .input_mux = &alc880_lg_lw_capture_source,
3946 .unsol_event = alc880_lg_lw_unsol_event,
3947 .init_hook = alc880_lg_lw_automute,
3949 [ALC880_MEDION_RIM] = {
3950 .mixers = { alc880_medion_rim_mixer },
3951 .init_verbs = { alc880_volume_init_verbs,
3952 alc880_medion_rim_init_verbs,
3953 alc_gpio2_init_verbs },
3954 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3955 .dac_nids = alc880_dac_nids,
3956 .dig_out_nid = ALC880_DIGOUT_NID,
3957 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3958 .channel_mode = alc880_2_jack_modes,
3959 .input_mux = &alc880_medion_rim_capture_source,
3960 .unsol_event = alc880_medion_rim_unsol_event,
3961 .init_hook = alc880_medion_rim_automute,
3963 #ifdef CONFIG_SND_DEBUG
3965 .mixers = { alc880_test_mixer },
3966 .init_verbs = { alc880_test_init_verbs },
3967 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3968 .dac_nids = alc880_test_dac_nids,
3969 .dig_out_nid = ALC880_DIGOUT_NID,
3970 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3971 .channel_mode = alc880_test_modes,
3972 .input_mux = &alc880_test_capture_source,
3978 * Automatic parse of I/O pins from the BIOS configuration
3983 ALC_CTL_WIDGET_MUTE,
3986 static struct snd_kcontrol_new alc880_control_templates[] = {
3987 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3988 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3989 HDA_BIND_MUTE(NULL, 0, 0, 0),
3992 /* add dynamic controls */
3993 static int add_control(struct alc_spec *spec, int type, const char *name,
3996 struct snd_kcontrol_new *knew;
3998 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3999 knew = snd_array_new(&spec->kctls);
4002 *knew = alc880_control_templates[type];
4003 knew->name = kstrdup(name, GFP_KERNEL);
4006 knew->private_value = val;
4010 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4011 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4012 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4013 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4014 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4015 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4016 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4017 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4018 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4019 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4020 #define ALC880_PIN_CD_NID 0x1c
4022 /* fill in the dac_nids table from the parsed pin configuration */
4023 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4024 const struct auto_pin_cfg *cfg)
4030 memset(assigned, 0, sizeof(assigned));
4031 spec->multiout.dac_nids = spec->private_dac_nids;
4033 /* check the pins hardwired to audio widget */
4034 for (i = 0; i < cfg->line_outs; i++) {
4035 nid = cfg->line_out_pins[i];
4036 if (alc880_is_fixed_pin(nid)) {
4037 int idx = alc880_fixed_pin_idx(nid);
4038 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4042 /* left pins can be connect to any audio widget */
4043 for (i = 0; i < cfg->line_outs; i++) {
4044 nid = cfg->line_out_pins[i];
4045 if (alc880_is_fixed_pin(nid))
4047 /* search for an empty channel */
4048 for (j = 0; j < cfg->line_outs; j++) {
4050 spec->multiout.dac_nids[i] =
4051 alc880_idx_to_dac(j);
4057 spec->multiout.num_dacs = cfg->line_outs;
4061 /* add playback controls from the parsed DAC table */
4062 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4063 const struct auto_pin_cfg *cfg)
4066 static const char *chname[4] = {
4067 "Front", "Surround", NULL /*CLFE*/, "Side"
4072 for (i = 0; i < cfg->line_outs; i++) {
4073 if (!spec->multiout.dac_nids[i])
4075 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4078 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4079 "Center Playback Volume",
4080 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4084 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4085 "LFE Playback Volume",
4086 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4090 err = add_control(spec, ALC_CTL_BIND_MUTE,
4091 "Center Playback Switch",
4092 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4096 err = add_control(spec, ALC_CTL_BIND_MUTE,
4097 "LFE Playback Switch",
4098 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4103 sprintf(name, "%s Playback Volume", chname[i]);
4104 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4105 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4109 sprintf(name, "%s Playback Switch", chname[i]);
4110 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4111 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4120 /* add playback controls for speaker and HP outputs */
4121 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4131 if (alc880_is_fixed_pin(pin)) {
4132 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4133 /* specify the DAC as the extra output */
4134 if (!spec->multiout.hp_nid)
4135 spec->multiout.hp_nid = nid;
4137 spec->multiout.extra_out_nid[0] = nid;
4138 /* control HP volume/switch on the output mixer amp */
4139 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4140 sprintf(name, "%s Playback Volume", pfx);
4141 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4142 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4145 sprintf(name, "%s Playback Switch", pfx);
4146 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4147 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4150 } else if (alc880_is_multi_pin(pin)) {
4151 /* set manual connection */
4152 /* we have only a switch on HP-out PIN */
4153 sprintf(name, "%s Playback Switch", pfx);
4154 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4155 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4162 /* create input playback/capture controls for the given pin */
4163 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4164 const char *ctlname,
4165 int idx, hda_nid_t mix_nid)
4170 sprintf(name, "%s Playback Volume", ctlname);
4171 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4172 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4175 sprintf(name, "%s Playback Switch", ctlname);
4176 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4177 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4183 /* create playback/capture controls for input pins */
4184 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4185 const struct auto_pin_cfg *cfg)
4187 struct hda_input_mux *imux = &spec->private_imux[0];
4190 for (i = 0; i < AUTO_PIN_LAST; i++) {
4191 if (alc880_is_input_pin(cfg->input_pins[i])) {
4192 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4193 err = new_analog_input(spec, cfg->input_pins[i],
4194 auto_pin_cfg_labels[i],
4198 imux->items[imux->num_items].label =
4199 auto_pin_cfg_labels[i];
4200 imux->items[imux->num_items].index =
4201 alc880_input_pin_idx(cfg->input_pins[i]);
4208 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4209 unsigned int pin_type)
4211 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4214 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4218 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4219 hda_nid_t nid, int pin_type,
4222 alc_set_pin_output(codec, nid, pin_type);
4223 /* need the manual connection? */
4224 if (alc880_is_multi_pin(nid)) {
4225 struct alc_spec *spec = codec->spec;
4226 int idx = alc880_multi_pin_idx(nid);
4227 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4228 AC_VERB_SET_CONNECT_SEL,
4229 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4233 static int get_pin_type(int line_out_type)
4235 if (line_out_type == AUTO_PIN_HP_OUT)
4241 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4243 struct alc_spec *spec = codec->spec;
4246 for (i = 0; i < spec->autocfg.line_outs; i++) {
4247 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4248 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4249 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4253 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4255 struct alc_spec *spec = codec->spec;
4258 pin = spec->autocfg.speaker_pins[0];
4259 if (pin) /* connect to front */
4260 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4261 pin = spec->autocfg.hp_pins[0];
4262 if (pin) /* connect to front */
4263 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4266 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4268 struct alc_spec *spec = codec->spec;
4271 for (i = 0; i < AUTO_PIN_LAST; i++) {
4272 hda_nid_t nid = spec->autocfg.input_pins[i];
4273 if (alc880_is_input_pin(nid)) {
4274 alc_set_input_pin(codec, nid, i);
4275 if (nid != ALC880_PIN_CD_NID &&
4276 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4277 snd_hda_codec_write(codec, nid, 0,
4278 AC_VERB_SET_AMP_GAIN_MUTE,
4284 /* parse the BIOS configuration and set up the alc_spec */
4285 /* return 1 if successful, 0 if the proper config is not found,
4286 * or a negative error code
4288 static int alc880_parse_auto_config(struct hda_codec *codec)
4290 struct alc_spec *spec = codec->spec;
4292 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4294 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4298 if (!spec->autocfg.line_outs)
4299 return 0; /* can't find valid BIOS pin config */
4301 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4304 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4307 err = alc880_auto_create_extra_out(spec,
4308 spec->autocfg.speaker_pins[0],
4312 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4316 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4320 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4322 /* check multiple SPDIF-out (for recent codecs) */
4323 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4325 err = snd_hda_get_connections(codec,
4326 spec->autocfg.dig_out_pins[i],
4331 spec->multiout.dig_out_nid = dig_nid;
4333 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4334 spec->slave_dig_outs[i - 1] = dig_nid;
4335 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4339 if (spec->autocfg.dig_in_pin)
4340 spec->dig_in_nid = ALC880_DIGIN_NID;
4342 if (spec->kctls.list)
4343 add_mixer(spec, spec->kctls.list);
4345 add_verb(spec, alc880_volume_init_verbs);
4347 spec->num_mux_defs = 1;
4348 spec->input_mux = &spec->private_imux[0];
4350 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4355 /* additional initialization for auto-configuration model */
4356 static void alc880_auto_init(struct hda_codec *codec)
4358 struct alc_spec *spec = codec->spec;
4359 alc880_auto_init_multi_out(codec);
4360 alc880_auto_init_extra_out(codec);
4361 alc880_auto_init_analog_input(codec);
4362 if (spec->unsol_event)
4363 alc_inithook(codec);
4366 static void set_capture_mixer(struct alc_spec *spec)
4368 static struct snd_kcontrol_new *caps[2][3] = {
4369 { alc_capture_mixer_nosrc1,
4370 alc_capture_mixer_nosrc2,
4371 alc_capture_mixer_nosrc3 },
4372 { alc_capture_mixer1,
4374 alc_capture_mixer3 },
4376 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4378 if (spec->input_mux && spec->input_mux->num_items > 1)
4382 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4386 #define set_beep_amp(spec, nid, idx, dir) \
4387 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4390 * OK, here we have finally the patch for ALC880
4393 static int patch_alc880(struct hda_codec *codec)
4395 struct alc_spec *spec;
4399 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4405 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4408 if (board_config < 0) {
4409 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4410 "trying auto-probe from BIOS...\n");
4411 board_config = ALC880_AUTO;
4414 if (board_config == ALC880_AUTO) {
4415 /* automatic parse from the BIOS config */
4416 err = alc880_parse_auto_config(codec);
4422 "hda_codec: Cannot set up configuration "
4423 "from BIOS. Using 3-stack mode...\n");
4424 board_config = ALC880_3ST;
4428 err = snd_hda_attach_beep_device(codec, 0x1);
4434 if (board_config != ALC880_AUTO)
4435 setup_preset(spec, &alc880_presets[board_config]);
4437 spec->stream_name_analog = "ALC880 Analog";
4438 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4439 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4440 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4442 spec->stream_name_digital = "ALC880 Digital";
4443 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4444 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4446 if (!spec->adc_nids && spec->input_mux) {
4447 /* check whether NID 0x07 is valid */
4448 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4450 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4451 if (wcap != AC_WID_AUD_IN) {
4452 spec->adc_nids = alc880_adc_nids_alt;
4453 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4455 spec->adc_nids = alc880_adc_nids;
4456 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4459 set_capture_mixer(spec);
4460 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4462 spec->vmaster_nid = 0x0c;
4464 codec->patch_ops = alc_patch_ops;
4465 if (board_config == ALC880_AUTO)
4466 spec->init_hook = alc880_auto_init;
4467 #ifdef CONFIG_SND_HDA_POWER_SAVE
4468 if (!spec->loopback.amplist)
4469 spec->loopback.amplist = alc880_loopbacks;
4471 codec->proc_widget_hook = print_realtek_coef;
4481 static hda_nid_t alc260_dac_nids[1] = {
4486 static hda_nid_t alc260_adc_nids[1] = {
4491 static hda_nid_t alc260_adc_nids_alt[1] = {
4496 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4497 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4499 static hda_nid_t alc260_dual_adc_nids[2] = {
4504 #define ALC260_DIGOUT_NID 0x03
4505 #define ALC260_DIGIN_NID 0x06
4507 static struct hda_input_mux alc260_capture_source = {
4511 { "Front Mic", 0x1 },
4517 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4518 * headphone jack and the internal CD lines since these are the only pins at
4519 * which audio can appear. For flexibility, also allow the option of
4520 * recording the mixer output on the second ADC (ADC0 doesn't have a
4521 * connection to the mixer output).
4523 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4527 { "Mic/Line", 0x0 },
4529 { "Headphone", 0x2 },
4535 { "Mic/Line", 0x0 },
4537 { "Headphone", 0x2 },
4544 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4545 * the Fujitsu S702x, but jacks are marked differently.
4547 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4554 { "Headphone", 0x5 },
4563 { "Headphone", 0x6 },
4569 /* Maxdata Favorit 100XS */
4570 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4574 { "Line/Mic", 0x0 },
4581 { "Line/Mic", 0x0 },
4589 * This is just place-holder, so there's something for alc_build_pcms to look
4590 * at when it calculates the maximum number of channels. ALC260 has no mixer
4591 * element which allows changing the channel mode, so the verb list is
4594 static struct hda_channel_mode alc260_modes[1] = {
4599 /* Mixer combinations
4601 * basic: base_output + input + pc_beep + capture
4602 * HP: base_output + input + capture_alt
4603 * HP_3013: hp_3013 + input + capture
4604 * fujitsu: fujitsu + capture
4605 * acer: acer + capture
4608 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4609 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4610 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4611 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4612 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4613 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4614 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4618 static struct snd_kcontrol_new alc260_input_mixer[] = {
4619 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4620 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4621 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4622 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4624 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4625 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4626 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4630 /* update HP, line and mono out pins according to the master switch */
4631 static void alc260_hp_master_update(struct hda_codec *codec,
4632 hda_nid_t hp, hda_nid_t line,
4635 struct alc_spec *spec = codec->spec;
4636 unsigned int val = spec->master_sw ? PIN_HP : 0;
4637 /* change HP and line-out pins */
4638 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4640 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4642 /* mono (speaker) depending on the HP jack sense */
4643 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4644 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4648 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4649 struct snd_ctl_elem_value *ucontrol)
4651 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4652 struct alc_spec *spec = codec->spec;
4653 *ucontrol->value.integer.value = spec->master_sw;
4657 static int alc260_hp_master_sw_put(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 int val = !!*ucontrol->value.integer.value;
4663 hda_nid_t hp, line, mono;
4665 if (val == spec->master_sw)
4667 spec->master_sw = val;
4668 hp = (kcontrol->private_value >> 16) & 0xff;
4669 line = (kcontrol->private_value >> 8) & 0xff;
4670 mono = kcontrol->private_value & 0xff;
4671 alc260_hp_master_update(codec, hp, line, mono);
4675 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4677 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4678 .name = "Master Playback Switch",
4679 .info = snd_ctl_boolean_mono_info,
4680 .get = alc260_hp_master_sw_get,
4681 .put = alc260_hp_master_sw_put,
4682 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4684 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4685 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4686 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4687 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4688 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4690 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4694 static struct hda_verb alc260_hp_unsol_verbs[] = {
4695 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4699 static void alc260_hp_automute(struct hda_codec *codec)
4701 struct alc_spec *spec = codec->spec;
4702 unsigned int present;
4704 present = snd_hda_codec_read(codec, 0x10, 0,
4705 AC_VERB_GET_PIN_SENSE, 0);
4706 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4707 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4710 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4712 if ((res >> 26) == ALC880_HP_EVENT)
4713 alc260_hp_automute(codec);
4716 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4718 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4719 .name = "Master Playback Switch",
4720 .info = snd_ctl_boolean_mono_info,
4721 .get = alc260_hp_master_sw_get,
4722 .put = alc260_hp_master_sw_put,
4723 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4725 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4726 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4727 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4728 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4729 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4730 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4731 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4732 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4736 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4737 .ops = &snd_hda_bind_vol,
4739 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4740 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4741 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4746 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4747 .ops = &snd_hda_bind_sw,
4749 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4750 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4755 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4756 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4757 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4758 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4759 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4763 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4764 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4768 static void alc260_hp_3013_automute(struct hda_codec *codec)
4770 struct alc_spec *spec = codec->spec;
4771 unsigned int present;
4773 present = snd_hda_codec_read(codec, 0x15, 0,
4774 AC_VERB_GET_PIN_SENSE, 0);
4775 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4776 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4779 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4782 if ((res >> 26) == ALC880_HP_EVENT)
4783 alc260_hp_3013_automute(codec);
4786 static void alc260_hp_3012_automute(struct hda_codec *codec)
4788 unsigned int present, bits;
4790 present = snd_hda_codec_read(codec, 0x10, 0,
4791 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4793 bits = present ? 0 : PIN_OUT;
4794 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4796 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4798 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4802 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4805 if ((res >> 26) == ALC880_HP_EVENT)
4806 alc260_hp_3012_automute(codec);
4809 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4810 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4812 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4813 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4814 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4815 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4816 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4817 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4818 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4819 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4820 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4821 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4822 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4826 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4827 * versions of the ALC260 don't act on requests to enable mic bias from NID
4828 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4829 * datasheet doesn't mention this restriction. At this stage it's not clear
4830 * whether this behaviour is intentional or is a hardware bug in chip
4831 * revisions available in early 2006. Therefore for now allow the
4832 * "Headphone Jack Mode" control to span all choices, but if it turns out
4833 * that the lack of mic bias for this NID is intentional we could change the
4834 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4836 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4837 * don't appear to make the mic bias available from the "line" jack, even
4838 * though the NID used for this jack (0x14) can supply it. The theory is
4839 * that perhaps Acer have included blocking capacitors between the ALC260
4840 * and the output jack. If this turns out to be the case for all such
4841 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4842 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4844 * The C20x Tablet series have a mono internal speaker which is controlled
4845 * via the chip's Mono sum widget and pin complex, so include the necessary
4846 * controls for such models. On models without a "mono speaker" the control
4847 * won't do anything.
4849 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4850 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4851 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4852 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4853 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4855 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4857 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4858 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4860 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4861 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4862 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4863 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4864 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4868 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4870 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4871 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4872 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4873 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4874 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4875 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4876 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4880 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4881 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4883 static struct snd_kcontrol_new alc260_will_mixer[] = {
4884 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4885 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4886 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4887 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4888 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4889 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4890 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4891 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4892 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4893 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4897 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4898 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4900 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4901 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4902 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4904 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4905 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4906 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4907 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4908 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4909 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4910 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4915 * initialization verbs
4917 static struct hda_verb alc260_init_verbs[] = {
4918 /* Line In pin widget for input */
4919 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4920 /* CD pin widget for input */
4921 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4922 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4923 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4924 /* Mic2 (front panel) pin widget for input and vref at 80% */
4925 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4926 /* LINE-2 is used for line-out in rear */
4927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4928 /* select line-out */
4929 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4931 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4933 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4935 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4936 /* mute capture amp left and right */
4937 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4938 /* set connection select to line in (default select for this ADC) */
4939 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4940 /* mute capture amp left and right */
4941 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4942 /* set connection select to line in (default select for this ADC) */
4943 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4944 /* set vol=0 Line-Out mixer amp left and right */
4945 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4946 /* unmute pin widget amp left and right (no gain on this amp) */
4947 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4948 /* set vol=0 HP mixer amp left and right */
4949 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4950 /* unmute pin widget amp left and right (no gain on this amp) */
4951 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4952 /* set vol=0 Mono mixer amp left and right */
4953 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4954 /* unmute pin widget amp left and right (no gain on this amp) */
4955 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4956 /* unmute LINE-2 out pin */
4957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4958 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4961 /* mute analog inputs */
4962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4964 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4965 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4967 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4968 /* mute Front out path */
4969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4970 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4971 /* mute Headphone out path */
4972 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4973 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4974 /* mute Mono out path */
4975 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4976 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4980 #if 0 /* should be identical with alc260_init_verbs? */
4981 static struct hda_verb alc260_hp_init_verbs[] = {
4982 /* Headphone and output */
4983 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4985 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4986 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4987 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4988 /* Mic2 (front panel) pin widget for input and vref at 80% */
4989 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4990 /* Line In pin widget for input */
4991 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4992 /* Line-2 pin widget for output */
4993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4994 /* CD pin widget for input */
4995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4996 /* unmute amp left and right */
4997 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4998 /* set connection select to line in (default select for this ADC) */
4999 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5000 /* unmute Line-Out mixer amp left and right (volume = 0) */
5001 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5002 /* mute pin widget amp left and right (no gain on this amp) */
5003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5004 /* unmute HP mixer amp left and right (volume = 0) */
5005 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5006 /* mute pin widget amp left and right (no gain on this amp) */
5007 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5008 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5011 /* mute analog inputs */
5012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5014 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5015 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5017 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5018 /* Unmute Front out path */
5019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5020 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5021 /* Unmute Headphone out path */
5022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5023 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5024 /* Unmute Mono out path */
5025 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5026 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5031 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5032 /* Line out and output */
5033 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5035 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5036 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5037 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5038 /* Mic2 (front panel) pin widget for input and vref at 80% */
5039 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5040 /* Line In pin widget for input */
5041 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5042 /* Headphone pin widget for output */
5043 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5044 /* CD pin widget for input */
5045 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5046 /* unmute amp left and right */
5047 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5048 /* set connection select to line in (default select for this ADC) */
5049 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5050 /* unmute Line-Out mixer amp left and right (volume = 0) */
5051 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5052 /* mute pin widget amp left and right (no gain on this amp) */
5053 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5054 /* unmute HP mixer amp left and right (volume = 0) */
5055 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5056 /* mute pin widget amp left and right (no gain on this amp) */
5057 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5058 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5061 /* mute analog inputs */
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5063 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5064 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5067 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5068 /* Unmute Front out path */
5069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5070 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5071 /* Unmute Headphone out path */
5072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5074 /* Unmute Mono out path */
5075 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5076 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5080 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5081 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5082 * audio = 0x16, internal speaker = 0x10.
5084 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5085 /* Disable all GPIOs */
5086 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5087 /* Internal speaker is connected to headphone pin */
5088 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5089 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5091 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5092 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5093 /* Ensure all other unused pins are disabled and muted. */
5094 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5095 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5096 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5097 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5098 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5099 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5101 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5103 /* Disable digital (SPDIF) pins */
5104 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5105 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5107 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5108 * when acting as an output.
5110 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5112 /* Start with output sum widgets muted and their output gains at min */
5113 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5114 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5115 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5116 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5117 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5118 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5119 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5120 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5121 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5123 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5124 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5125 /* Unmute Line1 pin widget output buffer since it starts as an output.
5126 * If the pin mode is changed by the user the pin mode control will
5127 * take care of enabling the pin's input/output buffers as needed.
5128 * Therefore there's no need to enable the input buffer at this
5131 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5132 /* Unmute input buffer of pin widget used for Line-in (no equiv
5135 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5137 /* Mute capture amp left and right */
5138 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5139 /* Set ADC connection select to match default mixer setting - line
5142 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5144 /* Do the same for the second ADC: mute capture input amp and
5145 * set ADC connection to line in (on mic1 pin)
5147 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5148 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5150 /* Mute all inputs to mixer widget (even unconnected ones) */
5151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5156 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5158 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5163 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5164 * similar laptops (adapted from Fujitsu init verbs).
5166 static struct hda_verb alc260_acer_init_verbs[] = {
5167 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5168 * the headphone jack. Turn this on and rely on the standard mute
5169 * methods whenever the user wants to turn these outputs off.
5171 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5172 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5173 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5174 /* Internal speaker/Headphone jack is connected to Line-out pin */
5175 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5176 /* Internal microphone/Mic jack is connected to Mic1 pin */
5177 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5178 /* Line In jack is connected to Line1 pin */
5179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5180 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5181 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5182 /* Ensure all other unused pins are disabled and muted. */
5183 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5184 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5185 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5186 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5187 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5188 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5189 /* Disable digital (SPDIF) pins */
5190 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5191 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5193 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5194 * bus when acting as outputs.
5196 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5197 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5199 /* Start with output sum widgets muted and their output gains at min */
5200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5201 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5202 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5203 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5204 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5205 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5206 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5207 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5208 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5210 /* Unmute Line-out pin widget amp left and right
5211 * (no equiv mixer ctrl)
5213 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5214 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5215 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5216 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5217 * inputs. If the pin mode is changed by the user the pin mode control
5218 * will take care of enabling the pin's input/output buffers as needed.
5219 * Therefore there's no need to enable the input buffer at this
5222 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5223 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5225 /* Mute capture amp left and right */
5226 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5227 /* Set ADC connection select to match default mixer setting - mic
5230 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5232 /* Do similar with the second ADC: mute capture input amp and
5233 * set ADC connection to mic to match ALSA's default state.
5235 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5236 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5238 /* Mute all inputs to mixer widget (even unconnected ones) */
5239 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5241 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5243 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5244 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5245 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5246 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5251 /* Initialisation sequence for Maxdata Favorit 100XS
5252 * (adapted from Acer init verbs).
5254 static struct hda_verb alc260_favorit100_init_verbs[] = {
5255 /* GPIO 0 enables the output jack.
5256 * Turn this on and rely on the standard mute
5257 * methods whenever the user wants to turn these outputs off.
5259 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5260 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5261 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5262 /* Line/Mic input jack is connected to Mic1 pin */
5263 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5264 /* Ensure all other unused pins are disabled and muted. */
5265 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5266 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5267 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5268 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5269 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5270 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5272 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5273 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5274 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5275 /* Disable digital (SPDIF) pins */
5276 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5277 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5279 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5280 * bus when acting as outputs.
5282 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5283 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5285 /* Start with output sum widgets muted and their output gains at min */
5286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5287 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5288 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5289 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5290 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5292 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5293 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5294 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5296 /* Unmute Line-out pin widget amp left and right
5297 * (no equiv mixer ctrl)
5299 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5300 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5301 * inputs. If the pin mode is changed by the user the pin mode control
5302 * will take care of enabling the pin's input/output buffers as needed.
5303 * Therefore there's no need to enable the input buffer at this
5306 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5308 /* Mute capture amp left and right */
5309 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5310 /* Set ADC connection select to match default mixer setting - mic
5313 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5315 /* Do similar with the second ADC: mute capture input amp and
5316 * set ADC connection to mic to match ALSA's default state.
5318 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5319 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5321 /* Mute all inputs to mixer widget (even unconnected ones) */
5322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5328 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5334 static struct hda_verb alc260_will_verbs[] = {
5335 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5336 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5337 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5338 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5339 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5340 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5344 static struct hda_verb alc260_replacer_672v_verbs[] = {
5345 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5346 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5347 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5349 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5350 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5351 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5353 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5357 /* toggle speaker-output according to the hp-jack state */
5358 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5360 unsigned int present;
5362 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5363 present = snd_hda_codec_read(codec, 0x0f, 0,
5364 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5366 snd_hda_codec_write_cache(codec, 0x01, 0,
5367 AC_VERB_SET_GPIO_DATA, 1);
5368 snd_hda_codec_write_cache(codec, 0x0f, 0,
5369 AC_VERB_SET_PIN_WIDGET_CONTROL,
5372 snd_hda_codec_write_cache(codec, 0x01, 0,
5373 AC_VERB_SET_GPIO_DATA, 0);
5374 snd_hda_codec_write_cache(codec, 0x0f, 0,
5375 AC_VERB_SET_PIN_WIDGET_CONTROL,
5380 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5383 if ((res >> 26) == ALC880_HP_EVENT)
5384 alc260_replacer_672v_automute(codec);
5387 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5388 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5390 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5391 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5392 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5394 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5395 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5396 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5397 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5401 /* Test configuration for debugging, modelled after the ALC880 test
5404 #ifdef CONFIG_SND_DEBUG
5405 static hda_nid_t alc260_test_dac_nids[1] = {
5408 static hda_nid_t alc260_test_adc_nids[2] = {
5411 /* For testing the ALC260, each input MUX needs its own definition since
5412 * the signal assignments are different. This assumes that the first ADC
5415 static struct hda_input_mux alc260_test_capture_sources[2] = {
5419 { "MIC1 pin", 0x0 },
5420 { "MIC2 pin", 0x1 },
5421 { "LINE1 pin", 0x2 },
5422 { "LINE2 pin", 0x3 },
5424 { "LINE-OUT pin", 0x5 },
5425 { "HP-OUT pin", 0x6 },
5431 { "MIC1 pin", 0x0 },
5432 { "MIC2 pin", 0x1 },
5433 { "LINE1 pin", 0x2 },
5434 { "LINE2 pin", 0x3 },
5437 { "LINE-OUT pin", 0x6 },
5438 { "HP-OUT pin", 0x7 },
5442 static struct snd_kcontrol_new alc260_test_mixer[] = {
5443 /* Output driver widgets */
5444 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5445 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5446 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5447 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5448 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5449 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5451 /* Modes for retasking pin widgets
5452 * Note: the ALC260 doesn't seem to act on requests to enable mic
5453 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5454 * mention this restriction. At this stage it's not clear whether
5455 * this behaviour is intentional or is a hardware bug in chip
5456 * revisions available at least up until early 2006. Therefore for
5457 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5458 * choices, but if it turns out that the lack of mic bias for these
5459 * NIDs is intentional we could change their modes from
5460 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5462 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5463 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5464 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5465 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5466 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5467 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5469 /* Loopback mixer controls */
5470 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5471 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5472 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5473 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5474 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5475 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5476 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5477 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5478 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5479 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5480 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5481 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5482 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5483 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5485 /* Controls for GPIO pins, assuming they are configured as outputs */
5486 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5487 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5488 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5489 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5491 /* Switches to allow the digital IO pins to be enabled. The datasheet
5492 * is ambigious as to which NID is which; testing on laptops which
5493 * make this output available should provide clarification.
5495 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5496 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5498 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5499 * this output to turn on an external amplifier.
5501 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5502 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5506 static struct hda_verb alc260_test_init_verbs[] = {
5507 /* Enable all GPIOs as outputs with an initial value of 0 */
5508 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5509 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5510 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5512 /* Enable retasking pins as output, initially without power amp */
5513 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5514 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5515 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5516 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5517 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5518 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5520 /* Disable digital (SPDIF) pins initially, but users can enable
5521 * them via a mixer switch. In the case of SPDIF-out, this initverb
5522 * payload also sets the generation to 0, output to be in "consumer"
5523 * PCM format, copyright asserted, no pre-emphasis and no validity
5526 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5527 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5529 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5530 * OUT1 sum bus when acting as an output.
5532 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5533 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5534 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5535 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5537 /* Start with output sum widgets muted and their output gains at min */
5538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5539 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5540 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5542 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5543 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5544 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5545 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5546 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5548 /* Unmute retasking pin widget output buffers since the default
5549 * state appears to be output. As the pin mode is changed by the
5550 * user the pin mode control will take care of enabling the pin's
5551 * input/output buffers as needed.
5553 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5554 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5556 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5557 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5558 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5559 /* Also unmute the mono-out pin widget */
5560 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5562 /* Mute capture amp left and right */
5563 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5564 /* Set ADC connection select to match default mixer setting (mic1
5567 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5569 /* Do the same for the second ADC: mute capture input amp and
5570 * set ADC connection to mic1 pin
5572 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5573 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5575 /* Mute all inputs to mixer widget (even unconnected ones) */
5576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5580 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5581 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5582 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5583 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5589 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5590 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5592 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5593 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5596 * for BIOS auto-configuration
5599 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5600 const char *pfx, int *vol_bits)
5603 unsigned long vol_val, sw_val;
5607 if (nid >= 0x0f && nid < 0x11) {
5608 nid_vol = nid - 0x7;
5609 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5610 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5611 } else if (nid == 0x11) {
5612 nid_vol = nid - 0x7;
5613 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5614 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5615 } else if (nid >= 0x12 && nid <= 0x15) {
5617 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5618 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5622 if (!(*vol_bits & (1 << nid_vol))) {
5623 /* first control for the volume widget */
5624 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5625 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5628 *vol_bits |= (1 << nid_vol);
5630 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5631 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5637 /* add playback controls from the parsed DAC table */
5638 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5639 const struct auto_pin_cfg *cfg)
5645 spec->multiout.num_dacs = 1;
5646 spec->multiout.dac_nids = spec->private_dac_nids;
5647 spec->multiout.dac_nids[0] = 0x02;
5649 nid = cfg->line_out_pins[0];
5651 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5656 nid = cfg->speaker_pins[0];
5658 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5663 nid = cfg->hp_pins[0];
5665 err = alc260_add_playback_controls(spec, nid, "Headphone",
5673 /* create playback/capture controls for input pins */
5674 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5675 const struct auto_pin_cfg *cfg)
5677 struct hda_input_mux *imux = &spec->private_imux[0];
5680 for (i = 0; i < AUTO_PIN_LAST; i++) {
5681 if (cfg->input_pins[i] >= 0x12) {
5682 idx = cfg->input_pins[i] - 0x12;
5683 err = new_analog_input(spec, cfg->input_pins[i],
5684 auto_pin_cfg_labels[i], idx,
5688 imux->items[imux->num_items].label =
5689 auto_pin_cfg_labels[i];
5690 imux->items[imux->num_items].index = idx;
5693 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5694 idx = cfg->input_pins[i] - 0x09;
5695 err = new_analog_input(spec, cfg->input_pins[i],
5696 auto_pin_cfg_labels[i], idx,
5700 imux->items[imux->num_items].label =
5701 auto_pin_cfg_labels[i];
5702 imux->items[imux->num_items].index = idx;
5709 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5710 hda_nid_t nid, int pin_type,
5713 alc_set_pin_output(codec, nid, pin_type);
5714 /* need the manual connection? */
5716 int idx = nid - 0x12;
5717 snd_hda_codec_write(codec, idx + 0x0b, 0,
5718 AC_VERB_SET_CONNECT_SEL, sel_idx);
5722 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5724 struct alc_spec *spec = codec->spec;
5727 nid = spec->autocfg.line_out_pins[0];
5729 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5730 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5733 nid = spec->autocfg.speaker_pins[0];
5735 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5737 nid = spec->autocfg.hp_pins[0];
5739 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5742 #define ALC260_PIN_CD_NID 0x16
5743 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5745 struct alc_spec *spec = codec->spec;
5748 for (i = 0; i < AUTO_PIN_LAST; i++) {
5749 hda_nid_t nid = spec->autocfg.input_pins[i];
5751 alc_set_input_pin(codec, nid, i);
5752 if (nid != ALC260_PIN_CD_NID &&
5753 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5754 snd_hda_codec_write(codec, nid, 0,
5755 AC_VERB_SET_AMP_GAIN_MUTE,
5762 * generic initialization of ADC, input mixers and output mixers
5764 static struct hda_verb alc260_volume_init_verbs[] = {
5766 * Unmute ADC0-1 and set the default input to mic-in
5768 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5769 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5770 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5771 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5773 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5775 * Note: PASD motherboards uses the Line In 2 as the input for
5776 * front panel mic (mic 2)
5778 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5779 /* mute analog inputs */
5780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5784 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5787 * Set up output mixers (0x08 - 0x0a)
5789 /* set vol=0 to output mixers */
5790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5792 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5793 /* set up input amps for analog loopback */
5794 /* Amp Indices: DAC = 0, mixer = 1 */
5795 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5796 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5797 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5798 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5799 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5800 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5805 static int alc260_parse_auto_config(struct hda_codec *codec)
5807 struct alc_spec *spec = codec->spec;
5809 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5811 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5815 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5818 if (!spec->kctls.list)
5819 return 0; /* can't find valid BIOS pin config */
5820 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5824 spec->multiout.max_channels = 2;
5826 if (spec->autocfg.dig_outs)
5827 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5828 if (spec->kctls.list)
5829 add_mixer(spec, spec->kctls.list);
5831 add_verb(spec, alc260_volume_init_verbs);
5833 spec->num_mux_defs = 1;
5834 spec->input_mux = &spec->private_imux[0];
5836 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5841 /* additional initialization for auto-configuration model */
5842 static void alc260_auto_init(struct hda_codec *codec)
5844 struct alc_spec *spec = codec->spec;
5845 alc260_auto_init_multi_out(codec);
5846 alc260_auto_init_analog_input(codec);
5847 if (spec->unsol_event)
5848 alc_inithook(codec);
5851 #ifdef CONFIG_SND_HDA_POWER_SAVE
5852 static struct hda_amp_list alc260_loopbacks[] = {
5853 { 0x07, HDA_INPUT, 0 },
5854 { 0x07, HDA_INPUT, 1 },
5855 { 0x07, HDA_INPUT, 2 },
5856 { 0x07, HDA_INPUT, 3 },
5857 { 0x07, HDA_INPUT, 4 },
5863 * ALC260 configurations
5865 static const char *alc260_models[ALC260_MODEL_LAST] = {
5866 [ALC260_BASIC] = "basic",
5868 [ALC260_HP_3013] = "hp-3013",
5869 [ALC260_HP_DC7600] = "hp-dc7600",
5870 [ALC260_FUJITSU_S702X] = "fujitsu",
5871 [ALC260_ACER] = "acer",
5872 [ALC260_WILL] = "will",
5873 [ALC260_REPLACER_672V] = "replacer",
5874 [ALC260_FAVORIT100] = "favorit100",
5875 #ifdef CONFIG_SND_DEBUG
5876 [ALC260_TEST] = "test",
5878 [ALC260_AUTO] = "auto",
5881 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5882 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5883 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5884 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5885 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5886 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5887 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5888 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5889 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5890 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5891 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5892 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5893 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5894 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5895 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5896 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5897 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5898 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5899 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5900 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5904 static struct alc_config_preset alc260_presets[] = {
5906 .mixers = { alc260_base_output_mixer,
5907 alc260_input_mixer },
5908 .init_verbs = { alc260_init_verbs },
5909 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5910 .dac_nids = alc260_dac_nids,
5911 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5912 .adc_nids = alc260_adc_nids,
5913 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5914 .channel_mode = alc260_modes,
5915 .input_mux = &alc260_capture_source,
5918 .mixers = { alc260_hp_output_mixer,
5919 alc260_input_mixer },
5920 .init_verbs = { alc260_init_verbs,
5921 alc260_hp_unsol_verbs },
5922 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5923 .dac_nids = alc260_dac_nids,
5924 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5925 .adc_nids = alc260_adc_nids_alt,
5926 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5927 .channel_mode = alc260_modes,
5928 .input_mux = &alc260_capture_source,
5929 .unsol_event = alc260_hp_unsol_event,
5930 .init_hook = alc260_hp_automute,
5932 [ALC260_HP_DC7600] = {
5933 .mixers = { alc260_hp_dc7600_mixer,
5934 alc260_input_mixer },
5935 .init_verbs = { alc260_init_verbs,
5936 alc260_hp_dc7600_verbs },
5937 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5938 .dac_nids = alc260_dac_nids,
5939 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5940 .adc_nids = alc260_adc_nids_alt,
5941 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5942 .channel_mode = alc260_modes,
5943 .input_mux = &alc260_capture_source,
5944 .unsol_event = alc260_hp_3012_unsol_event,
5945 .init_hook = alc260_hp_3012_automute,
5947 [ALC260_HP_3013] = {
5948 .mixers = { alc260_hp_3013_mixer,
5949 alc260_input_mixer },
5950 .init_verbs = { alc260_hp_3013_init_verbs,
5951 alc260_hp_3013_unsol_verbs },
5952 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5953 .dac_nids = alc260_dac_nids,
5954 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5955 .adc_nids = alc260_adc_nids_alt,
5956 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5957 .channel_mode = alc260_modes,
5958 .input_mux = &alc260_capture_source,
5959 .unsol_event = alc260_hp_3013_unsol_event,
5960 .init_hook = alc260_hp_3013_automute,
5962 [ALC260_FUJITSU_S702X] = {
5963 .mixers = { alc260_fujitsu_mixer },
5964 .init_verbs = { alc260_fujitsu_init_verbs },
5965 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5966 .dac_nids = alc260_dac_nids,
5967 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5968 .adc_nids = alc260_dual_adc_nids,
5969 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5970 .channel_mode = alc260_modes,
5971 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5972 .input_mux = alc260_fujitsu_capture_sources,
5975 .mixers = { alc260_acer_mixer },
5976 .init_verbs = { alc260_acer_init_verbs },
5977 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5978 .dac_nids = alc260_dac_nids,
5979 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5980 .adc_nids = alc260_dual_adc_nids,
5981 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5982 .channel_mode = alc260_modes,
5983 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5984 .input_mux = alc260_acer_capture_sources,
5986 [ALC260_FAVORIT100] = {
5987 .mixers = { alc260_favorit100_mixer },
5988 .init_verbs = { alc260_favorit100_init_verbs },
5989 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5990 .dac_nids = alc260_dac_nids,
5991 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5992 .adc_nids = alc260_dual_adc_nids,
5993 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5994 .channel_mode = alc260_modes,
5995 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5996 .input_mux = alc260_favorit100_capture_sources,
5999 .mixers = { alc260_will_mixer },
6000 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6001 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6002 .dac_nids = alc260_dac_nids,
6003 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6004 .adc_nids = alc260_adc_nids,
6005 .dig_out_nid = ALC260_DIGOUT_NID,
6006 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6007 .channel_mode = alc260_modes,
6008 .input_mux = &alc260_capture_source,
6010 [ALC260_REPLACER_672V] = {
6011 .mixers = { alc260_replacer_672v_mixer },
6012 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6013 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6014 .dac_nids = alc260_dac_nids,
6015 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6016 .adc_nids = alc260_adc_nids,
6017 .dig_out_nid = ALC260_DIGOUT_NID,
6018 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6019 .channel_mode = alc260_modes,
6020 .input_mux = &alc260_capture_source,
6021 .unsol_event = alc260_replacer_672v_unsol_event,
6022 .init_hook = alc260_replacer_672v_automute,
6024 #ifdef CONFIG_SND_DEBUG
6026 .mixers = { alc260_test_mixer },
6027 .init_verbs = { alc260_test_init_verbs },
6028 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6029 .dac_nids = alc260_test_dac_nids,
6030 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6031 .adc_nids = alc260_test_adc_nids,
6032 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6033 .channel_mode = alc260_modes,
6034 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6035 .input_mux = alc260_test_capture_sources,
6040 static int patch_alc260(struct hda_codec *codec)
6042 struct alc_spec *spec;
6043 int err, board_config;
6045 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6051 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6054 if (board_config < 0) {
6055 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
6056 "trying auto-probe from BIOS...\n");
6057 board_config = ALC260_AUTO;
6060 if (board_config == ALC260_AUTO) {
6061 /* automatic parse from the BIOS config */
6062 err = alc260_parse_auto_config(codec);
6068 "hda_codec: Cannot set up configuration "
6069 "from BIOS. Using base mode...\n");
6070 board_config = ALC260_BASIC;
6074 err = snd_hda_attach_beep_device(codec, 0x1);
6080 if (board_config != ALC260_AUTO)
6081 setup_preset(spec, &alc260_presets[board_config]);
6083 spec->stream_name_analog = "ALC260 Analog";
6084 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6085 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6087 spec->stream_name_digital = "ALC260 Digital";
6088 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6089 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6091 if (!spec->adc_nids && spec->input_mux) {
6092 /* check whether NID 0x04 is valid */
6093 unsigned int wcap = get_wcaps(codec, 0x04);
6094 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6096 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6097 spec->adc_nids = alc260_adc_nids_alt;
6098 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6100 spec->adc_nids = alc260_adc_nids;
6101 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6104 set_capture_mixer(spec);
6105 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6107 spec->vmaster_nid = 0x08;
6109 codec->patch_ops = alc_patch_ops;
6110 if (board_config == ALC260_AUTO)
6111 spec->init_hook = alc260_auto_init;
6112 #ifdef CONFIG_SND_HDA_POWER_SAVE
6113 if (!spec->loopback.amplist)
6114 spec->loopback.amplist = alc260_loopbacks;
6116 codec->proc_widget_hook = print_realtek_coef;
6125 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6126 * configuration. Each pin widget can choose any input DACs and a mixer.
6127 * Each ADC is connected from a mixer of all inputs. This makes possible
6128 * 6-channel independent captures.
6130 * In addition, an independent DAC for the multi-playback (not used in this
6133 #define ALC882_DIGOUT_NID 0x06
6134 #define ALC882_DIGIN_NID 0x0a
6136 static struct hda_channel_mode alc882_ch_modes[1] = {
6140 static hda_nid_t alc882_dac_nids[4] = {
6141 /* front, rear, clfe, rear_surr */
6142 0x02, 0x03, 0x04, 0x05
6145 /* identical with ALC880 */
6146 #define alc882_adc_nids alc880_adc_nids
6147 #define alc882_adc_nids_alt alc880_adc_nids_alt
6149 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6150 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6153 /* FIXME: should be a matrix-type input source selection */
6155 static struct hda_input_mux alc882_capture_source = {
6159 { "Front Mic", 0x1 },
6167 static struct hda_verb alc882_3ST_ch2_init[] = {
6168 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6169 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6170 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6171 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6178 static struct hda_verb alc882_3ST_ch6_init[] = {
6179 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6180 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6181 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6182 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6183 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6184 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6188 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6189 { 2, alc882_3ST_ch2_init },
6190 { 6, alc882_3ST_ch6_init },
6196 static struct hda_verb alc882_sixstack_ch6_init[] = {
6197 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6198 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6199 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6200 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6207 static struct hda_verb alc882_sixstack_ch8_init[] = {
6208 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6209 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6210 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6211 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6215 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6216 { 6, alc882_sixstack_ch6_init },
6217 { 8, alc882_sixstack_ch8_init },
6221 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6227 static struct hda_verb alc885_mbp_ch2_init[] = {
6228 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6229 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6230 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6237 static struct hda_verb alc885_mbp_ch6_init[] = {
6238 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6239 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6240 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6241 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6242 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6246 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6247 { 2, alc885_mbp_ch2_init },
6248 { 6, alc885_mbp_ch6_init },
6252 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6253 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6255 static struct snd_kcontrol_new alc882_base_mixer[] = {
6256 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6257 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6258 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6259 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6260 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6261 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6262 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6263 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6264 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6265 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6267 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6268 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6269 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6270 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6272 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6273 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6275 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6276 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6280 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6281 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6282 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6283 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6284 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6286 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6288 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6289 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6290 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6293 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6294 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6295 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6298 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6299 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6301 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6306 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6312 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6313 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6316 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6317 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6318 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6319 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6323 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6324 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6326 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6328 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6330 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6335 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6336 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6339 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6343 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6345 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6352 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6357 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6360 .name = "Channel Mode",
6361 .info = alc_ch_mode_info,
6362 .get = alc_ch_mode_get,
6363 .put = alc_ch_mode_put,
6368 static struct hda_verb alc882_init_verbs[] = {
6369 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6375 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6376 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6378 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6380 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6382 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6383 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6384 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6386 /* Front Pin: output 0 (0x0c) */
6387 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6388 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6389 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6390 /* Rear Pin: output 1 (0x0d) */
6391 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6392 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6393 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6394 /* CLFE Pin: output 2 (0x0e) */
6395 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6396 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6397 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6398 /* Side Pin: output 3 (0x0f) */
6399 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6400 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6401 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6402 /* Mic (rear) pin: input vref at 80% */
6403 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6405 /* Front Mic pin: input vref at 80% */
6406 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6407 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6408 /* Line In pin: input */
6409 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6410 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6411 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6413 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6414 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6415 /* CD pin widget for input */
6416 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6418 /* FIXME: use matrix-type input source selection */
6419 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6420 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6421 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6422 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6423 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6427 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6428 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6432 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6433 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6434 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6435 /* ADC1: mute amp left and right */
6436 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6437 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6438 /* ADC2: mute amp left and right */
6439 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6440 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6441 /* ADC3: mute amp left and right */
6442 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6443 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6448 static struct hda_verb alc882_eapd_verbs[] = {
6449 /* change to EAPD mode */
6450 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6451 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6456 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6457 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6458 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6459 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6461 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6462 /* FIXME: this looks suspicious...
6463 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6464 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6469 static struct hda_verb alc882_macpro_init_verbs[] = {
6470 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6472 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6474 /* Front Pin: output 0 (0x0c) */
6475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6476 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6478 /* Front Mic pin: input vref at 80% */
6479 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6480 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6481 /* Speaker: output */
6482 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6483 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6484 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6485 /* Headphone output (output 0 - 0x0c) */
6486 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6487 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6488 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6490 /* FIXME: use matrix-type input source selection */
6491 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6492 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6498 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6499 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6500 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6501 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6503 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6504 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6505 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6506 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6507 /* ADC1: mute amp left and right */
6508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6509 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6510 /* ADC2: mute amp left and right */
6511 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6512 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6513 /* ADC3: mute amp left and right */
6514 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6515 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6520 /* Macbook Pro rev3 */
6521 static struct hda_verb alc885_mbp3_init_verbs[] = {
6522 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6524 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6525 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6527 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6528 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6529 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6530 /* Front Pin: output 0 (0x0c) */
6531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6532 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6533 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6534 /* HP Pin: output 0 (0x0d) */
6535 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6536 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6537 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6538 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6539 /* Mic (rear) pin: input vref at 80% */
6540 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6542 /* Front Mic pin: input vref at 80% */
6543 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6544 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6545 /* Line In pin: use output 1 when in LineOut mode */
6546 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6547 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6548 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6550 /* FIXME: use matrix-type input source selection */
6551 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6552 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6555 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6556 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6558 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6565 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6567 /* ADC1: mute amp left and right */
6568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6569 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6570 /* ADC2: mute amp left and right */
6571 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6572 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6573 /* ADC3: mute amp left and right */
6574 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6575 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6580 /* iMac 24 mixer. */
6581 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6582 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6583 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6587 /* iMac 24 init verbs. */
6588 static struct hda_verb alc885_imac24_init_verbs[] = {
6589 /* Internal speakers: output 0 (0x0c) */
6590 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6591 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6592 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6593 /* Internal speakers: output 0 (0x0c) */
6594 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6595 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6596 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6597 /* Headphone: output 0 (0x0c) */
6598 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6599 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6600 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6601 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6602 /* Front Mic: input vref at 80% */
6603 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6604 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6608 /* Toggle speaker-output according to the hp-jack state */
6609 static void alc885_imac24_automute(struct hda_codec *codec)
6611 unsigned int present;
6613 present = snd_hda_codec_read(codec, 0x14, 0,
6614 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6615 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6616 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6617 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6618 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6621 /* Processes unsolicited events. */
6622 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6625 /* Headphone insertion or removal. */
6626 if ((res >> 26) == ALC880_HP_EVENT)
6627 alc885_imac24_automute(codec);
6630 static void alc885_mbp3_automute(struct hda_codec *codec)
6632 unsigned int present;
6634 present = snd_hda_codec_read(codec, 0x15, 0,
6635 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6636 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6637 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6638 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6639 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6642 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6645 /* Headphone insertion or removal. */
6646 if ((res >> 26) == ALC880_HP_EVENT)
6647 alc885_mbp3_automute(codec);
6651 static struct hda_verb alc882_targa_verbs[] = {
6652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6653 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6658 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6659 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6660 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6662 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6663 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6664 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6665 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6669 /* toggle speaker-output according to the hp-jack state */
6670 static void alc882_targa_automute(struct hda_codec *codec)
6672 unsigned int present;
6674 present = snd_hda_codec_read(codec, 0x14, 0,
6675 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6676 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6677 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6678 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6682 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6684 /* Looks like the unsol event is incompatible with the standard
6685 * definition. 4bit tag is placed at 26 bit!
6687 if (((res >> 26) == ALC880_HP_EVENT)) {
6688 alc882_targa_automute(codec);
6692 static struct hda_verb alc882_asus_a7j_verbs[] = {
6693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6694 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6696 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6698 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6700 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6701 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6702 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6704 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6705 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6710 static struct hda_verb alc882_asus_a7m_verbs[] = {
6711 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6714 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6715 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6716 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6718 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6719 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6720 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6722 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6723 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6724 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6728 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6730 unsigned int gpiostate, gpiomask, gpiodir;
6732 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6733 AC_VERB_GET_GPIO_DATA, 0);
6736 gpiostate |= (1 << pin);
6738 gpiostate &= ~(1 << pin);
6740 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6741 AC_VERB_GET_GPIO_MASK, 0);
6742 gpiomask |= (1 << pin);
6744 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6745 AC_VERB_GET_GPIO_DIRECTION, 0);
6746 gpiodir |= (1 << pin);
6749 snd_hda_codec_write(codec, codec->afg, 0,
6750 AC_VERB_SET_GPIO_MASK, gpiomask);
6751 snd_hda_codec_write(codec, codec->afg, 0,
6752 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6756 snd_hda_codec_write(codec, codec->afg, 0,
6757 AC_VERB_SET_GPIO_DATA, gpiostate);
6760 /* set up GPIO at initialization */
6761 static void alc885_macpro_init_hook(struct hda_codec *codec)
6763 alc882_gpio_mute(codec, 0, 0);
6764 alc882_gpio_mute(codec, 1, 0);
6767 /* set up GPIO and update auto-muting at initialization */
6768 static void alc885_imac24_init_hook(struct hda_codec *codec)
6770 alc885_macpro_init_hook(codec);
6771 alc885_imac24_automute(codec);
6775 * generic initialization of ADC, input mixers and output mixers
6777 static struct hda_verb alc882_auto_init_verbs[] = {
6779 * Unmute ADC0-2 and set the default input to mic-in
6781 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6783 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6784 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6785 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6786 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6788 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6790 * Note: PASD motherboards uses the Line In 2 as the input for
6791 * front panel mic (mic 2)
6793 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6794 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6797 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6798 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6801 * Set up output mixers (0x0c - 0x0f)
6803 /* set vol=0 to output mixers */
6804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6805 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6806 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6807 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6808 /* set up input amps for analog loopback */
6809 /* Amp Indices: DAC = 0, mixer = 1 */
6810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6812 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6813 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6814 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6815 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6816 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6817 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6818 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6819 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6821 /* FIXME: use matrix-type input source selection */
6822 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6823 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6824 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6825 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6826 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6827 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6829 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6830 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6831 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6832 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6834 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6835 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6836 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6837 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6842 #ifdef CONFIG_SND_HDA_POWER_SAVE
6843 #define alc882_loopbacks alc880_loopbacks
6846 /* pcm configuration: identiacal with ALC880 */
6847 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6848 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6849 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6850 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6853 * configuration and preset
6855 static const char *alc882_models[ALC882_MODEL_LAST] = {
6856 [ALC882_3ST_DIG] = "3stack-dig",
6857 [ALC882_6ST_DIG] = "6stack-dig",
6858 [ALC882_ARIMA] = "arima",
6859 [ALC882_W2JC] = "w2jc",
6860 [ALC882_TARGA] = "targa",
6861 [ALC882_ASUS_A7J] = "asus-a7j",
6862 [ALC882_ASUS_A7M] = "asus-a7m",
6863 [ALC885_MACPRO] = "macpro",
6864 [ALC885_MBP3] = "mbp3",
6865 [ALC885_IMAC24] = "imac24",
6866 [ALC882_AUTO] = "auto",
6869 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6870 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6871 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6872 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6873 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6874 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6875 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6876 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6877 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6878 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6879 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6880 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6881 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6885 static struct alc_config_preset alc882_presets[] = {
6886 [ALC882_3ST_DIG] = {
6887 .mixers = { alc882_base_mixer },
6888 .init_verbs = { alc882_init_verbs },
6889 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6890 .dac_nids = alc882_dac_nids,
6891 .dig_out_nid = ALC882_DIGOUT_NID,
6892 .dig_in_nid = ALC882_DIGIN_NID,
6893 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6894 .channel_mode = alc882_ch_modes,
6896 .input_mux = &alc882_capture_source,
6898 [ALC882_6ST_DIG] = {
6899 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6900 .init_verbs = { alc882_init_verbs },
6901 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6902 .dac_nids = alc882_dac_nids,
6903 .dig_out_nid = ALC882_DIGOUT_NID,
6904 .dig_in_nid = ALC882_DIGIN_NID,
6905 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6906 .channel_mode = alc882_sixstack_modes,
6907 .input_mux = &alc882_capture_source,
6910 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6911 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6912 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6913 .dac_nids = alc882_dac_nids,
6914 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6915 .channel_mode = alc882_sixstack_modes,
6916 .input_mux = &alc882_capture_source,
6919 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6920 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6921 alc880_gpio1_init_verbs },
6922 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6923 .dac_nids = alc882_dac_nids,
6924 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6925 .channel_mode = alc880_threestack_modes,
6927 .input_mux = &alc882_capture_source,
6928 .dig_out_nid = ALC882_DIGOUT_NID,
6931 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6932 .init_verbs = { alc885_mbp3_init_verbs,
6933 alc880_gpio1_init_verbs },
6934 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6935 .dac_nids = alc882_dac_nids,
6936 .channel_mode = alc885_mbp_6ch_modes,
6937 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6938 .input_mux = &alc882_capture_source,
6939 .dig_out_nid = ALC882_DIGOUT_NID,
6940 .dig_in_nid = ALC882_DIGIN_NID,
6941 .unsol_event = alc885_mbp3_unsol_event,
6942 .init_hook = alc885_mbp3_automute,
6945 .mixers = { alc882_macpro_mixer },
6946 .init_verbs = { alc882_macpro_init_verbs },
6947 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6948 .dac_nids = alc882_dac_nids,
6949 .dig_out_nid = ALC882_DIGOUT_NID,
6950 .dig_in_nid = ALC882_DIGIN_NID,
6951 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6952 .channel_mode = alc882_ch_modes,
6953 .input_mux = &alc882_capture_source,
6954 .init_hook = alc885_macpro_init_hook,
6957 .mixers = { alc885_imac24_mixer },
6958 .init_verbs = { alc885_imac24_init_verbs },
6959 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6960 .dac_nids = alc882_dac_nids,
6961 .dig_out_nid = ALC882_DIGOUT_NID,
6962 .dig_in_nid = ALC882_DIGIN_NID,
6963 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6964 .channel_mode = alc882_ch_modes,
6965 .input_mux = &alc882_capture_source,
6966 .unsol_event = alc885_imac24_unsol_event,
6967 .init_hook = alc885_imac24_init_hook,
6970 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6971 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6972 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6973 .dac_nids = alc882_dac_nids,
6974 .dig_out_nid = ALC882_DIGOUT_NID,
6975 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6976 .adc_nids = alc882_adc_nids,
6977 .capsrc_nids = alc882_capsrc_nids,
6978 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6979 .channel_mode = alc882_3ST_6ch_modes,
6981 .input_mux = &alc882_capture_source,
6982 .unsol_event = alc882_targa_unsol_event,
6983 .init_hook = alc882_targa_automute,
6985 [ALC882_ASUS_A7J] = {
6986 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6987 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6988 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6989 .dac_nids = alc882_dac_nids,
6990 .dig_out_nid = ALC882_DIGOUT_NID,
6991 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6992 .adc_nids = alc882_adc_nids,
6993 .capsrc_nids = alc882_capsrc_nids,
6994 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6995 .channel_mode = alc882_3ST_6ch_modes,
6997 .input_mux = &alc882_capture_source,
6999 [ALC882_ASUS_A7M] = {
7000 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7001 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7002 alc880_gpio1_init_verbs,
7003 alc882_asus_a7m_verbs },
7004 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7005 .dac_nids = alc882_dac_nids,
7006 .dig_out_nid = ALC882_DIGOUT_NID,
7007 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7008 .channel_mode = alc880_threestack_modes,
7010 .input_mux = &alc882_capture_source,
7019 PINFIX_ABIT_AW9D_MAX
7022 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7023 { 0x15, 0x01080104 }, /* side */
7024 { 0x16, 0x01011012 }, /* rear */
7025 { 0x17, 0x01016011 }, /* clfe */
7029 static const struct alc_pincfg *alc882_pin_fixes[] = {
7030 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7033 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7034 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7039 * BIOS auto configuration
7041 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7042 hda_nid_t nid, int pin_type,
7046 struct alc_spec *spec = codec->spec;
7049 alc_set_pin_output(codec, nid, pin_type);
7050 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7053 idx = spec->multiout.dac_nids[dac_idx] - 2;
7054 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7058 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7060 struct alc_spec *spec = codec->spec;
7063 for (i = 0; i <= HDA_SIDE; i++) {
7064 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7065 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7067 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7072 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7074 struct alc_spec *spec = codec->spec;
7077 pin = spec->autocfg.hp_pins[0];
7078 if (pin) /* connect to front */
7080 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7081 pin = spec->autocfg.speaker_pins[0];
7083 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7086 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7087 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7089 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7091 struct alc_spec *spec = codec->spec;
7094 for (i = 0; i < AUTO_PIN_LAST; i++) {
7095 hda_nid_t nid = spec->autocfg.input_pins[i];
7098 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7099 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7100 snd_hda_codec_write(codec, nid, 0,
7101 AC_VERB_SET_AMP_GAIN_MUTE,
7106 static void alc882_auto_init_input_src(struct hda_codec *codec)
7108 struct alc_spec *spec = codec->spec;
7111 for (c = 0; c < spec->num_adc_nids; c++) {
7112 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7113 hda_nid_t nid = spec->capsrc_nids[c];
7114 unsigned int mux_idx;
7115 const struct hda_input_mux *imux;
7116 int conns, mute, idx, item;
7118 conns = snd_hda_get_connections(codec, nid, conn_list,
7119 ARRAY_SIZE(conn_list));
7122 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7123 imux = &spec->input_mux[mux_idx];
7124 for (idx = 0; idx < conns; idx++) {
7125 /* if the current connection is the selected one,
7126 * unmute it as default - otherwise mute it
7128 mute = AMP_IN_MUTE(idx);
7129 for (item = 0; item < imux->num_items; item++) {
7130 if (imux->items[item].index == idx) {
7131 if (spec->cur_mux[c] == item)
7132 mute = AMP_IN_UNMUTE(idx);
7136 /* check if we have a selector or mixer
7137 * we could check for the widget type instead, but
7138 * just check for Amp-In presence (in case of mixer
7139 * without amp-in there is something wrong, this
7140 * function shouldn't be used or capsrc nid is wrong)
7142 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7143 snd_hda_codec_write(codec, nid, 0,
7144 AC_VERB_SET_AMP_GAIN_MUTE,
7146 else if (mute != AMP_IN_MUTE(idx))
7147 snd_hda_codec_write(codec, nid, 0,
7148 AC_VERB_SET_CONNECT_SEL,
7154 /* add mic boosts if needed */
7155 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7157 struct alc_spec *spec = codec->spec;
7161 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7162 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7163 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7165 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7169 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7170 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7171 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7173 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7180 /* almost identical with ALC880 parser... */
7181 static int alc882_parse_auto_config(struct hda_codec *codec)
7183 struct alc_spec *spec = codec->spec;
7184 int err = alc880_parse_auto_config(codec);
7189 return 0; /* no config found */
7191 err = alc_auto_add_mic_boost(codec);
7195 /* hack - override the init verbs */
7196 spec->init_verbs[0] = alc882_auto_init_verbs;
7198 return 1; /* config found */
7201 /* additional initialization for auto-configuration model */
7202 static void alc882_auto_init(struct hda_codec *codec)
7204 struct alc_spec *spec = codec->spec;
7205 alc882_auto_init_multi_out(codec);
7206 alc882_auto_init_hp_out(codec);
7207 alc882_auto_init_analog_input(codec);
7208 alc882_auto_init_input_src(codec);
7209 if (spec->unsol_event)
7210 alc_inithook(codec);
7213 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7215 static int patch_alc882(struct hda_codec *codec)
7217 struct alc_spec *spec;
7218 int err, board_config;
7220 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7226 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7230 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7231 /* Pick up systems that don't supply PCI SSID */
7232 switch (codec->subsystem_id) {
7233 case 0x106b0c00: /* Mac Pro */
7234 board_config = ALC885_MACPRO;
7236 case 0x106b1000: /* iMac 24 */
7237 case 0x106b2800: /* AppleTV */
7238 case 0x106b3e00: /* iMac 24 Aluminium */
7239 board_config = ALC885_IMAC24;
7241 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7242 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7243 case 0x106b00a4: /* MacbookPro4,1 */
7244 case 0x106b2c00: /* Macbook Pro rev3 */
7245 case 0x106b3600: /* Macbook 3.1 */
7246 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7247 board_config = ALC885_MBP3;
7250 /* ALC889A is handled better as ALC888-compatible */
7251 if (codec->revision_id == 0x100101 ||
7252 codec->revision_id == 0x100103) {
7254 return patch_alc883(codec);
7256 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7257 "trying auto-probe from BIOS...\n");
7258 board_config = ALC882_AUTO;
7262 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7264 if (board_config == ALC882_AUTO) {
7265 /* automatic parse from the BIOS config */
7266 err = alc882_parse_auto_config(codec);
7272 "hda_codec: Cannot set up configuration "
7273 "from BIOS. Using base mode...\n");
7274 board_config = ALC882_3ST_DIG;
7278 err = snd_hda_attach_beep_device(codec, 0x1);
7284 if (board_config != ALC882_AUTO)
7285 setup_preset(spec, &alc882_presets[board_config]);
7287 if (codec->vendor_id == 0x10ec0885) {
7288 spec->stream_name_analog = "ALC885 Analog";
7289 spec->stream_name_digital = "ALC885 Digital";
7291 spec->stream_name_analog = "ALC882 Analog";
7292 spec->stream_name_digital = "ALC882 Digital";
7295 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7296 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7297 /* FIXME: setup DAC5 */
7298 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7299 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7301 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7302 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7304 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7305 if (!spec->adc_nids && spec->input_mux) {
7306 /* check whether NID 0x07 is valid */
7307 unsigned int wcap = get_wcaps(codec, 0x07);
7309 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7310 if (wcap != AC_WID_AUD_IN) {
7311 spec->adc_nids = alc882_adc_nids_alt;
7312 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7313 spec->capsrc_nids = alc882_capsrc_nids_alt;
7315 spec->adc_nids = alc882_adc_nids;
7316 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7317 spec->capsrc_nids = alc882_capsrc_nids;
7320 set_capture_mixer(spec);
7321 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7323 spec->vmaster_nid = 0x0c;
7325 codec->patch_ops = alc_patch_ops;
7326 if (board_config == ALC882_AUTO)
7327 spec->init_hook = alc882_auto_init;
7328 #ifdef CONFIG_SND_HDA_POWER_SAVE
7329 if (!spec->loopback.amplist)
7330 spec->loopback.amplist = alc882_loopbacks;
7332 codec->proc_widget_hook = print_realtek_coef;
7340 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7341 * configuration. Each pin widget can choose any input DACs and a mixer.
7342 * Each ADC is connected from a mixer of all inputs. This makes possible
7343 * 6-channel independent captures.
7345 * In addition, an independent DAC for the multi-playback (not used in this
7348 #define ALC883_DIGOUT_NID 0x06
7349 #define ALC883_DIGIN_NID 0x0a
7351 #define ALC1200_DIGOUT_NID 0x10
7353 static hda_nid_t alc883_dac_nids[4] = {
7354 /* front, rear, clfe, rear_surr */
7355 0x02, 0x03, 0x04, 0x05
7358 static hda_nid_t alc883_adc_nids[2] = {
7363 static hda_nid_t alc883_adc_nids_alt[1] = {
7368 static hda_nid_t alc883_adc_nids_rev[2] = {
7373 #define alc889_adc_nids alc880_adc_nids
7375 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7377 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7379 #define alc889_capsrc_nids alc882_capsrc_nids
7382 /* FIXME: should be a matrix-type input source selection */
7384 static struct hda_input_mux alc883_capture_source = {
7388 { "Front Mic", 0x1 },
7394 static struct hda_input_mux alc883_3stack_6ch_intel = {
7398 { "Front Mic", 0x0 },
7404 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7412 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7422 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7430 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7434 { "Front Mic", 0x1 },
7439 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7450 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7457 static struct hda_verb alc883_3ST_ch2_init[] = {
7458 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7459 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7460 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7461 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7468 static struct hda_verb alc883_3ST_ch4_init[] = {
7469 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7470 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7471 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7472 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7473 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7480 static struct hda_verb alc883_3ST_ch6_init[] = {
7481 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7482 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7483 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7484 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7485 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7486 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7490 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7491 { 2, alc883_3ST_ch2_init },
7492 { 4, alc883_3ST_ch4_init },
7493 { 6, alc883_3ST_ch6_init },
7499 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7500 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7501 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7502 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7503 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7510 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7511 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7512 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7513 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7514 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7515 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7522 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7523 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7524 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7525 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7526 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7527 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7528 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7532 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7533 { 2, alc883_3ST_ch2_intel_init },
7534 { 4, alc883_3ST_ch4_intel_init },
7535 { 6, alc883_3ST_ch6_intel_init },
7541 static struct hda_verb alc883_sixstack_ch6_init[] = {
7542 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7543 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7544 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7545 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7552 static struct hda_verb alc883_sixstack_ch8_init[] = {
7553 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7554 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7555 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7556 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7560 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7561 { 6, alc883_sixstack_ch6_init },
7562 { 8, alc883_sixstack_ch8_init },
7565 static struct hda_verb alc883_medion_eapd_verbs[] = {
7566 /* eanable EAPD on medion laptop */
7567 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7568 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7572 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7573 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7576 static struct snd_kcontrol_new alc883_base_mixer[] = {
7577 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7578 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7579 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7580 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7581 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7582 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7583 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7584 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7585 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7586 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7587 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7588 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7589 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7590 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7591 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7592 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7593 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7594 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7595 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7596 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7597 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7601 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7602 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7603 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7604 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7605 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7606 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7607 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7608 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7610 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7611 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7612 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7613 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7614 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7618 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7619 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7620 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7621 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7622 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7624 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7626 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7627 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7628 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7632 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7633 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7634 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7635 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7636 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7638 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7640 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7641 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7642 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7646 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7648 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7650 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7651 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7652 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7653 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7655 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7658 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7659 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7663 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7664 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7665 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7666 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7667 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7668 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7669 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7670 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7671 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7672 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7678 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7680 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7681 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7682 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7686 static struct snd_kcontrol_new alc883_3ST_6ch_intel_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,
7693 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7694 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7695 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7696 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7697 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7698 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7699 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7700 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7702 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7704 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7705 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7706 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7710 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7711 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7712 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7713 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7714 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7715 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7716 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7717 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7718 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7719 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7720 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7721 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7722 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7723 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7724 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7725 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7727 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7728 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7729 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7733 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7734 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7735 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7736 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7737 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7738 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7739 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7740 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7741 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7742 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7743 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7744 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7745 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7746 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, 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),
7753 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7754 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7756 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7757 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7758 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7759 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7760 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7762 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7763 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7764 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7768 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7769 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7770 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7771 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7772 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7773 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7774 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7776 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7780 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7781 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7782 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7783 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7784 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7785 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7786 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7787 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7788 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7789 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7793 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7794 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7795 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7796 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7799 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7800 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7801 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7802 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7806 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7807 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7808 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7809 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7810 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7811 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7812 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7813 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7818 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7819 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7820 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7821 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7822 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7823 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7824 0x0d, 1, 0x0, HDA_OUTPUT),
7825 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7826 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7827 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7828 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7829 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7830 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7831 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7832 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7833 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7834 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7835 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7837 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7839 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7840 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7841 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7845 static struct hda_bind_ctls alc883_bind_cap_vol = {
7846 .ops = &snd_hda_bind_vol,
7848 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7849 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7854 static struct hda_bind_ctls alc883_bind_cap_switch = {
7855 .ops = &snd_hda_bind_sw,
7857 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7858 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7863 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7864 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7865 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7866 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7867 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7868 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, 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),
7875 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7876 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7877 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7879 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7880 /* .name = "Capture Source", */
7881 .name = "Input Source",
7883 .info = alc_mux_enum_info,
7884 .get = alc_mux_enum_get,
7885 .put = alc_mux_enum_put,
7890 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7892 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7893 .name = "Channel Mode",
7894 .info = alc_ch_mode_info,
7895 .get = alc_ch_mode_get,
7896 .put = alc_ch_mode_put,
7901 static struct hda_verb alc883_init_verbs[] = {
7902 /* ADC1: mute amp left and right */
7903 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7904 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7905 /* ADC2: mute amp left and right */
7906 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7907 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7908 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7910 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7911 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7913 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7914 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7915 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7917 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7918 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7919 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7921 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7922 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7923 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7925 /* mute analog input loopbacks */
7926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7932 /* Front Pin: output 0 (0x0c) */
7933 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7934 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7935 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7936 /* Rear Pin: output 1 (0x0d) */
7937 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7938 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7939 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7940 /* CLFE Pin: output 2 (0x0e) */
7941 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7942 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7943 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7944 /* Side Pin: output 3 (0x0f) */
7945 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7946 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7947 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7948 /* Mic (rear) pin: input vref at 80% */
7949 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7950 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7951 /* Front Mic pin: input vref at 80% */
7952 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7953 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7954 /* Line In pin: input */
7955 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7956 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7957 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7958 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7959 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7960 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7961 /* CD pin widget for input */
7962 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7964 /* FIXME: use matrix-type input source selection */
7965 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7967 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7968 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7969 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7972 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7973 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7974 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7975 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7979 /* toggle speaker-output according to the hp-jack state */
7980 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7982 unsigned int present;
7984 present = snd_hda_codec_read(codec, 0x15, 0,
7985 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7986 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7987 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7988 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7989 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7992 /* auto-toggle front mic */
7994 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7996 unsigned int present;
7999 present = snd_hda_codec_read(codec, 0x18, 0,
8000 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8001 bits = present ? HDA_AMP_MUTE : 0;
8002 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8006 static void alc883_mitac_automute(struct hda_codec *codec)
8008 alc883_mitac_hp_automute(codec);
8009 /* alc883_mitac_mic_automute(codec); */
8012 static void alc883_mitac_unsol_event(struct hda_codec *codec,
8015 switch (res >> 26) {
8016 case ALC880_HP_EVENT:
8017 alc883_mitac_hp_automute(codec);
8019 case ALC880_MIC_EVENT:
8020 /* alc883_mitac_mic_automute(codec); */
8025 static struct hda_verb alc883_mitac_verbs[] = {
8027 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8028 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8030 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8031 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8033 /* enable unsolicited event */
8034 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8035 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8040 static struct hda_verb alc883_clevo_m720_verbs[] = {
8042 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8043 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8045 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8046 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8048 /* enable unsolicited event */
8049 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8050 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8055 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8057 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8058 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8061 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8063 /* enable unsolicited event */
8064 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8069 static struct hda_verb alc883_tagra_verbs[] = {
8070 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8073 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8074 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8076 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8077 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8078 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8080 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8081 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8082 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8083 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8088 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8089 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8090 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8091 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8095 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8096 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8098 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8103 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8104 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8106 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8107 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8108 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8112 static struct hda_verb alc883_haier_w66_verbs[] = {
8113 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8116 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8118 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8119 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8120 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8121 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8125 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8127 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8128 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8129 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8130 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8132 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8133 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8137 static struct hda_verb alc888_6st_dell_verbs[] = {
8138 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8142 static void alc888_3st_hp_front_automute(struct hda_codec *codec)
8144 unsigned int present, bits;
8146 present = snd_hda_codec_read(codec, 0x1b, 0,
8147 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8148 bits = present ? HDA_AMP_MUTE : 0;
8149 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8150 HDA_AMP_MUTE, bits);
8151 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8152 HDA_AMP_MUTE, bits);
8153 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
8154 HDA_AMP_MUTE, bits);
8157 static void alc888_3st_hp_unsol_event(struct hda_codec *codec,
8160 switch (res >> 26) {
8161 case ALC880_HP_EVENT:
8162 alc888_3st_hp_front_automute(codec);
8167 static struct hda_verb alc888_3st_hp_verbs[] = {
8168 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8169 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8170 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8171 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8178 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8179 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8180 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8181 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8182 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8189 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8190 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8191 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8192 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8193 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8194 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8201 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8202 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8203 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8204 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8205 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8206 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8207 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8211 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8212 { 2, alc888_3st_hp_2ch_init },
8213 { 4, alc888_3st_hp_4ch_init },
8214 { 6, alc888_3st_hp_6ch_init },
8217 /* toggle front-jack and RCA according to the hp-jack state */
8218 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8220 unsigned int present;
8222 present = snd_hda_codec_read(codec, 0x1b, 0,
8223 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8224 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8225 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8226 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8227 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8230 /* toggle RCA according to the front-jack state */
8231 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8233 unsigned int present;
8235 present = snd_hda_codec_read(codec, 0x14, 0,
8236 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8237 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8238 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8241 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8244 if ((res >> 26) == ALC880_HP_EVENT)
8245 alc888_lenovo_ms7195_front_automute(codec);
8246 if ((res >> 26) == ALC880_FRONT_EVENT)
8247 alc888_lenovo_ms7195_rca_automute(codec);
8250 static struct hda_verb alc883_medion_md2_verbs[] = {
8251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8256 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8260 /* toggle speaker-output according to the hp-jack state */
8261 static void alc883_medion_md2_automute(struct hda_codec *codec)
8263 unsigned int present;
8265 present = snd_hda_codec_read(codec, 0x14, 0,
8266 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8267 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8268 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8271 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8274 if ((res >> 26) == ALC880_HP_EVENT)
8275 alc883_medion_md2_automute(codec);
8278 /* toggle speaker-output according to the hp-jack state */
8279 static void alc883_tagra_automute(struct hda_codec *codec)
8281 unsigned int present;
8284 present = snd_hda_codec_read(codec, 0x14, 0,
8285 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8286 bits = present ? HDA_AMP_MUTE : 0;
8287 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8288 HDA_AMP_MUTE, bits);
8289 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8293 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
8295 if ((res >> 26) == ALC880_HP_EVENT)
8296 alc883_tagra_automute(codec);
8299 /* toggle speaker-output according to the hp-jack state */
8300 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
8302 unsigned int present;
8305 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8306 & AC_PINSENSE_PRESENCE;
8307 bits = present ? HDA_AMP_MUTE : 0;
8308 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8309 HDA_AMP_MUTE, bits);
8312 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8314 unsigned int present;
8316 present = snd_hda_codec_read(codec, 0x18, 0,
8317 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8318 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8319 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8322 static void alc883_clevo_m720_automute(struct hda_codec *codec)
8324 alc883_clevo_m720_hp_automute(codec);
8325 alc883_clevo_m720_mic_automute(codec);
8328 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8331 switch (res >> 26) {
8332 case ALC880_HP_EVENT:
8333 alc883_clevo_m720_hp_automute(codec);
8335 case ALC880_MIC_EVENT:
8336 alc883_clevo_m720_mic_automute(codec);
8341 /* toggle speaker-output according to the hp-jack state */
8342 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8344 unsigned int present;
8347 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8348 & AC_PINSENSE_PRESENCE;
8349 bits = present ? HDA_AMP_MUTE : 0;
8350 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8351 HDA_AMP_MUTE, bits);
8354 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8357 if ((res >> 26) == ALC880_HP_EVENT)
8358 alc883_2ch_fujitsu_pi2515_automute(codec);
8361 static void alc883_haier_w66_automute(struct hda_codec *codec)
8363 unsigned int present;
8366 present = snd_hda_codec_read(codec, 0x1b, 0,
8367 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8368 bits = present ? 0x80 : 0;
8369 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8373 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8376 if ((res >> 26) == ALC880_HP_EVENT)
8377 alc883_haier_w66_automute(codec);
8380 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8382 unsigned int present;
8385 present = snd_hda_codec_read(codec, 0x14, 0,
8386 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8387 bits = present ? HDA_AMP_MUTE : 0;
8388 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8389 HDA_AMP_MUTE, bits);
8392 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8394 unsigned int present;
8397 present = snd_hda_codec_read(codec, 0x1b, 0,
8398 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8399 bits = present ? HDA_AMP_MUTE : 0;
8400 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8401 HDA_AMP_MUTE, bits);
8402 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8403 HDA_AMP_MUTE, bits);
8406 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8409 if ((res >> 26) == ALC880_HP_EVENT)
8410 alc883_lenovo_101e_all_automute(codec);
8411 if ((res >> 26) == ALC880_FRONT_EVENT)
8412 alc883_lenovo_101e_ispeaker_automute(codec);
8415 /* toggle speaker-output according to the hp-jack state */
8416 static void alc883_acer_aspire_automute(struct hda_codec *codec)
8418 unsigned int present;
8420 present = snd_hda_codec_read(codec, 0x14, 0,
8421 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8422 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8423 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8424 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8425 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8428 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8431 if ((res >> 26) == ALC880_HP_EVENT)
8432 alc883_acer_aspire_automute(codec);
8435 static struct hda_verb alc883_acer_eapd_verbs[] = {
8436 /* HP Pin: output 0 (0x0c) */
8437 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8438 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8439 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8440 /* Front Pin: output 0 (0x0c) */
8441 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8442 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8443 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8444 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8445 /* eanable EAPD on medion laptop */
8446 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8447 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8448 /* enable unsolicited event */
8449 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8453 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8455 unsigned int present;
8457 present = snd_hda_codec_read(codec, 0x1b, 0,
8458 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8459 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8460 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8461 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8462 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8463 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8464 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8465 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8466 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8469 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8472 switch (res >> 26) {
8473 case ALC880_HP_EVENT:
8474 /* printk(KERN_DEBUG "hp_event\n"); */
8475 alc888_6st_dell_front_automute(codec);
8480 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8483 unsigned int present;
8485 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8486 present = snd_hda_codec_read(codec, 0x1b, 0,
8487 AC_VERB_GET_PIN_SENSE, 0);
8488 present = (present & 0x80000000) != 0;
8490 /* mute internal speaker */
8491 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8492 HDA_AMP_MUTE, HDA_AMP_MUTE);
8493 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8494 HDA_AMP_MUTE, HDA_AMP_MUTE);
8495 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8496 HDA_AMP_MUTE, HDA_AMP_MUTE);
8497 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8498 HDA_AMP_MUTE, HDA_AMP_MUTE);
8499 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8500 HDA_AMP_MUTE, HDA_AMP_MUTE);
8502 /* unmute internal speaker if necessary */
8503 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8504 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8505 HDA_AMP_MUTE, mute);
8506 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8507 HDA_AMP_MUTE, mute);
8508 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8509 HDA_AMP_MUTE, mute);
8510 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8511 HDA_AMP_MUTE, mute);
8512 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8513 HDA_AMP_MUTE, mute);
8517 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8520 if ((res >> 26) == ALC880_HP_EVENT)
8521 alc888_lenovo_sky_front_automute(codec);
8525 * generic initialization of ADC, input mixers and output mixers
8527 static struct hda_verb alc883_auto_init_verbs[] = {
8529 * Unmute ADC0-2 and set the default input to mic-in
8531 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8532 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8533 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8534 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8536 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8538 * Note: PASD motherboards uses the Line In 2 as the input for
8539 * front panel mic (mic 2)
8541 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8545 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8546 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8549 * Set up output mixers (0x0c - 0x0f)
8551 /* set vol=0 to output mixers */
8552 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8553 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8554 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8555 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8556 /* set up input amps for analog loopback */
8557 /* Amp Indices: DAC = 0, mixer = 1 */
8558 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8559 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8560 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8561 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8562 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8563 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8564 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8565 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8566 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8567 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8569 /* FIXME: use matrix-type input source selection */
8570 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8575 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8576 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8580 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8581 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8587 static struct hda_verb alc888_asus_m90v_verbs[] = {
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8591 /* enable unsolicited event */
8592 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8593 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8597 static void alc883_nb_mic_automute(struct hda_codec *codec)
8599 unsigned int present;
8601 present = snd_hda_codec_read(codec, 0x18, 0,
8602 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8603 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8604 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8605 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8606 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8609 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8611 unsigned int present;
8614 present = snd_hda_codec_read(codec, 0x1b, 0,
8615 AC_VERB_GET_PIN_SENSE, 0)
8616 & AC_PINSENSE_PRESENCE;
8617 bits = present ? 0 : PIN_OUT;
8618 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8620 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8622 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8626 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8629 switch (res >> 26) {
8630 case ALC880_HP_EVENT:
8631 alc883_M90V_speaker_automute(codec);
8633 case ALC880_MIC_EVENT:
8634 alc883_nb_mic_automute(codec);
8639 static void alc883_mode2_inithook(struct hda_codec *codec)
8641 alc883_M90V_speaker_automute(codec);
8642 alc883_nb_mic_automute(codec);
8645 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8647 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8648 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8649 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8650 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8651 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8652 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8653 /* enable unsolicited event */
8654 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8658 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8660 unsigned int present;
8663 present = snd_hda_codec_read(codec, 0x14, 0,
8664 AC_VERB_GET_PIN_SENSE, 0)
8665 & AC_PINSENSE_PRESENCE;
8666 bits = present ? 0 : PIN_OUT;
8667 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8671 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8674 switch (res >> 26) {
8675 case ALC880_HP_EVENT:
8676 alc883_eee1601_speaker_automute(codec);
8681 static void alc883_eee1601_inithook(struct hda_codec *codec)
8683 alc883_eee1601_speaker_automute(codec);
8686 #ifdef CONFIG_SND_HDA_POWER_SAVE
8687 #define alc883_loopbacks alc880_loopbacks
8690 /* pcm configuration: identiacal with ALC880 */
8691 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8692 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8693 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8694 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8695 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8698 * configuration and preset
8700 static const char *alc883_models[ALC883_MODEL_LAST] = {
8701 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8702 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8703 [ALC883_3ST_6ch] = "3stack-6ch",
8704 [ALC883_6ST_DIG] = "6stack-dig",
8705 [ALC883_TARGA_DIG] = "targa-dig",
8706 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8707 [ALC883_ACER] = "acer",
8708 [ALC883_ACER_ASPIRE] = "acer-aspire",
8709 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8710 [ALC883_MEDION] = "medion",
8711 [ALC883_MEDION_MD2] = "medion-md2",
8712 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8713 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8714 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8715 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8716 [ALC888_LENOVO_SKY] = "lenovo-sky",
8717 [ALC883_HAIER_W66] = "haier-w66",
8718 [ALC888_3ST_HP] = "3stack-hp",
8719 [ALC888_6ST_DELL] = "6stack-dell",
8720 [ALC883_MITAC] = "mitac",
8721 [ALC883_CLEVO_M720] = "clevo-m720",
8722 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8723 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8724 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8725 [ALC1200_ASUS_P5Q] = "asus-p5q",
8726 [ALC883_AUTO] = "auto",
8729 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8730 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8731 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8732 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8733 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8734 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8735 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8736 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8737 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8738 ALC888_ACER_ASPIRE_4930G),
8739 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8740 ALC888_ACER_ASPIRE_4930G),
8741 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8742 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8743 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8744 ALC888_ACER_ASPIRE_4930G),
8745 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8746 ALC888_ACER_ASPIRE_4930G),
8748 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
8749 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8750 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8751 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8752 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8753 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8754 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8755 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8756 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8757 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8758 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8759 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8760 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8761 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8762 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8763 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8764 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8765 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8766 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8767 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8768 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8769 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8770 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8771 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8772 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8773 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8774 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8775 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8776 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8777 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8778 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8779 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8780 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8781 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8782 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8783 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8784 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8785 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8786 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8787 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8788 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8789 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8790 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8791 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8792 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8793 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8794 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8795 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8796 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8797 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8798 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8799 ALC883_FUJITSU_PI2515),
8800 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8801 ALC888_FUJITSU_XA3530),
8802 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8803 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8804 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8805 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8806 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8807 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8808 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8809 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8810 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8811 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8812 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8813 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8814 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8815 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8819 static hda_nid_t alc883_slave_dig_outs[] = {
8820 ALC1200_DIGOUT_NID, 0,
8823 static hda_nid_t alc1200_slave_dig_outs[] = {
8824 ALC883_DIGOUT_NID, 0,
8827 static struct alc_config_preset alc883_presets[] = {
8828 [ALC883_3ST_2ch_DIG] = {
8829 .mixers = { alc883_3ST_2ch_mixer },
8830 .init_verbs = { alc883_init_verbs },
8831 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8832 .dac_nids = alc883_dac_nids,
8833 .dig_out_nid = ALC883_DIGOUT_NID,
8834 .dig_in_nid = ALC883_DIGIN_NID,
8835 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8836 .channel_mode = alc883_3ST_2ch_modes,
8837 .input_mux = &alc883_capture_source,
8839 [ALC883_3ST_6ch_DIG] = {
8840 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8841 .init_verbs = { alc883_init_verbs },
8842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8843 .dac_nids = alc883_dac_nids,
8844 .dig_out_nid = ALC883_DIGOUT_NID,
8845 .dig_in_nid = ALC883_DIGIN_NID,
8846 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8847 .channel_mode = alc883_3ST_6ch_modes,
8849 .input_mux = &alc883_capture_source,
8851 [ALC883_3ST_6ch] = {
8852 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8853 .init_verbs = { alc883_init_verbs },
8854 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8855 .dac_nids = alc883_dac_nids,
8856 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8857 .channel_mode = alc883_3ST_6ch_modes,
8859 .input_mux = &alc883_capture_source,
8861 [ALC883_3ST_6ch_INTEL] = {
8862 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8863 .init_verbs = { alc883_init_verbs },
8864 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8865 .dac_nids = alc883_dac_nids,
8866 .dig_out_nid = ALC883_DIGOUT_NID,
8867 .dig_in_nid = ALC883_DIGIN_NID,
8868 .slave_dig_outs = alc883_slave_dig_outs,
8869 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8870 .channel_mode = alc883_3ST_6ch_intel_modes,
8872 .input_mux = &alc883_3stack_6ch_intel,
8874 [ALC883_6ST_DIG] = {
8875 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8876 .init_verbs = { alc883_init_verbs },
8877 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8878 .dac_nids = alc883_dac_nids,
8879 .dig_out_nid = ALC883_DIGOUT_NID,
8880 .dig_in_nid = ALC883_DIGIN_NID,
8881 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8882 .channel_mode = alc883_sixstack_modes,
8883 .input_mux = &alc883_capture_source,
8885 [ALC883_TARGA_DIG] = {
8886 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8887 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8888 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8889 .dac_nids = alc883_dac_nids,
8890 .dig_out_nid = ALC883_DIGOUT_NID,
8891 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8892 .channel_mode = alc883_3ST_6ch_modes,
8894 .input_mux = &alc883_capture_source,
8895 .unsol_event = alc883_tagra_unsol_event,
8896 .init_hook = alc883_tagra_automute,
8898 [ALC883_TARGA_2ch_DIG] = {
8899 .mixers = { alc883_tagra_2ch_mixer},
8900 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8901 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8902 .dac_nids = alc883_dac_nids,
8903 .adc_nids = alc883_adc_nids_alt,
8904 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8905 .dig_out_nid = ALC883_DIGOUT_NID,
8906 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8907 .channel_mode = alc883_3ST_2ch_modes,
8908 .input_mux = &alc883_capture_source,
8909 .unsol_event = alc883_tagra_unsol_event,
8910 .init_hook = alc883_tagra_automute,
8913 .mixers = { alc883_base_mixer },
8914 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8915 * and the headphone jack. Turn this on and rely on the
8916 * standard mute methods whenever the user wants to turn
8917 * these outputs off.
8919 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8920 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8921 .dac_nids = alc883_dac_nids,
8922 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8923 .channel_mode = alc883_3ST_2ch_modes,
8924 .input_mux = &alc883_capture_source,
8926 [ALC883_ACER_ASPIRE] = {
8927 .mixers = { alc883_acer_aspire_mixer },
8928 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8929 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8930 .dac_nids = alc883_dac_nids,
8931 .dig_out_nid = ALC883_DIGOUT_NID,
8932 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8933 .channel_mode = alc883_3ST_2ch_modes,
8934 .input_mux = &alc883_capture_source,
8935 .unsol_event = alc883_acer_aspire_unsol_event,
8936 .init_hook = alc883_acer_aspire_automute,
8938 [ALC888_ACER_ASPIRE_4930G] = {
8939 .mixers = { alc888_base_mixer,
8940 alc883_chmode_mixer },
8941 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8942 alc888_acer_aspire_4930g_verbs },
8943 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8944 .dac_nids = alc883_dac_nids,
8945 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8946 .adc_nids = alc883_adc_nids_rev,
8947 .capsrc_nids = alc883_capsrc_nids_rev,
8948 .dig_out_nid = ALC883_DIGOUT_NID,
8949 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8950 .channel_mode = alc883_3ST_6ch_modes,
8953 ARRAY_SIZE(alc888_2_capture_sources),
8954 .input_mux = alc888_2_capture_sources,
8955 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8956 .init_hook = alc888_acer_aspire_4930g_automute,
8959 .mixers = { alc883_fivestack_mixer,
8960 alc883_chmode_mixer },
8961 .init_verbs = { alc883_init_verbs,
8962 alc883_medion_eapd_verbs },
8963 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8964 .dac_nids = alc883_dac_nids,
8965 .adc_nids = alc883_adc_nids_alt,
8966 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8967 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8968 .channel_mode = alc883_sixstack_modes,
8969 .input_mux = &alc883_capture_source,
8971 [ALC883_MEDION_MD2] = {
8972 .mixers = { alc883_medion_md2_mixer},
8973 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8974 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8975 .dac_nids = alc883_dac_nids,
8976 .dig_out_nid = ALC883_DIGOUT_NID,
8977 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8978 .channel_mode = alc883_3ST_2ch_modes,
8979 .input_mux = &alc883_capture_source,
8980 .unsol_event = alc883_medion_md2_unsol_event,
8981 .init_hook = alc883_medion_md2_automute,
8983 [ALC883_LAPTOP_EAPD] = {
8984 .mixers = { alc883_base_mixer },
8985 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8986 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8987 .dac_nids = alc883_dac_nids,
8988 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8989 .channel_mode = alc883_3ST_2ch_modes,
8990 .input_mux = &alc883_capture_source,
8992 [ALC883_CLEVO_M720] = {
8993 .mixers = { alc883_clevo_m720_mixer },
8994 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8995 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8996 .dac_nids = alc883_dac_nids,
8997 .dig_out_nid = ALC883_DIGOUT_NID,
8998 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8999 .channel_mode = alc883_3ST_2ch_modes,
9000 .input_mux = &alc883_capture_source,
9001 .unsol_event = alc883_clevo_m720_unsol_event,
9002 .init_hook = alc883_clevo_m720_automute,
9004 [ALC883_LENOVO_101E_2ch] = {
9005 .mixers = { alc883_lenovo_101e_2ch_mixer},
9006 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9007 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9008 .dac_nids = alc883_dac_nids,
9009 .adc_nids = alc883_adc_nids_alt,
9010 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9011 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9012 .channel_mode = alc883_3ST_2ch_modes,
9013 .input_mux = &alc883_lenovo_101e_capture_source,
9014 .unsol_event = alc883_lenovo_101e_unsol_event,
9015 .init_hook = alc883_lenovo_101e_all_automute,
9017 [ALC883_LENOVO_NB0763] = {
9018 .mixers = { alc883_lenovo_nb0763_mixer },
9019 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9020 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9021 .dac_nids = alc883_dac_nids,
9022 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9023 .channel_mode = alc883_3ST_2ch_modes,
9025 .input_mux = &alc883_lenovo_nb0763_capture_source,
9026 .unsol_event = alc883_medion_md2_unsol_event,
9027 .init_hook = alc883_medion_md2_automute,
9029 [ALC888_LENOVO_MS7195_DIG] = {
9030 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9031 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9032 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9033 .dac_nids = alc883_dac_nids,
9034 .dig_out_nid = ALC883_DIGOUT_NID,
9035 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9036 .channel_mode = alc883_3ST_6ch_modes,
9038 .input_mux = &alc883_capture_source,
9039 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9040 .init_hook = alc888_lenovo_ms7195_front_automute,
9042 [ALC883_HAIER_W66] = {
9043 .mixers = { alc883_tagra_2ch_mixer},
9044 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9045 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9046 .dac_nids = alc883_dac_nids,
9047 .dig_out_nid = ALC883_DIGOUT_NID,
9048 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9049 .channel_mode = alc883_3ST_2ch_modes,
9050 .input_mux = &alc883_capture_source,
9051 .unsol_event = alc883_haier_w66_unsol_event,
9052 .init_hook = alc883_haier_w66_automute,
9055 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9056 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9057 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9058 .dac_nids = alc883_dac_nids,
9059 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9060 .channel_mode = alc888_3st_hp_modes,
9062 .input_mux = &alc883_capture_source,
9063 .unsol_event = alc888_3st_hp_unsol_event,
9064 .init_hook = alc888_3st_hp_front_automute,
9066 [ALC888_6ST_DELL] = {
9067 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9068 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9069 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9070 .dac_nids = alc883_dac_nids,
9071 .dig_out_nid = ALC883_DIGOUT_NID,
9072 .dig_in_nid = ALC883_DIGIN_NID,
9073 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9074 .channel_mode = alc883_sixstack_modes,
9075 .input_mux = &alc883_capture_source,
9076 .unsol_event = alc888_6st_dell_unsol_event,
9077 .init_hook = alc888_6st_dell_front_automute,
9080 .mixers = { alc883_mitac_mixer },
9081 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9082 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9083 .dac_nids = alc883_dac_nids,
9084 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9085 .channel_mode = alc883_3ST_2ch_modes,
9086 .input_mux = &alc883_capture_source,
9087 .unsol_event = alc883_mitac_unsol_event,
9088 .init_hook = alc883_mitac_automute,
9090 [ALC883_FUJITSU_PI2515] = {
9091 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9092 .init_verbs = { alc883_init_verbs,
9093 alc883_2ch_fujitsu_pi2515_verbs},
9094 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9095 .dac_nids = alc883_dac_nids,
9096 .dig_out_nid = ALC883_DIGOUT_NID,
9097 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9098 .channel_mode = alc883_3ST_2ch_modes,
9099 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9100 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
9101 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
9103 [ALC888_FUJITSU_XA3530] = {
9104 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9105 .init_verbs = { alc883_init_verbs,
9106 alc888_fujitsu_xa3530_verbs },
9107 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9108 .dac_nids = alc883_dac_nids,
9109 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9110 .adc_nids = alc883_adc_nids_rev,
9111 .capsrc_nids = alc883_capsrc_nids_rev,
9112 .dig_out_nid = ALC883_DIGOUT_NID,
9113 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9114 .channel_mode = alc888_4ST_8ch_intel_modes,
9116 ARRAY_SIZE(alc888_2_capture_sources),
9117 .input_mux = alc888_2_capture_sources,
9118 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
9119 .init_hook = alc888_fujitsu_xa3530_automute,
9121 [ALC888_LENOVO_SKY] = {
9122 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9123 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9124 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9125 .dac_nids = alc883_dac_nids,
9126 .dig_out_nid = ALC883_DIGOUT_NID,
9127 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9128 .channel_mode = alc883_sixstack_modes,
9130 .input_mux = &alc883_lenovo_sky_capture_source,
9131 .unsol_event = alc883_lenovo_sky_unsol_event,
9132 .init_hook = alc888_lenovo_sky_front_automute,
9134 [ALC888_ASUS_M90V] = {
9135 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9136 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9137 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9138 .dac_nids = alc883_dac_nids,
9139 .dig_out_nid = ALC883_DIGOUT_NID,
9140 .dig_in_nid = ALC883_DIGIN_NID,
9141 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9142 .channel_mode = alc883_3ST_6ch_modes,
9144 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9145 .unsol_event = alc883_mode2_unsol_event,
9146 .init_hook = alc883_mode2_inithook,
9148 [ALC888_ASUS_EEE1601] = {
9149 .mixers = { alc883_asus_eee1601_mixer },
9150 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9151 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9152 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9153 .dac_nids = alc883_dac_nids,
9154 .dig_out_nid = ALC883_DIGOUT_NID,
9155 .dig_in_nid = ALC883_DIGIN_NID,
9156 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9157 .channel_mode = alc883_3ST_2ch_modes,
9159 .input_mux = &alc883_asus_eee1601_capture_source,
9160 .unsol_event = alc883_eee1601_unsol_event,
9161 .init_hook = alc883_eee1601_inithook,
9163 [ALC1200_ASUS_P5Q] = {
9164 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9165 .init_verbs = { alc883_init_verbs },
9166 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9167 .dac_nids = alc883_dac_nids,
9168 .dig_out_nid = ALC1200_DIGOUT_NID,
9169 .dig_in_nid = ALC883_DIGIN_NID,
9170 .slave_dig_outs = alc1200_slave_dig_outs,
9171 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9172 .channel_mode = alc883_sixstack_modes,
9173 .input_mux = &alc883_capture_source,
9179 * BIOS auto configuration
9181 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9182 hda_nid_t nid, int pin_type,
9186 struct alc_spec *spec = codec->spec;
9189 alc_set_pin_output(codec, nid, pin_type);
9190 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9193 idx = spec->multiout.dac_nids[dac_idx] - 2;
9194 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9198 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9200 struct alc_spec *spec = codec->spec;
9203 for (i = 0; i <= HDA_SIDE; i++) {
9204 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9205 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9207 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9212 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9214 struct alc_spec *spec = codec->spec;
9217 pin = spec->autocfg.hp_pins[0];
9218 if (pin) /* connect to front */
9220 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9221 pin = spec->autocfg.speaker_pins[0];
9223 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9226 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9227 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9229 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9231 struct alc_spec *spec = codec->spec;
9234 for (i = 0; i < AUTO_PIN_LAST; i++) {
9235 hda_nid_t nid = spec->autocfg.input_pins[i];
9236 if (alc883_is_input_pin(nid)) {
9237 alc_set_input_pin(codec, nid, i);
9238 if (nid != ALC883_PIN_CD_NID &&
9239 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9240 snd_hda_codec_write(codec, nid, 0,
9241 AC_VERB_SET_AMP_GAIN_MUTE,
9247 #define alc883_auto_init_input_src alc882_auto_init_input_src
9249 /* almost identical with ALC880 parser... */
9250 static int alc883_parse_auto_config(struct hda_codec *codec)
9252 struct alc_spec *spec = codec->spec;
9253 int err = alc880_parse_auto_config(codec);
9254 struct auto_pin_cfg *cfg = &spec->autocfg;
9260 return 0; /* no config found */
9262 err = alc_auto_add_mic_boost(codec);
9266 /* hack - override the init verbs */
9267 spec->init_verbs[0] = alc883_auto_init_verbs;
9269 /* setup input_mux for ALC889 */
9270 if (codec->vendor_id == 0x10ec0889) {
9271 /* digital-mic input pin is excluded in alc880_auto_create..()
9272 * because it's under 0x18
9274 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9275 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9276 struct hda_input_mux *imux = &spec->private_imux[0];
9277 for (i = 1; i < 3; i++)
9278 memcpy(&spec->private_imux[i],
9279 &spec->private_imux[0],
9280 sizeof(spec->private_imux[0]));
9281 imux->items[imux->num_items].label = "Int DMic";
9282 imux->items[imux->num_items].index = 0x0b;
9284 spec->num_mux_defs = 3;
9285 spec->input_mux = spec->private_imux;
9289 return 1; /* config found */
9292 /* additional initialization for auto-configuration model */
9293 static void alc883_auto_init(struct hda_codec *codec)
9295 struct alc_spec *spec = codec->spec;
9296 alc883_auto_init_multi_out(codec);
9297 alc883_auto_init_hp_out(codec);
9298 alc883_auto_init_analog_input(codec);
9299 alc883_auto_init_input_src(codec);
9300 if (spec->unsol_event)
9301 alc_inithook(codec);
9304 static int patch_alc883(struct hda_codec *codec)
9306 struct alc_spec *spec;
9307 int err, board_config;
9309 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9315 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9317 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9320 if (board_config < 0) {
9321 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9322 "trying auto-probe from BIOS...\n");
9323 board_config = ALC883_AUTO;
9326 if (board_config == ALC883_AUTO) {
9327 /* automatic parse from the BIOS config */
9328 err = alc883_parse_auto_config(codec);
9334 "hda_codec: Cannot set up configuration "
9335 "from BIOS. Using base mode...\n");
9336 board_config = ALC883_3ST_2ch_DIG;
9340 err = snd_hda_attach_beep_device(codec, 0x1);
9346 if (board_config != ALC883_AUTO)
9347 setup_preset(spec, &alc883_presets[board_config]);
9349 switch (codec->vendor_id) {
9351 if (codec->revision_id == 0x100101) {
9352 spec->stream_name_analog = "ALC1200 Analog";
9353 spec->stream_name_digital = "ALC1200 Digital";
9355 spec->stream_name_analog = "ALC888 Analog";
9356 spec->stream_name_digital = "ALC888 Digital";
9358 if (!spec->num_adc_nids) {
9359 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9360 spec->adc_nids = alc883_adc_nids;
9362 if (!spec->capsrc_nids)
9363 spec->capsrc_nids = alc883_capsrc_nids;
9364 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9365 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9368 spec->stream_name_analog = "ALC889 Analog";
9369 spec->stream_name_digital = "ALC889 Digital";
9370 if (!spec->num_adc_nids) {
9371 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9372 spec->adc_nids = alc889_adc_nids;
9374 if (!spec->capsrc_nids)
9375 spec->capsrc_nids = alc889_capsrc_nids;
9376 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9380 spec->stream_name_analog = "ALC883 Analog";
9381 spec->stream_name_digital = "ALC883 Digital";
9382 if (!spec->num_adc_nids) {
9383 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9384 spec->adc_nids = alc883_adc_nids;
9386 if (!spec->capsrc_nids)
9387 spec->capsrc_nids = alc883_capsrc_nids;
9388 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9392 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9393 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9394 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9396 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9397 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9399 if (!spec->cap_mixer)
9400 set_capture_mixer(spec);
9401 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9403 spec->vmaster_nid = 0x0c;
9405 codec->patch_ops = alc_patch_ops;
9406 if (board_config == ALC883_AUTO)
9407 spec->init_hook = alc883_auto_init;
9409 #ifdef CONFIG_SND_HDA_POWER_SAVE
9410 if (!spec->loopback.amplist)
9411 spec->loopback.amplist = alc883_loopbacks;
9413 codec->proc_widget_hook = print_realtek_coef;
9422 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9423 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9425 #define alc262_dac_nids alc260_dac_nids
9426 #define alc262_adc_nids alc882_adc_nids
9427 #define alc262_adc_nids_alt alc882_adc_nids_alt
9428 #define alc262_capsrc_nids alc882_capsrc_nids
9429 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9431 #define alc262_modes alc260_modes
9432 #define alc262_capture_source alc882_capture_source
9434 static hda_nid_t alc262_dmic_adc_nids[1] = {
9439 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9441 static struct snd_kcontrol_new alc262_base_mixer[] = {
9442 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9443 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9444 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9445 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9446 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9447 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9448 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9449 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9450 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9451 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9452 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9453 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9454 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9455 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9456 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9457 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9461 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9462 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9463 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9466 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9470 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9471 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9472 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9473 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9474 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9479 /* update HP, line and mono-out pins according to the master switch */
9480 static void alc262_hp_master_update(struct hda_codec *codec)
9482 struct alc_spec *spec = codec->spec;
9483 int val = spec->master_sw;
9486 snd_hda_codec_write_cache(codec, 0x1b, 0,
9487 AC_VERB_SET_PIN_WIDGET_CONTROL,
9489 snd_hda_codec_write_cache(codec, 0x15, 0,
9490 AC_VERB_SET_PIN_WIDGET_CONTROL,
9492 /* mono (speaker) depending on the HP jack sense */
9493 val = val && !spec->jack_present;
9494 snd_hda_codec_write_cache(codec, 0x16, 0,
9495 AC_VERB_SET_PIN_WIDGET_CONTROL,
9499 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9501 struct alc_spec *spec = codec->spec;
9502 unsigned int presence;
9503 presence = snd_hda_codec_read(codec, 0x1b, 0,
9504 AC_VERB_GET_PIN_SENSE, 0);
9505 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9506 alc262_hp_master_update(codec);
9509 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9511 if ((res >> 26) != ALC880_HP_EVENT)
9513 alc262_hp_bpc_automute(codec);
9516 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9518 struct alc_spec *spec = codec->spec;
9519 unsigned int presence;
9520 presence = snd_hda_codec_read(codec, 0x15, 0,
9521 AC_VERB_GET_PIN_SENSE, 0);
9522 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9523 alc262_hp_master_update(codec);
9526 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9529 if ((res >> 26) != ALC880_HP_EVENT)
9531 alc262_hp_wildwest_automute(codec);
9534 static int alc262_hp_master_sw_get(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 *ucontrol->value.integer.value = spec->master_sw;
9543 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9544 struct snd_ctl_elem_value *ucontrol)
9546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9547 struct alc_spec *spec = codec->spec;
9548 int val = !!*ucontrol->value.integer.value;
9550 if (val == spec->master_sw)
9552 spec->master_sw = val;
9553 alc262_hp_master_update(codec);
9557 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9560 .name = "Master Playback Switch",
9561 .info = snd_ctl_boolean_mono_info,
9562 .get = alc262_hp_master_sw_get,
9563 .put = alc262_hp_master_sw_put,
9565 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9566 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9567 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9568 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9570 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9572 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9574 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9575 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9576 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9577 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9578 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9579 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9580 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9581 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9582 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9583 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9587 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9589 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9590 .name = "Master Playback Switch",
9591 .info = snd_ctl_boolean_mono_info,
9592 .get = alc262_hp_master_sw_get,
9593 .put = alc262_hp_master_sw_put,
9595 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9596 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9597 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9599 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9601 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9603 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9605 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9608 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9609 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9613 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9614 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9615 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9616 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9620 /* mute/unmute internal speaker according to the hp jack and mute state */
9621 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9623 struct alc_spec *spec = codec->spec;
9625 if (force || !spec->sense_updated) {
9626 unsigned int present;
9627 present = snd_hda_codec_read(codec, 0x15, 0,
9628 AC_VERB_GET_PIN_SENSE, 0);
9629 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9630 spec->sense_updated = 1;
9632 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9633 spec->jack_present ? HDA_AMP_MUTE : 0);
9636 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9639 if ((res >> 26) != ALC880_HP_EVENT)
9641 alc262_hp_t5735_automute(codec, 1);
9644 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9646 alc262_hp_t5735_automute(codec, 1);
9649 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9650 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9651 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9652 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9656 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9660 static struct hda_verb alc262_hp_t5735_verbs[] = {
9661 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9662 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9664 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9668 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9669 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9670 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9671 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9672 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9673 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9674 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9678 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9679 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9680 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9681 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9682 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9683 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9684 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9685 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9686 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9687 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9692 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9699 /* bind hp and internal speaker mute (with plug check) */
9700 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9701 struct snd_ctl_elem_value *ucontrol)
9703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9704 long *valp = ucontrol->value.integer.value;
9707 /* change hp mute */
9708 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9710 valp[0] ? 0 : HDA_AMP_MUTE);
9711 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9713 valp[1] ? 0 : HDA_AMP_MUTE);
9715 /* change speaker according to HP jack state */
9716 struct alc_spec *spec = codec->spec;
9718 if (spec->jack_present)
9719 mute = HDA_AMP_MUTE;
9721 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9723 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9724 HDA_AMP_MUTE, mute);
9729 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9730 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9733 .name = "Master Playback Switch",
9734 .info = snd_hda_mixer_amp_switch_info,
9735 .get = snd_hda_mixer_amp_switch_get,
9736 .put = alc262_sony_master_sw_put,
9737 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9740 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9741 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9742 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9746 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9747 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9748 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9749 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9750 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9751 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9752 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9753 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9757 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9758 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9759 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9760 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9761 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9762 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9763 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9766 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9767 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9768 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9769 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9773 static struct hda_verb alc262_tyan_verbs[] = {
9774 /* Headphone automute */
9775 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9776 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9777 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9779 /* P11 AUX_IN, white 4-pin connector */
9780 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9781 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9782 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9783 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9788 /* unsolicited event for HP jack sensing */
9789 static void alc262_tyan_automute(struct hda_codec *codec)
9792 unsigned int present;
9794 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9795 present = snd_hda_codec_read(codec, 0x1b, 0,
9796 AC_VERB_GET_PIN_SENSE, 0);
9797 present = (present & 0x80000000) != 0;
9799 /* mute line output on ATX panel */
9800 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9801 HDA_AMP_MUTE, HDA_AMP_MUTE);
9803 /* unmute line output if necessary */
9804 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9805 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9806 HDA_AMP_MUTE, mute);
9810 static void alc262_tyan_unsol_event(struct hda_codec *codec,
9813 if ((res >> 26) != ALC880_HP_EVENT)
9815 alc262_tyan_automute(codec);
9818 #define alc262_capture_mixer alc882_capture_mixer
9819 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9822 * generic initialization of ADC, input mixers and output mixers
9824 static struct hda_verb alc262_init_verbs[] = {
9826 * Unmute ADC0-2 and set the default input to mic-in
9828 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9830 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9831 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9832 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9833 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9835 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9837 * Note: PASD motherboards uses the Line In 2 as the input for
9838 * front panel mic (mic 2)
9840 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9843 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9844 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9845 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9848 * Set up output mixers (0x0c - 0x0e)
9850 /* set vol=0 to output mixers */
9851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9852 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9853 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9854 /* set up input amps for analog loopback */
9855 /* Amp Indices: DAC = 0, mixer = 1 */
9856 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9857 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9858 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9859 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9860 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9861 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9863 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9865 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9866 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9867 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9868 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9872 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9876 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9877 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9879 /* FIXME: use matrix-type input source selection */
9880 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9881 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9883 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9884 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9885 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9889 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9890 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9894 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9900 static struct hda_verb alc262_eapd_verbs[] = {
9901 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9902 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9906 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9907 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9908 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9912 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9914 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9915 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9917 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9918 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9922 static struct hda_verb alc262_sony_unsol_verbs[] = {
9923 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9924 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9925 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9927 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9928 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9932 static struct hda_input_mux alc262_dmic_capture_source = {
9935 { "Int DMic", 0x9 },
9940 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9941 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9942 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9945 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9949 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9950 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9951 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9952 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9953 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9954 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9955 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9956 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9957 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9961 static void alc262_dmic_automute(struct hda_codec *codec)
9963 unsigned int present;
9965 present = snd_hda_codec_read(codec, 0x18, 0,
9966 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9967 snd_hda_codec_write(codec, 0x22, 0,
9968 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9971 /* toggle speaker-output according to the hp-jack state */
9972 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9974 unsigned int present;
9977 present = snd_hda_codec_read(codec, 0x15, 0,
9978 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9979 bits = present ? 0 : PIN_OUT;
9980 snd_hda_codec_write(codec, 0x14, 0,
9981 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9986 /* unsolicited event for HP jack sensing */
9987 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9990 if ((res >> 26) == ALC880_HP_EVENT)
9991 alc262_toshiba_s06_speaker_automute(codec);
9992 if ((res >> 26) == ALC880_MIC_EVENT)
9993 alc262_dmic_automute(codec);
9997 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9999 alc262_toshiba_s06_speaker_automute(codec);
10000 alc262_dmic_automute(codec);
10003 /* mute/unmute internal speaker according to the hp jack and mute state */
10004 static void alc262_hippo_automute(struct hda_codec *codec)
10006 struct alc_spec *spec = codec->spec;
10008 unsigned int present;
10010 /* need to execute and sync at first */
10011 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10012 present = snd_hda_codec_read(codec, 0x15, 0,
10013 AC_VERB_GET_PIN_SENSE, 0);
10014 spec->jack_present = (present & 0x80000000) != 0;
10015 if (spec->jack_present) {
10016 /* mute internal speaker */
10017 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10018 HDA_AMP_MUTE, HDA_AMP_MUTE);
10020 /* unmute internal speaker if necessary */
10021 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10022 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10023 HDA_AMP_MUTE, mute);
10027 /* unsolicited event for HP jack sensing */
10028 static void alc262_hippo_unsol_event(struct hda_codec *codec,
10031 if ((res >> 26) != ALC880_HP_EVENT)
10033 alc262_hippo_automute(codec);
10036 static void alc262_hippo1_automute(struct hda_codec *codec)
10039 unsigned int present;
10041 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10042 present = snd_hda_codec_read(codec, 0x1b, 0,
10043 AC_VERB_GET_PIN_SENSE, 0);
10044 present = (present & 0x80000000) != 0;
10046 /* mute internal speaker */
10047 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10048 HDA_AMP_MUTE, HDA_AMP_MUTE);
10050 /* unmute internal speaker if necessary */
10051 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10052 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10053 HDA_AMP_MUTE, mute);
10057 /* unsolicited event for HP jack sensing */
10058 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
10061 if ((res >> 26) != ALC880_HP_EVENT)
10063 alc262_hippo1_automute(codec);
10069 * 0x16 = internal speaker
10070 * 0x18 = external mic
10073 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10074 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10075 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10077 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10079 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10081 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10086 static struct hda_verb alc262_nec_verbs[] = {
10087 /* Unmute Speaker */
10088 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10091 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10092 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10094 /* External mic to headphone */
10095 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10096 /* External mic to speaker */
10097 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10103 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10104 * 0x1b = port replicator headphone out
10107 #define ALC_HP_EVENT 0x37
10109 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10110 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10111 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10112 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10113 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10117 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10118 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10119 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10123 static struct hda_input_mux alc262_fujitsu_capture_source = {
10127 { "Int Mic", 0x1 },
10132 static struct hda_input_mux alc262_HP_capture_source = {
10136 { "Front Mic", 0x1 },
10143 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10147 { "Front Mic", 0x2 },
10153 /* mute/unmute internal speaker according to the hp jacks and mute state */
10154 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10156 struct alc_spec *spec = codec->spec;
10159 if (force || !spec->sense_updated) {
10160 unsigned int present;
10161 /* need to execute and sync at first */
10162 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10163 /* check laptop HP jack */
10164 present = snd_hda_codec_read(codec, 0x14, 0,
10165 AC_VERB_GET_PIN_SENSE, 0);
10166 /* need to execute and sync at first */
10167 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10168 /* check docking HP jack */
10169 present |= snd_hda_codec_read(codec, 0x1b, 0,
10170 AC_VERB_GET_PIN_SENSE, 0);
10171 if (present & AC_PINSENSE_PRESENCE)
10172 spec->jack_present = 1;
10174 spec->jack_present = 0;
10175 spec->sense_updated = 1;
10177 /* unmute internal speaker only if both HPs are unplugged and
10178 * master switch is on
10180 if (spec->jack_present)
10181 mute = HDA_AMP_MUTE;
10183 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10184 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10185 HDA_AMP_MUTE, mute);
10188 /* unsolicited event for HP jack sensing */
10189 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10192 if ((res >> 26) != ALC_HP_EVENT)
10194 alc262_fujitsu_automute(codec, 1);
10197 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10199 alc262_fujitsu_automute(codec, 1);
10202 /* bind volumes of both NID 0x0c and 0x0d */
10203 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10204 .ops = &snd_hda_bind_vol,
10206 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10207 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10212 /* mute/unmute internal speaker according to the hp jack and mute state */
10213 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10215 struct alc_spec *spec = codec->spec;
10218 if (force || !spec->sense_updated) {
10219 unsigned int present_int_hp;
10220 /* need to execute and sync at first */
10221 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10222 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10223 AC_VERB_GET_PIN_SENSE, 0);
10224 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10225 spec->sense_updated = 1;
10227 if (spec->jack_present) {
10228 /* mute internal speaker */
10229 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10230 HDA_AMP_MUTE, HDA_AMP_MUTE);
10231 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10232 HDA_AMP_MUTE, HDA_AMP_MUTE);
10234 /* unmute internal speaker if necessary */
10235 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10236 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10237 HDA_AMP_MUTE, mute);
10238 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10239 HDA_AMP_MUTE, mute);
10243 /* unsolicited event for HP jack sensing */
10244 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10247 if ((res >> 26) != ALC_HP_EVENT)
10249 alc262_lenovo_3000_automute(codec, 1);
10252 /* bind hp and internal speaker mute (with plug check) */
10253 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10254 struct snd_ctl_elem_value *ucontrol)
10256 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10257 long *valp = ucontrol->value.integer.value;
10260 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10262 valp ? 0 : HDA_AMP_MUTE);
10263 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10265 valp ? 0 : HDA_AMP_MUTE);
10268 alc262_fujitsu_automute(codec, 0);
10272 static struct snd_kcontrol_new alc262_fujitsu_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_fujitsu_master_sw_put,
10280 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 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 /* bind hp and internal speaker mute (with plug check) */
10294 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10295 struct snd_ctl_elem_value *ucontrol)
10297 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10298 long *valp = ucontrol->value.integer.value;
10301 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10303 valp ? 0 : HDA_AMP_MUTE);
10306 alc262_lenovo_3000_automute(codec, 0);
10310 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10311 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10314 .name = "Master Playback Switch",
10315 .info = snd_hda_mixer_amp_switch_info,
10316 .get = snd_hda_mixer_amp_switch_get,
10317 .put = alc262_lenovo_3000_master_sw_put,
10318 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10320 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10321 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10325 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10326 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10327 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10331 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10332 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10334 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10335 .name = "Master Playback Switch",
10336 .info = snd_hda_mixer_amp_switch_info,
10337 .get = snd_hda_mixer_amp_switch_get,
10338 .put = alc262_sony_master_sw_put,
10339 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10342 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10343 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10344 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10345 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10346 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10350 /* additional init verbs for Benq laptops */
10351 static struct hda_verb alc262_EAPD_verbs[] = {
10352 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10353 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10357 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10358 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10361 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10362 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10366 /* Samsung Q1 Ultra Vista model setup */
10367 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10368 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10369 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10372 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10373 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10377 static struct hda_verb alc262_ultra_verbs[] = {
10379 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10380 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10381 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10385 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10386 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10388 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10389 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10390 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10391 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10392 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10394 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10395 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10396 /* ADC, choose mic */
10397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10398 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10399 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10400 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10401 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10406 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10410 /* mute/unmute internal speaker according to the hp jack and mute state */
10411 static void alc262_ultra_automute(struct hda_codec *codec)
10413 struct alc_spec *spec = codec->spec;
10417 /* auto-mute only when HP is used as HP */
10418 if (!spec->cur_mux[0]) {
10419 unsigned int present;
10420 /* need to execute and sync at first */
10421 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10422 present = snd_hda_codec_read(codec, 0x15, 0,
10423 AC_VERB_GET_PIN_SENSE, 0);
10424 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10425 if (spec->jack_present)
10426 mute = HDA_AMP_MUTE;
10428 /* mute/unmute internal speaker */
10429 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10430 HDA_AMP_MUTE, mute);
10431 /* mute/unmute HP */
10432 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10433 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10436 /* unsolicited event for HP jack sensing */
10437 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10440 if ((res >> 26) != ALC880_HP_EVENT)
10442 alc262_ultra_automute(codec);
10445 static struct hda_input_mux alc262_ultra_capture_source = {
10449 { "Headphone", 0x7 },
10453 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10454 struct snd_ctl_elem_value *ucontrol)
10456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10457 struct alc_spec *spec = codec->spec;
10460 ret = alc_mux_enum_put(kcontrol, ucontrol);
10463 /* reprogram the HP pin as mic or HP according to the input source */
10464 snd_hda_codec_write_cache(codec, 0x15, 0,
10465 AC_VERB_SET_PIN_WIDGET_CONTROL,
10466 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10467 alc262_ultra_automute(codec); /* mute/unmute HP */
10471 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10472 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10473 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10475 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10476 .name = "Capture Source",
10477 .info = alc_mux_enum_info,
10478 .get = alc_mux_enum_get,
10479 .put = alc262_ultra_mux_enum_put,
10484 /* add playback controls from the parsed DAC table */
10485 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10486 const struct auto_pin_cfg *cfg)
10491 spec->multiout.num_dacs = 1; /* only use one dac */
10492 spec->multiout.dac_nids = spec->private_dac_nids;
10493 spec->multiout.dac_nids[0] = 2;
10495 nid = cfg->line_out_pins[0];
10497 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10498 "Front Playback Volume",
10499 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10502 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10503 "Front Playback Switch",
10504 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10509 nid = cfg->speaker_pins[0];
10512 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10513 "Speaker Playback Volume",
10514 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10518 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10519 "Speaker Playback Switch",
10520 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10525 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10526 "Speaker Playback Switch",
10527 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10533 nid = cfg->hp_pins[0];
10535 /* spec->multiout.hp_nid = 2; */
10537 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10538 "Headphone Playback Volume",
10539 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10543 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10544 "Headphone Playback Switch",
10545 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10550 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10551 "Headphone Playback Switch",
10552 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10561 /* identical with ALC880 */
10562 #define alc262_auto_create_analog_input_ctls \
10563 alc880_auto_create_analog_input_ctls
10566 * generic initialization of ADC, input mixers and output mixers
10568 static struct hda_verb alc262_volume_init_verbs[] = {
10570 * Unmute ADC0-2 and set the default input to mic-in
10572 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10574 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10575 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10576 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10577 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10579 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10581 * Note: PASD motherboards uses the Line In 2 as the input for
10582 * front panel mic (mic 2)
10584 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10585 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10586 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10587 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10588 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10589 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10592 * Set up output mixers (0x0c - 0x0f)
10594 /* set vol=0 to output mixers */
10595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10596 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10597 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10599 /* set up input amps for analog loopback */
10600 /* Amp Indices: DAC = 0, mixer = 1 */
10601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10603 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10604 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10605 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10606 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10608 /* FIXME: use matrix-type input source selection */
10609 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10610 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10612 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10613 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10614 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10617 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10618 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10619 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10622 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10624 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10629 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10631 * Unmute ADC0-2 and set the default input to mic-in
10633 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10634 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10635 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10636 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10637 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10638 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10640 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10642 * Note: PASD motherboards uses the Line In 2 as the input for
10643 * front panel mic (mic 2)
10645 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10651 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10652 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10655 * Set up output mixers (0x0c - 0x0e)
10657 /* set vol=0 to output mixers */
10658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10659 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10660 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10662 /* set up input amps for analog loopback */
10663 /* Amp Indices: DAC = 0, mixer = 1 */
10664 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10666 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10667 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10671 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10672 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10675 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10678 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10679 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10681 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10682 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10683 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10684 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10685 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10687 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10688 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10689 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10690 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10691 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10692 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10695 /* FIXME: use matrix-type input source selection */
10696 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10697 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10698 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10699 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10700 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10701 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10703 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10704 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10705 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10706 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10708 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10709 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10713 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10718 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10720 * Unmute ADC0-2 and set the default input to mic-in
10722 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10723 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10724 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10725 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10726 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10727 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10729 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10731 * Note: PASD motherboards uses the Line In 2 as the input for front
10732 * panel mic (mic 2)
10734 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10735 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10736 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10737 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10738 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10739 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10740 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10742 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10744 * Set up output mixers (0x0c - 0x0e)
10746 /* set vol=0 to output mixers */
10747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10751 /* set up input amps for analog loopback */
10752 /* Amp Indices: DAC = 0, mixer = 1 */
10753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10763 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10765 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10766 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10767 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10769 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10772 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10773 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10775 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10777 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10778 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10779 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10780 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10782 /* FIXME: use matrix-type input source selection */
10783 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10784 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10785 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10786 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10787 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10788 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10789 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10790 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10791 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10793 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10794 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10795 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10796 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10797 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10798 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10799 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10801 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10802 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10803 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10804 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10805 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10806 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10807 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10809 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10814 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10816 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10817 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10818 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10821 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10823 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10826 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10827 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10832 #ifdef CONFIG_SND_HDA_POWER_SAVE
10833 #define alc262_loopbacks alc880_loopbacks
10836 /* pcm configuration: identiacal with ALC880 */
10837 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10838 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10839 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10840 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10843 * BIOS auto configuration
10845 static int alc262_parse_auto_config(struct hda_codec *codec)
10847 struct alc_spec *spec = codec->spec;
10849 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10851 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10855 if (!spec->autocfg.line_outs) {
10856 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10857 spec->multiout.max_channels = 2;
10858 spec->no_analog = 1;
10861 return 0; /* can't find valid BIOS pin config */
10863 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10866 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10870 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10873 if (spec->autocfg.dig_outs) {
10874 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10875 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10877 if (spec->autocfg.dig_in_pin)
10878 spec->dig_in_nid = ALC262_DIGIN_NID;
10880 if (spec->kctls.list)
10881 add_mixer(spec, spec->kctls.list);
10883 add_verb(spec, alc262_volume_init_verbs);
10884 spec->num_mux_defs = 1;
10885 spec->input_mux = &spec->private_imux[0];
10887 err = alc_auto_add_mic_boost(codec);
10891 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10896 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10897 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10898 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10899 #define alc262_auto_init_input_src alc882_auto_init_input_src
10902 /* init callback for auto-configuration model -- overriding the default init */
10903 static void alc262_auto_init(struct hda_codec *codec)
10905 struct alc_spec *spec = codec->spec;
10906 alc262_auto_init_multi_out(codec);
10907 alc262_auto_init_hp_out(codec);
10908 alc262_auto_init_analog_input(codec);
10909 alc262_auto_init_input_src(codec);
10910 if (spec->unsol_event)
10911 alc_inithook(codec);
10915 * configuration and preset
10917 static const char *alc262_models[ALC262_MODEL_LAST] = {
10918 [ALC262_BASIC] = "basic",
10919 [ALC262_HIPPO] = "hippo",
10920 [ALC262_HIPPO_1] = "hippo_1",
10921 [ALC262_FUJITSU] = "fujitsu",
10922 [ALC262_HP_BPC] = "hp-bpc",
10923 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10924 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10925 [ALC262_HP_RP5700] = "hp-rp5700",
10926 [ALC262_BENQ_ED8] = "benq",
10927 [ALC262_BENQ_T31] = "benq-t31",
10928 [ALC262_SONY_ASSAMD] = "sony-assamd",
10929 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10930 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10931 [ALC262_ULTRA] = "ultra",
10932 [ALC262_LENOVO_3000] = "lenovo-3000",
10933 [ALC262_NEC] = "nec",
10934 [ALC262_TYAN] = "tyan",
10935 [ALC262_AUTO] = "auto",
10938 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10939 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10940 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10941 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10943 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10945 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10947 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10948 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10949 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10950 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10951 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10952 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10953 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10954 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10955 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10956 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10957 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10958 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10959 ALC262_HP_TC_T5735),
10960 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10961 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10962 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10963 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10964 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10965 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10966 ALC262_SONY_ASSAMD),
10967 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10968 ALC262_TOSHIBA_RX1),
10969 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10970 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10971 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10972 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10973 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10975 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10976 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10977 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10978 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10979 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10983 static struct alc_config_preset alc262_presets[] = {
10985 .mixers = { alc262_base_mixer },
10986 .init_verbs = { alc262_init_verbs },
10987 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10988 .dac_nids = alc262_dac_nids,
10990 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10991 .channel_mode = alc262_modes,
10992 .input_mux = &alc262_capture_source,
10995 .mixers = { alc262_base_mixer },
10996 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10997 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10998 .dac_nids = alc262_dac_nids,
11000 .dig_out_nid = ALC262_DIGOUT_NID,
11001 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11002 .channel_mode = alc262_modes,
11003 .input_mux = &alc262_capture_source,
11004 .unsol_event = alc262_hippo_unsol_event,
11005 .init_hook = alc262_hippo_automute,
11007 [ALC262_HIPPO_1] = {
11008 .mixers = { alc262_hippo1_mixer },
11009 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11010 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11011 .dac_nids = alc262_dac_nids,
11013 .dig_out_nid = ALC262_DIGOUT_NID,
11014 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11015 .channel_mode = alc262_modes,
11016 .input_mux = &alc262_capture_source,
11017 .unsol_event = alc262_hippo1_unsol_event,
11018 .init_hook = alc262_hippo1_automute,
11020 [ALC262_FUJITSU] = {
11021 .mixers = { alc262_fujitsu_mixer },
11022 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11023 alc262_fujitsu_unsol_verbs },
11024 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11025 .dac_nids = alc262_dac_nids,
11027 .dig_out_nid = ALC262_DIGOUT_NID,
11028 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11029 .channel_mode = alc262_modes,
11030 .input_mux = &alc262_fujitsu_capture_source,
11031 .unsol_event = alc262_fujitsu_unsol_event,
11032 .init_hook = alc262_fujitsu_init_hook,
11034 [ALC262_HP_BPC] = {
11035 .mixers = { alc262_HP_BPC_mixer },
11036 .init_verbs = { alc262_HP_BPC_init_verbs },
11037 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11038 .dac_nids = alc262_dac_nids,
11040 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11041 .channel_mode = alc262_modes,
11042 .input_mux = &alc262_HP_capture_source,
11043 .unsol_event = alc262_hp_bpc_unsol_event,
11044 .init_hook = alc262_hp_bpc_automute,
11046 [ALC262_HP_BPC_D7000_WF] = {
11047 .mixers = { alc262_HP_BPC_WildWest_mixer },
11048 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11049 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11050 .dac_nids = alc262_dac_nids,
11052 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11053 .channel_mode = alc262_modes,
11054 .input_mux = &alc262_HP_D7000_capture_source,
11055 .unsol_event = alc262_hp_wildwest_unsol_event,
11056 .init_hook = alc262_hp_wildwest_automute,
11058 [ALC262_HP_BPC_D7000_WL] = {
11059 .mixers = { alc262_HP_BPC_WildWest_mixer,
11060 alc262_HP_BPC_WildWest_option_mixer },
11061 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11062 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11063 .dac_nids = alc262_dac_nids,
11065 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11066 .channel_mode = alc262_modes,
11067 .input_mux = &alc262_HP_D7000_capture_source,
11068 .unsol_event = alc262_hp_wildwest_unsol_event,
11069 .init_hook = alc262_hp_wildwest_automute,
11071 [ALC262_HP_TC_T5735] = {
11072 .mixers = { alc262_hp_t5735_mixer },
11073 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11074 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11075 .dac_nids = alc262_dac_nids,
11077 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11078 .channel_mode = alc262_modes,
11079 .input_mux = &alc262_capture_source,
11080 .unsol_event = alc262_hp_t5735_unsol_event,
11081 .init_hook = alc262_hp_t5735_init_hook,
11083 [ALC262_HP_RP5700] = {
11084 .mixers = { alc262_hp_rp5700_mixer },
11085 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11086 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11087 .dac_nids = alc262_dac_nids,
11088 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11089 .channel_mode = alc262_modes,
11090 .input_mux = &alc262_hp_rp5700_capture_source,
11092 [ALC262_BENQ_ED8] = {
11093 .mixers = { alc262_base_mixer },
11094 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11095 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11096 .dac_nids = alc262_dac_nids,
11098 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11099 .channel_mode = alc262_modes,
11100 .input_mux = &alc262_capture_source,
11102 [ALC262_SONY_ASSAMD] = {
11103 .mixers = { alc262_sony_mixer },
11104 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11105 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11106 .dac_nids = alc262_dac_nids,
11108 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11109 .channel_mode = alc262_modes,
11110 .input_mux = &alc262_capture_source,
11111 .unsol_event = alc262_hippo_unsol_event,
11112 .init_hook = alc262_hippo_automute,
11114 [ALC262_BENQ_T31] = {
11115 .mixers = { alc262_benq_t31_mixer },
11116 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11117 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11118 .dac_nids = alc262_dac_nids,
11120 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11121 .channel_mode = alc262_modes,
11122 .input_mux = &alc262_capture_source,
11123 .unsol_event = alc262_hippo_unsol_event,
11124 .init_hook = alc262_hippo_automute,
11127 .mixers = { alc262_ultra_mixer },
11128 .cap_mixer = alc262_ultra_capture_mixer,
11129 .init_verbs = { alc262_ultra_verbs },
11130 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11131 .dac_nids = alc262_dac_nids,
11132 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11133 .channel_mode = alc262_modes,
11134 .input_mux = &alc262_ultra_capture_source,
11135 .adc_nids = alc262_adc_nids, /* ADC0 */
11136 .capsrc_nids = alc262_capsrc_nids,
11137 .num_adc_nids = 1, /* single ADC */
11138 .unsol_event = alc262_ultra_unsol_event,
11139 .init_hook = alc262_ultra_automute,
11141 [ALC262_LENOVO_3000] = {
11142 .mixers = { alc262_lenovo_3000_mixer },
11143 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11144 alc262_lenovo_3000_unsol_verbs },
11145 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11146 .dac_nids = alc262_dac_nids,
11148 .dig_out_nid = ALC262_DIGOUT_NID,
11149 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11150 .channel_mode = alc262_modes,
11151 .input_mux = &alc262_fujitsu_capture_source,
11152 .unsol_event = alc262_lenovo_3000_unsol_event,
11155 .mixers = { alc262_nec_mixer },
11156 .init_verbs = { alc262_nec_verbs },
11157 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11158 .dac_nids = alc262_dac_nids,
11160 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11161 .channel_mode = alc262_modes,
11162 .input_mux = &alc262_capture_source,
11164 [ALC262_TOSHIBA_S06] = {
11165 .mixers = { alc262_toshiba_s06_mixer },
11166 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11167 alc262_eapd_verbs },
11168 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11169 .capsrc_nids = alc262_dmic_capsrc_nids,
11170 .dac_nids = alc262_dac_nids,
11171 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11172 .dig_out_nid = ALC262_DIGOUT_NID,
11173 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11174 .channel_mode = alc262_modes,
11175 .input_mux = &alc262_dmic_capture_source,
11176 .unsol_event = alc262_toshiba_s06_unsol_event,
11177 .init_hook = alc262_toshiba_s06_init_hook,
11179 [ALC262_TOSHIBA_RX1] = {
11180 .mixers = { alc262_toshiba_rx1_mixer },
11181 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11182 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11183 .dac_nids = alc262_dac_nids,
11185 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11186 .channel_mode = alc262_modes,
11187 .input_mux = &alc262_capture_source,
11188 .unsol_event = alc262_hippo_unsol_event,
11189 .init_hook = alc262_hippo_automute,
11192 .mixers = { alc262_tyan_mixer },
11193 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11194 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11195 .dac_nids = alc262_dac_nids,
11197 .dig_out_nid = ALC262_DIGOUT_NID,
11198 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11199 .channel_mode = alc262_modes,
11200 .input_mux = &alc262_capture_source,
11201 .unsol_event = alc262_tyan_unsol_event,
11202 .init_hook = alc262_tyan_automute,
11206 static int patch_alc262(struct hda_codec *codec)
11208 struct alc_spec *spec;
11212 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11216 codec->spec = spec;
11218 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11223 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11224 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11225 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11226 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11230 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11232 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11236 if (board_config < 0) {
11237 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11238 "trying auto-probe from BIOS...\n");
11239 board_config = ALC262_AUTO;
11242 if (board_config == ALC262_AUTO) {
11243 /* automatic parse from the BIOS config */
11244 err = alc262_parse_auto_config(codec);
11250 "hda_codec: Cannot set up configuration "
11251 "from BIOS. Using base mode...\n");
11252 board_config = ALC262_BASIC;
11256 if (!spec->no_analog) {
11257 err = snd_hda_attach_beep_device(codec, 0x1);
11264 if (board_config != ALC262_AUTO)
11265 setup_preset(spec, &alc262_presets[board_config]);
11267 spec->stream_name_analog = "ALC262 Analog";
11268 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11269 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11271 spec->stream_name_digital = "ALC262 Digital";
11272 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11273 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11275 spec->capture_style = CAPT_MIX;
11276 if (!spec->adc_nids && spec->input_mux) {
11277 /* check whether NID 0x07 is valid */
11278 unsigned int wcap = get_wcaps(codec, 0x07);
11281 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11282 if (wcap != AC_WID_AUD_IN) {
11283 spec->adc_nids = alc262_adc_nids_alt;
11284 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11285 spec->capsrc_nids = alc262_capsrc_nids_alt;
11287 spec->adc_nids = alc262_adc_nids;
11288 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11289 spec->capsrc_nids = alc262_capsrc_nids;
11292 if (!spec->cap_mixer && !spec->no_analog)
11293 set_capture_mixer(spec);
11294 if (!spec->no_analog)
11295 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11297 spec->vmaster_nid = 0x0c;
11299 codec->patch_ops = alc_patch_ops;
11300 if (board_config == ALC262_AUTO)
11301 spec->init_hook = alc262_auto_init;
11302 #ifdef CONFIG_SND_HDA_POWER_SAVE
11303 if (!spec->loopback.amplist)
11304 spec->loopback.amplist = alc262_loopbacks;
11306 codec->proc_widget_hook = print_realtek_coef;
11312 * ALC268 channel source setting (2 channel)
11314 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11315 #define alc268_modes alc260_modes
11317 static hda_nid_t alc268_dac_nids[2] = {
11322 static hda_nid_t alc268_adc_nids[2] = {
11327 static hda_nid_t alc268_adc_nids_alt[1] = {
11332 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11334 static struct snd_kcontrol_new alc268_base_mixer[] = {
11335 /* output mixer control */
11336 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11337 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11338 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11339 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11340 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11341 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11342 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11346 /* bind Beep switches of both NID 0x0f and 0x10 */
11347 static struct hda_bind_ctls alc268_bind_beep_sw = {
11348 .ops = &snd_hda_bind_sw,
11350 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11351 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11356 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11357 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11358 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11362 static struct hda_verb alc268_eapd_verbs[] = {
11363 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11364 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11368 /* Toshiba specific */
11369 #define alc268_toshiba_automute alc262_hippo_automute
11371 static struct hda_verb alc268_toshiba_verbs[] = {
11372 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11376 static struct hda_input_mux alc268_acer_lc_capture_source = {
11384 /* Acer specific */
11385 /* bind volumes of both NID 0x02 and 0x03 */
11386 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11387 .ops = &snd_hda_bind_vol,
11389 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11390 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11395 /* mute/unmute internal speaker according to the hp jack and mute state */
11396 static void alc268_acer_automute(struct hda_codec *codec, int force)
11398 struct alc_spec *spec = codec->spec;
11401 if (force || !spec->sense_updated) {
11402 unsigned int present;
11403 present = snd_hda_codec_read(codec, 0x14, 0,
11404 AC_VERB_GET_PIN_SENSE, 0);
11405 spec->jack_present = (present & 0x80000000) != 0;
11406 spec->sense_updated = 1;
11408 if (spec->jack_present)
11409 mute = HDA_AMP_MUTE; /* mute internal speaker */
11410 else /* unmute internal speaker if necessary */
11411 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11412 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11413 HDA_AMP_MUTE, mute);
11417 /* bind hp and internal speaker mute (with plug check) */
11418 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11419 struct snd_ctl_elem_value *ucontrol)
11421 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11422 long *valp = ucontrol->value.integer.value;
11425 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11427 valp[0] ? 0 : HDA_AMP_MUTE);
11428 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11430 valp[1] ? 0 : HDA_AMP_MUTE);
11432 alc268_acer_automute(codec, 0);
11436 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11437 /* output mixer control */
11438 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11440 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11441 .name = "Master Playback Switch",
11442 .info = snd_hda_mixer_amp_switch_info,
11443 .get = snd_hda_mixer_amp_switch_get,
11444 .put = alc268_acer_master_sw_put,
11445 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11447 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11451 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11452 /* output mixer control */
11453 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11456 .name = "Master Playback Switch",
11457 .info = snd_hda_mixer_amp_switch_info,
11458 .get = snd_hda_mixer_amp_switch_get,
11459 .put = alc268_acer_master_sw_put,
11460 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11462 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11463 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11464 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11468 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11469 /* output mixer control */
11470 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11473 .name = "Master Playback Switch",
11474 .info = snd_hda_mixer_amp_switch_info,
11475 .get = snd_hda_mixer_amp_switch_get,
11476 .put = alc268_acer_master_sw_put,
11477 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11479 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11480 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11484 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11485 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11486 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11487 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11488 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11489 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11490 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11494 static struct hda_verb alc268_acer_verbs[] = {
11495 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11496 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11497 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11498 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11500 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11501 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11505 /* unsolicited event for HP jack sensing */
11506 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
11509 if ((res >> 26) != ALC880_HP_EVENT)
11511 alc268_toshiba_automute(codec);
11514 static void alc268_acer_unsol_event(struct hda_codec *codec,
11517 if ((res >> 26) != ALC880_HP_EVENT)
11519 alc268_acer_automute(codec, 1);
11522 static void alc268_acer_init_hook(struct hda_codec *codec)
11524 alc268_acer_automute(codec, 1);
11527 /* toggle speaker-output according to the hp-jack state */
11528 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11530 unsigned int present;
11531 unsigned char bits;
11533 present = snd_hda_codec_read(codec, 0x15, 0,
11534 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11535 bits = present ? AMP_IN_MUTE(0) : 0;
11536 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11537 AMP_IN_MUTE(0), bits);
11538 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11539 AMP_IN_MUTE(0), bits);
11543 static void alc268_acer_mic_automute(struct hda_codec *codec)
11545 unsigned int present;
11547 present = snd_hda_codec_read(codec, 0x18, 0,
11548 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11549 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11550 present ? 0x0 : 0x6);
11553 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11556 if ((res >> 26) == ALC880_HP_EVENT)
11557 alc268_aspire_one_speaker_automute(codec);
11558 if ((res >> 26) == ALC880_MIC_EVENT)
11559 alc268_acer_mic_automute(codec);
11562 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11564 alc268_aspire_one_speaker_automute(codec);
11565 alc268_acer_mic_automute(codec);
11568 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11569 /* output mixer control */
11570 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11571 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11572 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11573 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11574 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11575 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11579 static struct hda_verb alc268_dell_verbs[] = {
11580 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11581 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11582 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11586 /* mute/unmute internal speaker according to the hp jack and mute state */
11587 static void alc268_dell_automute(struct hda_codec *codec)
11589 unsigned int present;
11592 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11593 if (present & 0x80000000)
11594 mute = HDA_AMP_MUTE;
11596 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11597 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11598 HDA_AMP_MUTE, mute);
11601 static void alc268_dell_unsol_event(struct hda_codec *codec,
11604 if ((res >> 26) != ALC880_HP_EVENT)
11606 alc268_dell_automute(codec);
11609 #define alc268_dell_init_hook alc268_dell_automute
11611 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11612 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11613 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11614 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11615 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11616 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11617 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11618 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11619 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11623 static struct hda_verb alc267_quanta_il1_verbs[] = {
11624 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11625 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11629 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11631 unsigned int present;
11633 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11634 & AC_PINSENSE_PRESENCE;
11635 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11636 present ? 0 : PIN_OUT);
11639 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11641 unsigned int present;
11643 present = snd_hda_codec_read(codec, 0x18, 0,
11644 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11645 snd_hda_codec_write(codec, 0x23, 0,
11646 AC_VERB_SET_CONNECT_SEL,
11647 present ? 0x00 : 0x01);
11650 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11652 alc267_quanta_il1_hp_automute(codec);
11653 alc267_quanta_il1_mic_automute(codec);
11656 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11659 switch (res >> 26) {
11660 case ALC880_HP_EVENT:
11661 alc267_quanta_il1_hp_automute(codec);
11663 case ALC880_MIC_EVENT:
11664 alc267_quanta_il1_mic_automute(codec);
11670 * generic initialization of ADC, input mixers and output mixers
11672 static struct hda_verb alc268_base_init_verbs[] = {
11673 /* Unmute DAC0-1 and set vol = 0 */
11674 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11675 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11678 * Set up output mixers (0x0c - 0x0e)
11680 /* set vol=0 to output mixers */
11681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11682 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11687 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11689 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11690 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11691 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11692 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11693 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11694 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11696 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11697 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11698 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11699 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11700 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11702 /* set PCBEEP vol = 0, mute connections */
11703 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11705 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11707 /* Unmute Selector 23h,24h and set the default input to mic-in */
11709 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11710 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11711 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11712 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11718 * generic initialization of ADC, input mixers and output mixers
11720 static struct hda_verb alc268_volume_init_verbs[] = {
11721 /* set output DAC */
11722 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11723 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11725 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11726 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11727 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11728 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11729 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11731 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11732 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11733 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11735 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11736 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11738 /* set PCBEEP vol = 0, mute connections */
11739 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11740 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11741 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11746 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11747 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11748 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11751 /* The multiple "Capture Source" controls confuse alsamixer
11752 * So call somewhat different..
11754 /* .name = "Capture Source", */
11755 .name = "Input Source",
11757 .info = alc_mux_enum_info,
11758 .get = alc_mux_enum_get,
11759 .put = alc_mux_enum_put,
11764 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11765 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11766 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11767 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11768 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11770 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11771 /* The multiple "Capture Source" controls confuse alsamixer
11772 * So call somewhat different..
11774 /* .name = "Capture Source", */
11775 .name = "Input Source",
11777 .info = alc_mux_enum_info,
11778 .get = alc_mux_enum_get,
11779 .put = alc_mux_enum_put,
11784 static struct hda_input_mux alc268_capture_source = {
11788 { "Front Mic", 0x1 },
11794 static struct hda_input_mux alc268_acer_capture_source = {
11798 { "Internal Mic", 0x1 },
11803 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11807 { "Internal Mic", 0x6 },
11812 #ifdef CONFIG_SND_DEBUG
11813 static struct snd_kcontrol_new alc268_test_mixer[] = {
11814 /* Volume widgets */
11815 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11816 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11817 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11818 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11819 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11820 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11821 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11822 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11823 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11824 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11825 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11826 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11827 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11828 /* The below appears problematic on some hardwares */
11829 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11830 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11831 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11832 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11833 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11835 /* Modes for retasking pin widgets */
11836 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11837 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11838 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11839 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11841 /* Controls for GPIO pins, assuming they are configured as outputs */
11842 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11843 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11844 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11845 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11847 /* Switches to allow the digital SPDIF output pin to be enabled.
11848 * The ALC268 does not have an SPDIF input.
11850 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11852 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11853 * this output to turn on an external amplifier.
11855 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11856 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11862 /* create input playback/capture controls for the given pin */
11863 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11864 const char *ctlname, int idx)
11869 sprintf(name, "%s Playback Volume", ctlname);
11871 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11872 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11876 } else if (nid == 0x15) {
11877 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11878 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11884 sprintf(name, "%s Playback Switch", ctlname);
11885 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11886 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11892 /* add playback controls from the parsed DAC table */
11893 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11894 const struct auto_pin_cfg *cfg)
11899 spec->multiout.num_dacs = 2; /* only use one dac */
11900 spec->multiout.dac_nids = spec->private_dac_nids;
11901 spec->multiout.dac_nids[0] = 2;
11902 spec->multiout.dac_nids[1] = 3;
11904 nid = cfg->line_out_pins[0];
11906 alc268_new_analog_output(spec, nid, "Front", 0);
11908 nid = cfg->speaker_pins[0];
11910 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11911 "Speaker Playback Volume",
11912 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11916 nid = cfg->hp_pins[0];
11918 alc268_new_analog_output(spec, nid, "Headphone", 0);
11920 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11922 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11923 "Mono Playback Switch",
11924 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11931 /* create playback/capture controls for input pins */
11932 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11933 const struct auto_pin_cfg *cfg)
11935 struct hda_input_mux *imux = &spec->private_imux[0];
11938 for (i = 0; i < AUTO_PIN_LAST; i++) {
11939 switch(cfg->input_pins[i]) {
11941 idx1 = 0; /* Mic 1 */
11944 idx1 = 1; /* Mic 2 */
11947 idx1 = 2; /* Line In */
11954 idx1 = 6; /* digital mics */
11959 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11960 imux->items[imux->num_items].index = idx1;
11966 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11968 struct alc_spec *spec = codec->spec;
11969 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11970 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11971 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11972 unsigned int dac_vol1, dac_vol2;
11975 snd_hda_codec_write(codec, speaker_nid, 0,
11976 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11977 snd_hda_codec_write(codec, 0x0f, 0,
11978 AC_VERB_SET_AMP_GAIN_MUTE,
11980 snd_hda_codec_write(codec, 0x10, 0,
11981 AC_VERB_SET_AMP_GAIN_MUTE,
11984 snd_hda_codec_write(codec, 0x0f, 0,
11985 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11986 snd_hda_codec_write(codec, 0x10, 0,
11987 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11990 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11991 if (line_nid == 0x14)
11992 dac_vol2 = AMP_OUT_ZERO;
11993 else if (line_nid == 0x15)
11994 dac_vol1 = AMP_OUT_ZERO;
11995 if (hp_nid == 0x14)
11996 dac_vol2 = AMP_OUT_ZERO;
11997 else if (hp_nid == 0x15)
11998 dac_vol1 = AMP_OUT_ZERO;
11999 if (line_nid != 0x16 || hp_nid != 0x16 ||
12000 spec->autocfg.line_out_pins[1] != 0x16 ||
12001 spec->autocfg.line_out_pins[2] != 0x16)
12002 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12004 snd_hda_codec_write(codec, 0x02, 0,
12005 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12006 snd_hda_codec_write(codec, 0x03, 0,
12007 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12010 /* pcm configuration: identiacal with ALC880 */
12011 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
12012 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
12013 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
12014 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
12017 * BIOS auto configuration
12019 static int alc268_parse_auto_config(struct hda_codec *codec)
12021 struct alc_spec *spec = codec->spec;
12023 static hda_nid_t alc268_ignore[] = { 0 };
12025 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12029 if (!spec->autocfg.line_outs) {
12030 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12031 spec->multiout.max_channels = 2;
12032 spec->no_analog = 1;
12035 return 0; /* can't find valid BIOS pin config */
12037 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12040 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
12044 spec->multiout.max_channels = 2;
12047 /* digital only support output */
12048 if (spec->autocfg.dig_outs) {
12049 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12050 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12052 if (spec->kctls.list)
12053 add_mixer(spec, spec->kctls.list);
12055 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12056 add_mixer(spec, alc268_beep_mixer);
12058 add_verb(spec, alc268_volume_init_verbs);
12059 spec->num_mux_defs = 1;
12060 spec->input_mux = &spec->private_imux[0];
12062 err = alc_auto_add_mic_boost(codec);
12069 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12070 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12071 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12073 /* init callback for auto-configuration model -- overriding the default init */
12074 static void alc268_auto_init(struct hda_codec *codec)
12076 struct alc_spec *spec = codec->spec;
12077 alc268_auto_init_multi_out(codec);
12078 alc268_auto_init_hp_out(codec);
12079 alc268_auto_init_mono_speaker_out(codec);
12080 alc268_auto_init_analog_input(codec);
12081 if (spec->unsol_event)
12082 alc_inithook(codec);
12086 * configuration and preset
12088 static const char *alc268_models[ALC268_MODEL_LAST] = {
12089 [ALC267_QUANTA_IL1] = "quanta-il1",
12090 [ALC268_3ST] = "3stack",
12091 [ALC268_TOSHIBA] = "toshiba",
12092 [ALC268_ACER] = "acer",
12093 [ALC268_ACER_DMIC] = "acer-dmic",
12094 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12095 [ALC268_DELL] = "dell",
12096 [ALC268_ZEPTO] = "zepto",
12097 #ifdef CONFIG_SND_DEBUG
12098 [ALC268_TEST] = "test",
12100 [ALC268_AUTO] = "auto",
12103 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12104 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12105 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12106 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12107 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12108 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12109 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12110 ALC268_ACER_ASPIRE_ONE),
12111 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12112 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12113 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
12114 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12115 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
12116 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
12117 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
12118 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12119 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12120 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12121 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12125 static struct alc_config_preset alc268_presets[] = {
12126 [ALC267_QUANTA_IL1] = {
12127 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12128 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12129 alc267_quanta_il1_verbs },
12130 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12131 .dac_nids = alc268_dac_nids,
12132 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12133 .adc_nids = alc268_adc_nids_alt,
12135 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12136 .channel_mode = alc268_modes,
12137 .input_mux = &alc268_capture_source,
12138 .unsol_event = alc267_quanta_il1_unsol_event,
12139 .init_hook = alc267_quanta_il1_automute,
12142 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12143 alc268_beep_mixer },
12144 .init_verbs = { alc268_base_init_verbs },
12145 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12146 .dac_nids = alc268_dac_nids,
12147 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12148 .adc_nids = alc268_adc_nids_alt,
12149 .capsrc_nids = alc268_capsrc_nids,
12151 .dig_out_nid = ALC268_DIGOUT_NID,
12152 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12153 .channel_mode = alc268_modes,
12154 .input_mux = &alc268_capture_source,
12156 [ALC268_TOSHIBA] = {
12157 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12158 alc268_beep_mixer },
12159 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12160 alc268_toshiba_verbs },
12161 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12162 .dac_nids = alc268_dac_nids,
12163 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12164 .adc_nids = alc268_adc_nids_alt,
12165 .capsrc_nids = alc268_capsrc_nids,
12167 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12168 .channel_mode = alc268_modes,
12169 .input_mux = &alc268_capture_source,
12170 .unsol_event = alc268_toshiba_unsol_event,
12171 .init_hook = alc268_toshiba_automute,
12174 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12175 alc268_beep_mixer },
12176 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12177 alc268_acer_verbs },
12178 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12179 .dac_nids = alc268_dac_nids,
12180 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12181 .adc_nids = alc268_adc_nids_alt,
12182 .capsrc_nids = alc268_capsrc_nids,
12184 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12185 .channel_mode = alc268_modes,
12186 .input_mux = &alc268_acer_capture_source,
12187 .unsol_event = alc268_acer_unsol_event,
12188 .init_hook = alc268_acer_init_hook,
12190 [ALC268_ACER_DMIC] = {
12191 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12192 alc268_beep_mixer },
12193 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12194 alc268_acer_verbs },
12195 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12196 .dac_nids = alc268_dac_nids,
12197 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12198 .adc_nids = alc268_adc_nids_alt,
12199 .capsrc_nids = alc268_capsrc_nids,
12201 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12202 .channel_mode = alc268_modes,
12203 .input_mux = &alc268_acer_dmic_capture_source,
12204 .unsol_event = alc268_acer_unsol_event,
12205 .init_hook = alc268_acer_init_hook,
12207 [ALC268_ACER_ASPIRE_ONE] = {
12208 .mixers = { alc268_acer_aspire_one_mixer,
12210 alc268_capture_alt_mixer },
12211 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12212 alc268_acer_aspire_one_verbs },
12213 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12214 .dac_nids = alc268_dac_nids,
12215 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12216 .adc_nids = alc268_adc_nids_alt,
12217 .capsrc_nids = alc268_capsrc_nids,
12219 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12220 .channel_mode = alc268_modes,
12221 .input_mux = &alc268_acer_lc_capture_source,
12222 .unsol_event = alc268_acer_lc_unsol_event,
12223 .init_hook = alc268_acer_lc_init_hook,
12226 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12227 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12228 alc268_dell_verbs },
12229 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12230 .dac_nids = alc268_dac_nids,
12232 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12233 .channel_mode = alc268_modes,
12234 .unsol_event = alc268_dell_unsol_event,
12235 .init_hook = alc268_dell_init_hook,
12236 .input_mux = &alc268_capture_source,
12239 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12240 alc268_beep_mixer },
12241 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12242 alc268_toshiba_verbs },
12243 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12244 .dac_nids = alc268_dac_nids,
12245 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12246 .adc_nids = alc268_adc_nids_alt,
12247 .capsrc_nids = alc268_capsrc_nids,
12249 .dig_out_nid = ALC268_DIGOUT_NID,
12250 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12251 .channel_mode = alc268_modes,
12252 .input_mux = &alc268_capture_source,
12253 .unsol_event = alc268_toshiba_unsol_event,
12254 .init_hook = alc268_toshiba_automute
12256 #ifdef CONFIG_SND_DEBUG
12258 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12259 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12260 alc268_volume_init_verbs },
12261 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12262 .dac_nids = alc268_dac_nids,
12263 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12264 .adc_nids = alc268_adc_nids_alt,
12265 .capsrc_nids = alc268_capsrc_nids,
12267 .dig_out_nid = ALC268_DIGOUT_NID,
12268 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12269 .channel_mode = alc268_modes,
12270 .input_mux = &alc268_capture_source,
12275 static int patch_alc268(struct hda_codec *codec)
12277 struct alc_spec *spec;
12279 int i, has_beep, err;
12281 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12285 codec->spec = spec;
12287 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12291 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12292 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12293 "trying auto-probe from BIOS...\n");
12294 board_config = ALC268_AUTO;
12297 if (board_config == ALC268_AUTO) {
12298 /* automatic parse from the BIOS config */
12299 err = alc268_parse_auto_config(codec);
12305 "hda_codec: Cannot set up configuration "
12306 "from BIOS. Using base mode...\n");
12307 board_config = ALC268_3ST;
12311 if (board_config != ALC268_AUTO)
12312 setup_preset(spec, &alc268_presets[board_config]);
12314 if (codec->vendor_id == 0x10ec0267) {
12315 spec->stream_name_analog = "ALC267 Analog";
12316 spec->stream_name_digital = "ALC267 Digital";
12318 spec->stream_name_analog = "ALC268 Analog";
12319 spec->stream_name_digital = "ALC268 Digital";
12322 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12323 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12324 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12326 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12329 for (i = 0; i < spec->num_mixers; i++) {
12330 if (spec->mixers[i] == alc268_beep_mixer) {
12337 err = snd_hda_attach_beep_device(codec, 0x1);
12342 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12343 /* override the amp caps for beep generator */
12344 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12345 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12346 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12347 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12348 (0 << AC_AMPCAP_MUTE_SHIFT));
12351 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12352 /* check whether NID 0x07 is valid */
12353 unsigned int wcap = get_wcaps(codec, 0x07);
12357 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12358 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12359 spec->adc_nids = alc268_adc_nids_alt;
12360 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12361 add_mixer(spec, alc268_capture_alt_mixer);
12363 spec->adc_nids = alc268_adc_nids;
12364 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12365 add_mixer(spec, alc268_capture_mixer);
12367 spec->capsrc_nids = alc268_capsrc_nids;
12368 /* set default input source */
12369 for (i = 0; i < spec->num_adc_nids; i++)
12370 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12371 0, AC_VERB_SET_CONNECT_SEL,
12372 spec->input_mux->items[0].index);
12375 spec->vmaster_nid = 0x02;
12377 codec->patch_ops = alc_patch_ops;
12378 if (board_config == ALC268_AUTO)
12379 spec->init_hook = alc268_auto_init;
12381 codec->proc_widget_hook = print_realtek_coef;
12387 * ALC269 channel source setting (2 channel)
12389 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12391 #define alc269_dac_nids alc260_dac_nids
12393 static hda_nid_t alc269_adc_nids[1] = {
12398 static hda_nid_t alc269_capsrc_nids[1] = {
12402 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12406 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12414 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12422 #define alc269_modes alc260_modes
12423 #define alc269_capture_source alc880_lg_lw_capture_source
12425 static struct snd_kcontrol_new alc269_base_mixer[] = {
12426 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12427 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12432 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12433 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12434 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12435 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12436 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12437 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12441 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12442 /* output mixer control */
12443 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12446 .name = "Master Playback Switch",
12447 .info = snd_hda_mixer_amp_switch_info,
12448 .get = snd_hda_mixer_amp_switch_get,
12449 .put = alc268_acer_master_sw_put,
12450 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12452 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12453 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12454 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12455 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12456 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12457 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12461 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12462 /* output mixer control */
12463 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12465 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12466 .name = "Master Playback Switch",
12467 .info = snd_hda_mixer_amp_switch_info,
12468 .get = snd_hda_mixer_amp_switch_get,
12469 .put = alc268_acer_master_sw_put,
12470 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12473 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12474 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12475 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12476 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12477 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12478 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12479 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12480 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12484 /* bind volumes of both NID 0x0c and 0x0d */
12485 static struct hda_bind_ctls alc269_epc_bind_vol = {
12486 .ops = &snd_hda_bind_vol,
12488 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12489 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12494 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12495 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12496 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12497 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12501 /* capture mixer elements */
12502 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12503 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12504 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12505 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12510 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12511 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12513 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12517 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12518 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12519 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12520 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12521 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12522 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12523 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12527 static struct hda_verb alc269_lifebook_verbs[] = {
12528 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12529 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12530 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12531 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12532 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12533 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12534 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12535 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12536 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12537 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12541 /* toggle speaker-output according to the hp-jack state */
12542 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12544 unsigned int present;
12545 unsigned char bits;
12547 present = snd_hda_codec_read(codec, 0x15, 0,
12548 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12549 bits = present ? AMP_IN_MUTE(0) : 0;
12550 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12551 AMP_IN_MUTE(0), bits);
12552 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12553 AMP_IN_MUTE(0), bits);
12555 snd_hda_codec_write(codec, 0x20, 0,
12556 AC_VERB_SET_COEF_INDEX, 0x0c);
12557 snd_hda_codec_write(codec, 0x20, 0,
12558 AC_VERB_SET_PROC_COEF, 0x680);
12560 snd_hda_codec_write(codec, 0x20, 0,
12561 AC_VERB_SET_COEF_INDEX, 0x0c);
12562 snd_hda_codec_write(codec, 0x20, 0,
12563 AC_VERB_SET_PROC_COEF, 0x480);
12566 /* toggle speaker-output according to the hp-jacks state */
12567 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12569 unsigned int present;
12570 unsigned char bits;
12572 /* Check laptop headphone socket */
12573 present = snd_hda_codec_read(codec, 0x15, 0,
12574 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12576 /* Check port replicator headphone socket */
12577 present |= snd_hda_codec_read(codec, 0x1a, 0,
12578 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12580 bits = present ? AMP_IN_MUTE(0) : 0;
12581 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12582 AMP_IN_MUTE(0), bits);
12583 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12584 AMP_IN_MUTE(0), bits);
12586 snd_hda_codec_write(codec, 0x20, 0,
12587 AC_VERB_SET_COEF_INDEX, 0x0c);
12588 snd_hda_codec_write(codec, 0x20, 0,
12589 AC_VERB_SET_PROC_COEF, 0x680);
12591 snd_hda_codec_write(codec, 0x20, 0,
12592 AC_VERB_SET_COEF_INDEX, 0x0c);
12593 snd_hda_codec_write(codec, 0x20, 0,
12594 AC_VERB_SET_PROC_COEF, 0x480);
12597 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12599 unsigned int present;
12601 present = snd_hda_codec_read(codec, 0x18, 0,
12602 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12603 snd_hda_codec_write(codec, 0x23, 0,
12604 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12607 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12609 unsigned int present_laptop;
12610 unsigned int present_dock;
12612 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12613 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12615 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12616 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12618 /* Laptop mic port overrides dock mic port, design decision */
12620 snd_hda_codec_write(codec, 0x23, 0,
12621 AC_VERB_SET_CONNECT_SEL, 0x3);
12622 if (present_laptop)
12623 snd_hda_codec_write(codec, 0x23, 0,
12624 AC_VERB_SET_CONNECT_SEL, 0x0);
12625 if (!present_dock && !present_laptop)
12626 snd_hda_codec_write(codec, 0x23, 0,
12627 AC_VERB_SET_CONNECT_SEL, 0x1);
12630 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12633 if ((res >> 26) == ALC880_HP_EVENT)
12634 alc269_quanta_fl1_speaker_automute(codec);
12635 if ((res >> 26) == ALC880_MIC_EVENT)
12636 alc269_quanta_fl1_mic_automute(codec);
12639 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12642 if ((res >> 26) == ALC880_HP_EVENT)
12643 alc269_lifebook_speaker_automute(codec);
12644 if ((res >> 26) == ALC880_MIC_EVENT)
12645 alc269_lifebook_mic_autoswitch(codec);
12648 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12650 alc269_quanta_fl1_speaker_automute(codec);
12651 alc269_quanta_fl1_mic_automute(codec);
12654 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12656 alc269_lifebook_speaker_automute(codec);
12657 alc269_lifebook_mic_autoswitch(codec);
12660 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12661 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12662 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12663 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12664 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12665 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12666 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12667 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12671 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12673 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12674 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12676 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12677 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12681 /* toggle speaker-output according to the hp-jack state */
12682 static void alc269_speaker_automute(struct hda_codec *codec)
12684 unsigned int present;
12685 unsigned char bits;
12687 present = snd_hda_codec_read(codec, 0x15, 0,
12688 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12689 bits = present ? AMP_IN_MUTE(0) : 0;
12690 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12691 AMP_IN_MUTE(0), bits);
12692 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12693 AMP_IN_MUTE(0), bits);
12696 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12698 unsigned int present;
12700 present = snd_hda_codec_read(codec, 0x18, 0,
12701 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12702 snd_hda_codec_write(codec, 0x23, 0,
12703 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12706 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12708 unsigned int present;
12710 present = snd_hda_codec_read(codec, 0x18, 0,
12711 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12712 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12713 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12714 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12715 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12718 /* unsolicited event for HP jack sensing */
12719 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12722 if ((res >> 26) == ALC880_HP_EVENT)
12723 alc269_speaker_automute(codec);
12725 if ((res >> 26) == ALC880_MIC_EVENT)
12726 alc269_eeepc_dmic_automute(codec);
12729 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12731 alc269_speaker_automute(codec);
12732 alc269_eeepc_dmic_automute(codec);
12735 /* unsolicited event for HP jack sensing */
12736 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12739 if ((res >> 26) == ALC880_HP_EVENT)
12740 alc269_speaker_automute(codec);
12742 if ((res >> 26) == ALC880_MIC_EVENT)
12743 alc269_eeepc_amic_automute(codec);
12746 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12748 alc269_speaker_automute(codec);
12749 alc269_eeepc_amic_automute(codec);
12753 * generic initialization of ADC, input mixers and output mixers
12755 static struct hda_verb alc269_init_verbs[] = {
12757 * Unmute ADC0 and set the default input to mic-in
12759 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12761 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12762 * analog-loopback mixer widget
12763 * Note: PASD motherboards uses the Line In 2 as the input for
12764 * front panel mic (mic 2)
12766 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12771 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12774 * Set up output mixers (0x0c - 0x0e)
12776 /* set vol=0 to output mixers */
12777 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12778 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12780 /* set up input amps for analog loopback */
12781 /* Amp Indices: DAC = 0, mixer = 1 */
12782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12783 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12784 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12785 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12786 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12787 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12789 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12790 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12791 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12792 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12794 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12795 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12799 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12800 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12802 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12803 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12805 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12806 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12808 /* FIXME: use matrix-type input source selection */
12809 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12810 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12811 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12812 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12813 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12814 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12817 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12818 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12822 /* add playback controls from the parsed DAC table */
12823 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12824 const struct auto_pin_cfg *cfg)
12829 spec->multiout.num_dacs = 1; /* only use one dac */
12830 spec->multiout.dac_nids = spec->private_dac_nids;
12831 spec->multiout.dac_nids[0] = 2;
12833 nid = cfg->line_out_pins[0];
12835 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12836 "Front Playback Volume",
12837 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12840 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12841 "Front Playback Switch",
12842 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12847 nid = cfg->speaker_pins[0];
12849 if (!cfg->line_out_pins[0]) {
12850 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12851 "Speaker Playback Volume",
12852 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12858 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12859 "Speaker Playback Switch",
12860 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12865 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12866 "Speaker Playback Switch",
12867 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12873 nid = cfg->hp_pins[0];
12875 /* spec->multiout.hp_nid = 2; */
12876 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12877 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12878 "Headphone Playback Volume",
12879 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12885 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12886 "Headphone Playback Switch",
12887 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12892 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12893 "Headphone Playback Switch",
12894 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12903 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12904 const struct auto_pin_cfg *cfg)
12908 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12911 /* digital-mic input pin is excluded in alc880_auto_create..()
12912 * because it's under 0x18
12914 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12915 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12916 struct hda_input_mux *imux = &spec->private_imux[0];
12917 imux->items[imux->num_items].label = "Int Mic";
12918 imux->items[imux->num_items].index = 0x05;
12924 #ifdef CONFIG_SND_HDA_POWER_SAVE
12925 #define alc269_loopbacks alc880_loopbacks
12928 /* pcm configuration: identiacal with ALC880 */
12929 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12930 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12931 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12932 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12934 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12938 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12939 /* NID is set in alc_build_pcms */
12941 .open = alc880_playback_pcm_open,
12942 .prepare = alc880_playback_pcm_prepare,
12943 .cleanup = alc880_playback_pcm_cleanup
12947 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12951 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12952 /* NID is set in alc_build_pcms */
12956 * BIOS auto configuration
12958 static int alc269_parse_auto_config(struct hda_codec *codec)
12960 struct alc_spec *spec = codec->spec;
12962 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12964 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12969 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12972 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12976 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12978 if (spec->autocfg.dig_outs)
12979 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12981 if (spec->kctls.list)
12982 add_mixer(spec, spec->kctls.list);
12984 add_verb(spec, alc269_init_verbs);
12985 spec->num_mux_defs = 1;
12986 spec->input_mux = &spec->private_imux[0];
12987 /* set default input source */
12988 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12989 0, AC_VERB_SET_CONNECT_SEL,
12990 spec->input_mux->items[0].index);
12992 err = alc_auto_add_mic_boost(codec);
12996 if (!spec->cap_mixer && !spec->no_analog)
12997 set_capture_mixer(spec);
13002 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
13003 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
13004 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
13007 /* init callback for auto-configuration model -- overriding the default init */
13008 static void alc269_auto_init(struct hda_codec *codec)
13010 struct alc_spec *spec = codec->spec;
13011 alc269_auto_init_multi_out(codec);
13012 alc269_auto_init_hp_out(codec);
13013 alc269_auto_init_analog_input(codec);
13014 if (spec->unsol_event)
13015 alc_inithook(codec);
13019 * configuration and preset
13021 static const char *alc269_models[ALC269_MODEL_LAST] = {
13022 [ALC269_BASIC] = "basic",
13023 [ALC269_QUANTA_FL1] = "quanta",
13024 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
13025 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
13026 [ALC269_FUJITSU] = "fujitsu",
13027 [ALC269_LIFEBOOK] = "lifebook"
13030 static struct snd_pci_quirk alc269_cfg_tbl[] = {
13031 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13032 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13033 ALC269_ASUS_EEEPC_P703),
13034 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13035 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13036 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13037 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13038 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13039 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
13040 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13041 ALC269_ASUS_EEEPC_P901),
13042 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13043 ALC269_ASUS_EEEPC_P901),
13044 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
13045 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13046 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13050 static struct alc_config_preset alc269_presets[] = {
13052 .mixers = { alc269_base_mixer },
13053 .init_verbs = { alc269_init_verbs },
13054 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13055 .dac_nids = alc269_dac_nids,
13057 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13058 .channel_mode = alc269_modes,
13059 .input_mux = &alc269_capture_source,
13061 [ALC269_QUANTA_FL1] = {
13062 .mixers = { alc269_quanta_fl1_mixer },
13063 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13064 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13065 .dac_nids = alc269_dac_nids,
13067 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13068 .channel_mode = alc269_modes,
13069 .input_mux = &alc269_capture_source,
13070 .unsol_event = alc269_quanta_fl1_unsol_event,
13071 .init_hook = alc269_quanta_fl1_init_hook,
13073 [ALC269_ASUS_EEEPC_P703] = {
13074 .mixers = { alc269_eeepc_mixer },
13075 .cap_mixer = alc269_epc_capture_mixer,
13076 .init_verbs = { alc269_init_verbs,
13077 alc269_eeepc_amic_init_verbs },
13078 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13079 .dac_nids = alc269_dac_nids,
13081 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13082 .channel_mode = alc269_modes,
13083 .input_mux = &alc269_eeepc_amic_capture_source,
13084 .unsol_event = alc269_eeepc_amic_unsol_event,
13085 .init_hook = alc269_eeepc_amic_inithook,
13087 [ALC269_ASUS_EEEPC_P901] = {
13088 .mixers = { alc269_eeepc_mixer },
13089 .cap_mixer = alc269_epc_capture_mixer,
13090 .init_verbs = { alc269_init_verbs,
13091 alc269_eeepc_dmic_init_verbs },
13092 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13093 .dac_nids = alc269_dac_nids,
13095 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13096 .channel_mode = alc269_modes,
13097 .input_mux = &alc269_eeepc_dmic_capture_source,
13098 .unsol_event = alc269_eeepc_dmic_unsol_event,
13099 .init_hook = alc269_eeepc_dmic_inithook,
13101 [ALC269_FUJITSU] = {
13102 .mixers = { alc269_fujitsu_mixer },
13103 .cap_mixer = alc269_epc_capture_mixer,
13104 .init_verbs = { alc269_init_verbs,
13105 alc269_eeepc_dmic_init_verbs },
13106 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13107 .dac_nids = alc269_dac_nids,
13109 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13110 .channel_mode = alc269_modes,
13111 .input_mux = &alc269_eeepc_dmic_capture_source,
13112 .unsol_event = alc269_eeepc_dmic_unsol_event,
13113 .init_hook = alc269_eeepc_dmic_inithook,
13115 [ALC269_LIFEBOOK] = {
13116 .mixers = { alc269_lifebook_mixer },
13117 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13118 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13119 .dac_nids = alc269_dac_nids,
13121 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13122 .channel_mode = alc269_modes,
13123 .input_mux = &alc269_capture_source,
13124 .unsol_event = alc269_lifebook_unsol_event,
13125 .init_hook = alc269_lifebook_init_hook,
13129 static int patch_alc269(struct hda_codec *codec)
13131 struct alc_spec *spec;
13135 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13139 codec->spec = spec;
13141 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13143 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13147 if (board_config < 0) {
13148 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
13149 "trying auto-probe from BIOS...\n");
13150 board_config = ALC269_AUTO;
13153 if (board_config == ALC269_AUTO) {
13154 /* automatic parse from the BIOS config */
13155 err = alc269_parse_auto_config(codec);
13161 "hda_codec: Cannot set up configuration "
13162 "from BIOS. Using base mode...\n");
13163 board_config = ALC269_BASIC;
13167 err = snd_hda_attach_beep_device(codec, 0x1);
13173 if (board_config != ALC269_AUTO)
13174 setup_preset(spec, &alc269_presets[board_config]);
13176 spec->stream_name_analog = "ALC269 Analog";
13177 if (codec->subsystem_id == 0x17aa3bf8) {
13178 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13179 * fix the sample rate of analog I/O to 44.1kHz
13181 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13182 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13184 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13185 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13187 spec->stream_name_digital = "ALC269 Digital";
13188 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13189 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13191 spec->adc_nids = alc269_adc_nids;
13192 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13193 spec->capsrc_nids = alc269_capsrc_nids;
13194 if (!spec->cap_mixer)
13195 set_capture_mixer(spec);
13196 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13198 codec->patch_ops = alc_patch_ops;
13199 if (board_config == ALC269_AUTO)
13200 spec->init_hook = alc269_auto_init;
13201 #ifdef CONFIG_SND_HDA_POWER_SAVE
13202 if (!spec->loopback.amplist)
13203 spec->loopback.amplist = alc269_loopbacks;
13205 codec->proc_widget_hook = print_realtek_coef;
13211 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13215 * set the path ways for 2 channel output
13216 * need to set the codec line out and mic 1 pin widgets to inputs
13218 static struct hda_verb alc861_threestack_ch2_init[] = {
13219 /* set pin widget 1Ah (line in) for input */
13220 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13221 /* set pin widget 18h (mic1/2) for input, for mic also enable
13224 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13226 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13228 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13229 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13235 * need to set the codec line out and mic 1 pin widgets to outputs
13237 static struct hda_verb alc861_threestack_ch6_init[] = {
13238 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13239 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13240 /* set pin widget 18h (mic1) for output (CLFE)*/
13241 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13243 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13244 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13246 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13248 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13249 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13254 static struct hda_channel_mode alc861_threestack_modes[2] = {
13255 { 2, alc861_threestack_ch2_init },
13256 { 6, alc861_threestack_ch6_init },
13258 /* Set mic1 as input and unmute the mixer */
13259 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13260 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13261 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13264 /* Set mic1 as output and mute mixer */
13265 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13266 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13267 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13271 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13272 { 2, alc861_uniwill_m31_ch2_init },
13273 { 4, alc861_uniwill_m31_ch4_init },
13276 /* Set mic1 and line-in as input and unmute the mixer */
13277 static struct hda_verb alc861_asus_ch2_init[] = {
13278 /* set pin widget 1Ah (line in) for input */
13279 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13280 /* set pin widget 18h (mic1/2) for input, for mic also enable
13283 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13285 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13287 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13288 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13292 /* Set mic1 nad line-in as output and mute mixer */
13293 static struct hda_verb alc861_asus_ch6_init[] = {
13294 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13295 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13296 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13297 /* set pin widget 18h (mic1) for output (CLFE)*/
13298 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13299 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13300 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13301 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13303 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13305 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13306 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13311 static struct hda_channel_mode alc861_asus_modes[2] = {
13312 { 2, alc861_asus_ch2_init },
13313 { 6, alc861_asus_ch6_init },
13318 static struct snd_kcontrol_new alc861_base_mixer[] = {
13319 /* output mixer control */
13320 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13321 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13322 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13323 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13324 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13326 /*Input mixer control */
13327 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13328 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13329 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13330 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13331 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13332 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13333 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13334 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13335 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13336 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13341 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13342 /* output mixer control */
13343 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13344 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13345 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13346 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13347 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13349 /* Input mixer control */
13350 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13351 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13352 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13353 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13354 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13355 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13357 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13358 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13359 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13363 .name = "Channel Mode",
13364 .info = alc_ch_mode_info,
13365 .get = alc_ch_mode_get,
13366 .put = alc_ch_mode_put,
13367 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13372 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13373 /* output mixer control */
13374 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13376 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13381 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13382 /* output mixer control */
13383 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13384 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13385 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13386 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13387 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13389 /* Input mixer control */
13390 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13391 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13392 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13393 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13394 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13395 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13396 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13397 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13398 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13403 .name = "Channel Mode",
13404 .info = alc_ch_mode_info,
13405 .get = alc_ch_mode_get,
13406 .put = alc_ch_mode_put,
13407 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13412 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13413 /* output mixer control */
13414 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13415 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13416 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13417 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13418 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13420 /* Input mixer control */
13421 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13422 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13423 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13424 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13425 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13426 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13428 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13429 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13430 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13434 .name = "Channel Mode",
13435 .info = alc_ch_mode_info,
13436 .get = alc_ch_mode_get,
13437 .put = alc_ch_mode_put,
13438 .private_value = ARRAY_SIZE(alc861_asus_modes),
13443 /* additional mixer */
13444 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13445 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13446 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13451 * generic initialization of ADC, input mixers and output mixers
13453 static struct hda_verb alc861_base_init_verbs[] = {
13455 * Unmute ADC0 and set the default input to mic-in
13457 /* port-A for surround (rear panel) */
13458 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13459 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13460 /* port-B for mic-in (rear panel) with vref */
13461 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13462 /* port-C for line-in (rear panel) */
13463 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13464 /* port-D for Front */
13465 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13466 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13467 /* port-E for HP out (front panel) */
13468 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13469 /* route front PCM to HP */
13470 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13471 /* port-F for mic-in (front panel) with vref */
13472 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13473 /* port-G for CLFE (rear panel) */
13474 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13475 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13476 /* port-H for side (rear panel) */
13477 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13478 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13480 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13481 /* route front mic to ADC1*/
13482 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13483 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13485 /* Unmute DAC0~3 & spdif out*/
13486 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13487 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13488 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13489 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13492 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13493 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13494 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13495 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13496 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13498 /* Unmute Stereo Mixer 15 */
13499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13502 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13505 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13506 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13507 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13512 /* hp used DAC 3 (Front) */
13513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13514 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13519 static struct hda_verb alc861_threestack_init_verbs[] = {
13521 * Unmute ADC0 and set the default input to mic-in
13523 /* port-A for surround (rear panel) */
13524 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13525 /* port-B for mic-in (rear panel) with vref */
13526 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13527 /* port-C for line-in (rear panel) */
13528 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13529 /* port-D for Front */
13530 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13531 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13532 /* port-E for HP out (front panel) */
13533 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13534 /* route front PCM to HP */
13535 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13536 /* port-F for mic-in (front panel) with vref */
13537 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13538 /* port-G for CLFE (rear panel) */
13539 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13540 /* port-H for side (rear panel) */
13541 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13543 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13544 /* route front mic to ADC1*/
13545 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13547 /* Unmute DAC0~3 & spdif out*/
13548 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13549 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13550 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13551 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13554 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13555 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13556 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13557 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13558 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13560 /* Unmute Stereo Mixer 15 */
13561 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13562 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13566 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13567 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13568 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13569 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13571 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13572 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13573 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13574 /* hp used DAC 3 (Front) */
13575 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13576 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13580 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13582 * Unmute ADC0 and set the default input to mic-in
13584 /* port-A for surround (rear panel) */
13585 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13586 /* port-B for mic-in (rear panel) with vref */
13587 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13588 /* port-C for line-in (rear panel) */
13589 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13590 /* port-D for Front */
13591 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13592 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13593 /* port-E for HP out (front panel) */
13594 /* this has to be set to VREF80 */
13595 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13596 /* route front PCM to HP */
13597 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13598 /* port-F for mic-in (front panel) with vref */
13599 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13600 /* port-G for CLFE (rear panel) */
13601 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13602 /* port-H for side (rear panel) */
13603 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13605 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13606 /* route front mic to ADC1*/
13607 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13608 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13609 /* Unmute DAC0~3 & spdif out*/
13610 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13611 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13613 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13616 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13617 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13618 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13619 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13620 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13622 /* Unmute Stereo Mixer 15 */
13623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13628 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13629 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13630 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13631 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13633 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13635 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13636 /* hp used DAC 3 (Front) */
13637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13642 static struct hda_verb alc861_asus_init_verbs[] = {
13644 * Unmute ADC0 and set the default input to mic-in
13646 /* port-A for surround (rear panel)
13647 * according to codec#0 this is the HP jack
13649 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13650 /* route front PCM to HP */
13651 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13652 /* port-B for mic-in (rear panel) with vref */
13653 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13654 /* port-C for line-in (rear panel) */
13655 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13656 /* port-D for Front */
13657 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13658 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13659 /* port-E for HP out (front panel) */
13660 /* this has to be set to VREF80 */
13661 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13662 /* route front PCM to HP */
13663 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13664 /* port-F for mic-in (front panel) with vref */
13665 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13666 /* port-G for CLFE (rear panel) */
13667 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13668 /* port-H for side (rear panel) */
13669 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13671 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13672 /* route front mic to ADC1*/
13673 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13675 /* Unmute DAC0~3 & spdif out*/
13676 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13677 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13678 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13679 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13681 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13682 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13683 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13684 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13685 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13687 /* Unmute Stereo Mixer 15 */
13688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13691 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13693 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13694 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13695 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13696 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13698 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13699 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13700 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13701 /* hp used DAC 3 (Front) */
13702 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13703 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13707 /* additional init verbs for ASUS laptops */
13708 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13709 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13710 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13715 * generic initialization of ADC, input mixers and output mixers
13717 static struct hda_verb alc861_auto_init_verbs[] = {
13719 * Unmute ADC0 and set the default input to mic-in
13721 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13722 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13724 /* Unmute DAC0~3 & spdif out*/
13725 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13726 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13727 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13728 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13729 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13731 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13732 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13733 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13734 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13735 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13737 /* Unmute Stereo Mixer 15 */
13738 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13739 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13740 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13743 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13744 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13745 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13746 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13749 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13755 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13757 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13758 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13759 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13761 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13766 static struct hda_verb alc861_toshiba_init_verbs[] = {
13767 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13772 /* toggle speaker-output according to the hp-jack state */
13773 static void alc861_toshiba_automute(struct hda_codec *codec)
13775 unsigned int present;
13777 present = snd_hda_codec_read(codec, 0x0f, 0,
13778 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13779 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13780 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13781 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13782 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13785 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13788 if ((res >> 26) == ALC880_HP_EVENT)
13789 alc861_toshiba_automute(codec);
13792 /* pcm configuration: identiacal with ALC880 */
13793 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13794 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13795 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13796 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13799 #define ALC861_DIGOUT_NID 0x07
13801 static struct hda_channel_mode alc861_8ch_modes[1] = {
13805 static hda_nid_t alc861_dac_nids[4] = {
13806 /* front, surround, clfe, side */
13807 0x03, 0x06, 0x05, 0x04
13810 static hda_nid_t alc660_dac_nids[3] = {
13811 /* front, clfe, surround */
13815 static hda_nid_t alc861_adc_nids[1] = {
13820 static struct hda_input_mux alc861_capture_source = {
13824 { "Front Mic", 0x3 },
13831 /* fill in the dac_nids table from the parsed pin configuration */
13832 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13833 const struct auto_pin_cfg *cfg)
13838 spec->multiout.dac_nids = spec->private_dac_nids;
13839 for (i = 0; i < cfg->line_outs; i++) {
13840 nid = cfg->line_out_pins[i];
13842 if (i >= ARRAY_SIZE(alc861_dac_nids))
13844 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13847 spec->multiout.num_dacs = cfg->line_outs;
13851 /* add playback controls from the parsed DAC table */
13852 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13853 const struct auto_pin_cfg *cfg)
13856 static const char *chname[4] = {
13857 "Front", "Surround", NULL /*CLFE*/, "Side"
13862 for (i = 0; i < cfg->line_outs; i++) {
13863 nid = spec->multiout.dac_nids[i];
13868 err = add_control(spec, ALC_CTL_BIND_MUTE,
13869 "Center Playback Switch",
13870 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13874 err = add_control(spec, ALC_CTL_BIND_MUTE,
13875 "LFE Playback Switch",
13876 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13881 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13883 if (nid == alc861_dac_nids[idx])
13885 sprintf(name, "%s Playback Switch", chname[idx]);
13886 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13887 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13896 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13904 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13906 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13907 "Headphone Playback Switch",
13908 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13911 spec->multiout.hp_nid = nid;
13916 /* create playback/capture controls for input pins */
13917 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13918 const struct auto_pin_cfg *cfg)
13920 struct hda_input_mux *imux = &spec->private_imux[0];
13921 int i, err, idx, idx1;
13923 for (i = 0; i < AUTO_PIN_LAST; i++) {
13924 switch (cfg->input_pins[i]) {
13927 idx = 2; /* Line In */
13931 idx = 2; /* Line In */
13935 idx = 1; /* Mic In */
13939 idx = 1; /* Mic In */
13949 err = new_analog_input(spec, cfg->input_pins[i],
13950 auto_pin_cfg_labels[i], idx, 0x15);
13954 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13955 imux->items[imux->num_items].index = idx1;
13961 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13963 int pin_type, int dac_idx)
13965 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13967 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13971 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13973 struct alc_spec *spec = codec->spec;
13976 for (i = 0; i < spec->autocfg.line_outs; i++) {
13977 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13978 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13980 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13981 spec->multiout.dac_nids[i]);
13985 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13987 struct alc_spec *spec = codec->spec;
13990 pin = spec->autocfg.hp_pins[0];
13991 if (pin) /* connect to front */
13992 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13993 spec->multiout.dac_nids[0]);
13994 pin = spec->autocfg.speaker_pins[0];
13996 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13999 static void alc861_auto_init_analog_input(struct hda_codec *codec)
14001 struct alc_spec *spec = codec->spec;
14004 for (i = 0; i < AUTO_PIN_LAST; i++) {
14005 hda_nid_t nid = spec->autocfg.input_pins[i];
14006 if (nid >= 0x0c && nid <= 0x11)
14007 alc_set_input_pin(codec, nid, i);
14011 /* parse the BIOS configuration and set up the alc_spec */
14012 /* return 1 if successful, 0 if the proper config is not found,
14013 * or a negative error code
14015 static int alc861_parse_auto_config(struct hda_codec *codec)
14017 struct alc_spec *spec = codec->spec;
14019 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14021 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14025 if (!spec->autocfg.line_outs)
14026 return 0; /* can't find valid BIOS pin config */
14028 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
14031 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
14034 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
14037 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
14041 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14043 if (spec->autocfg.dig_outs)
14044 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14046 if (spec->kctls.list)
14047 add_mixer(spec, spec->kctls.list);
14049 add_verb(spec, alc861_auto_init_verbs);
14051 spec->num_mux_defs = 1;
14052 spec->input_mux = &spec->private_imux[0];
14054 spec->adc_nids = alc861_adc_nids;
14055 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14056 set_capture_mixer(spec);
14058 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14063 /* additional initialization for auto-configuration model */
14064 static void alc861_auto_init(struct hda_codec *codec)
14066 struct alc_spec *spec = codec->spec;
14067 alc861_auto_init_multi_out(codec);
14068 alc861_auto_init_hp_out(codec);
14069 alc861_auto_init_analog_input(codec);
14070 if (spec->unsol_event)
14071 alc_inithook(codec);
14074 #ifdef CONFIG_SND_HDA_POWER_SAVE
14075 static struct hda_amp_list alc861_loopbacks[] = {
14076 { 0x15, HDA_INPUT, 0 },
14077 { 0x15, HDA_INPUT, 1 },
14078 { 0x15, HDA_INPUT, 2 },
14079 { 0x15, HDA_INPUT, 3 },
14086 * configuration and preset
14088 static const char *alc861_models[ALC861_MODEL_LAST] = {
14089 [ALC861_3ST] = "3stack",
14090 [ALC660_3ST] = "3stack-660",
14091 [ALC861_3ST_DIG] = "3stack-dig",
14092 [ALC861_6ST_DIG] = "6stack-dig",
14093 [ALC861_UNIWILL_M31] = "uniwill-m31",
14094 [ALC861_TOSHIBA] = "toshiba",
14095 [ALC861_ASUS] = "asus",
14096 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14097 [ALC861_AUTO] = "auto",
14100 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14101 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14102 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14103 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14104 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14105 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14106 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14107 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14108 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14109 * Any other models that need this preset?
14111 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14112 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14113 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14114 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14115 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14116 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14117 /* FIXME: the below seems conflict */
14118 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14119 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14120 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14124 static struct alc_config_preset alc861_presets[] = {
14126 .mixers = { alc861_3ST_mixer },
14127 .init_verbs = { alc861_threestack_init_verbs },
14128 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14129 .dac_nids = alc861_dac_nids,
14130 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14131 .channel_mode = alc861_threestack_modes,
14133 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14134 .adc_nids = alc861_adc_nids,
14135 .input_mux = &alc861_capture_source,
14137 [ALC861_3ST_DIG] = {
14138 .mixers = { alc861_base_mixer },
14139 .init_verbs = { alc861_threestack_init_verbs },
14140 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14141 .dac_nids = alc861_dac_nids,
14142 .dig_out_nid = ALC861_DIGOUT_NID,
14143 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14144 .channel_mode = alc861_threestack_modes,
14146 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14147 .adc_nids = alc861_adc_nids,
14148 .input_mux = &alc861_capture_source,
14150 [ALC861_6ST_DIG] = {
14151 .mixers = { alc861_base_mixer },
14152 .init_verbs = { alc861_base_init_verbs },
14153 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14154 .dac_nids = alc861_dac_nids,
14155 .dig_out_nid = ALC861_DIGOUT_NID,
14156 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14157 .channel_mode = alc861_8ch_modes,
14158 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14159 .adc_nids = alc861_adc_nids,
14160 .input_mux = &alc861_capture_source,
14163 .mixers = { alc861_3ST_mixer },
14164 .init_verbs = { alc861_threestack_init_verbs },
14165 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14166 .dac_nids = alc660_dac_nids,
14167 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14168 .channel_mode = alc861_threestack_modes,
14170 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14171 .adc_nids = alc861_adc_nids,
14172 .input_mux = &alc861_capture_source,
14174 [ALC861_UNIWILL_M31] = {
14175 .mixers = { alc861_uniwill_m31_mixer },
14176 .init_verbs = { alc861_uniwill_m31_init_verbs },
14177 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14178 .dac_nids = alc861_dac_nids,
14179 .dig_out_nid = ALC861_DIGOUT_NID,
14180 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14181 .channel_mode = alc861_uniwill_m31_modes,
14183 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14184 .adc_nids = alc861_adc_nids,
14185 .input_mux = &alc861_capture_source,
14187 [ALC861_TOSHIBA] = {
14188 .mixers = { alc861_toshiba_mixer },
14189 .init_verbs = { alc861_base_init_verbs,
14190 alc861_toshiba_init_verbs },
14191 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14192 .dac_nids = alc861_dac_nids,
14193 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14194 .channel_mode = alc883_3ST_2ch_modes,
14195 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14196 .adc_nids = alc861_adc_nids,
14197 .input_mux = &alc861_capture_source,
14198 .unsol_event = alc861_toshiba_unsol_event,
14199 .init_hook = alc861_toshiba_automute,
14202 .mixers = { alc861_asus_mixer },
14203 .init_verbs = { alc861_asus_init_verbs },
14204 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14205 .dac_nids = alc861_dac_nids,
14206 .dig_out_nid = ALC861_DIGOUT_NID,
14207 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14208 .channel_mode = alc861_asus_modes,
14211 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14212 .adc_nids = alc861_adc_nids,
14213 .input_mux = &alc861_capture_source,
14215 [ALC861_ASUS_LAPTOP] = {
14216 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14217 .init_verbs = { alc861_asus_init_verbs,
14218 alc861_asus_laptop_init_verbs },
14219 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14220 .dac_nids = alc861_dac_nids,
14221 .dig_out_nid = ALC861_DIGOUT_NID,
14222 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14223 .channel_mode = alc883_3ST_2ch_modes,
14225 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14226 .adc_nids = alc861_adc_nids,
14227 .input_mux = &alc861_capture_source,
14232 static int patch_alc861(struct hda_codec *codec)
14234 struct alc_spec *spec;
14238 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14242 codec->spec = spec;
14244 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14248 if (board_config < 0) {
14249 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14250 "trying auto-probe from BIOS...\n");
14251 board_config = ALC861_AUTO;
14254 if (board_config == ALC861_AUTO) {
14255 /* automatic parse from the BIOS config */
14256 err = alc861_parse_auto_config(codec);
14262 "hda_codec: Cannot set up configuration "
14263 "from BIOS. Using base mode...\n");
14264 board_config = ALC861_3ST_DIG;
14268 err = snd_hda_attach_beep_device(codec, 0x23);
14274 if (board_config != ALC861_AUTO)
14275 setup_preset(spec, &alc861_presets[board_config]);
14277 spec->stream_name_analog = "ALC861 Analog";
14278 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14279 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14281 spec->stream_name_digital = "ALC861 Digital";
14282 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14283 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14285 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14287 spec->vmaster_nid = 0x03;
14289 codec->patch_ops = alc_patch_ops;
14290 if (board_config == ALC861_AUTO)
14291 spec->init_hook = alc861_auto_init;
14292 #ifdef CONFIG_SND_HDA_POWER_SAVE
14293 if (!spec->loopback.amplist)
14294 spec->loopback.amplist = alc861_loopbacks;
14296 codec->proc_widget_hook = print_realtek_coef;
14302 * ALC861-VD support
14306 * In addition, an independent DAC
14308 #define ALC861VD_DIGOUT_NID 0x06
14310 static hda_nid_t alc861vd_dac_nids[4] = {
14311 /* front, surr, clfe, side surr */
14312 0x02, 0x03, 0x04, 0x05
14315 /* dac_nids for ALC660vd are in a different order - according to
14316 * Realtek's driver.
14317 * This should probably tesult in a different mixer for 6stack models
14318 * of ALC660vd codecs, but for now there is only 3stack mixer
14319 * - and it is the same as in 861vd.
14320 * adc_nids in ALC660vd are (is) the same as in 861vd
14322 static hda_nid_t alc660vd_dac_nids[3] = {
14323 /* front, rear, clfe, rear_surr */
14327 static hda_nid_t alc861vd_adc_nids[1] = {
14332 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14335 /* FIXME: should be a matrix-type input source selection */
14336 static struct hda_input_mux alc861vd_capture_source = {
14340 { "Front Mic", 0x1 },
14346 static struct hda_input_mux alc861vd_dallas_capture_source = {
14349 { "Ext Mic", 0x0 },
14350 { "Int Mic", 0x1 },
14354 static struct hda_input_mux alc861vd_hp_capture_source = {
14357 { "Front Mic", 0x0 },
14358 { "ATAPI Mic", 0x1 },
14365 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14372 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14373 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14374 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14375 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14376 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14383 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14384 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14385 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14386 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14387 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14391 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14392 { 6, alc861vd_6stack_ch6_init },
14393 { 8, alc861vd_6stack_ch8_init },
14396 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14398 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14399 .name = "Channel Mode",
14400 .info = alc_ch_mode_info,
14401 .get = alc_ch_mode_get,
14402 .put = alc_ch_mode_put,
14407 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14408 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14410 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14411 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14412 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14414 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14415 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14417 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14419 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14421 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14422 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14424 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14425 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14429 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14433 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14434 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14440 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14441 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14446 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14447 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14448 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14452 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14456 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14457 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14461 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14463 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14464 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14469 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14470 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14471 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14472 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14474 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14476 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14478 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14480 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14481 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14482 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14484 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14485 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14490 /* Pin assignment: Speaker=0x14, HP = 0x15,
14491 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14493 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14494 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14495 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14496 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14497 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14498 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14499 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14500 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14501 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14502 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14503 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14507 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14508 * Front Mic=0x18, ATAPI Mic = 0x19,
14510 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14511 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14512 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14513 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14514 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14515 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14516 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14517 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14518 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14524 * generic initialization of ADC, input mixers and output mixers
14526 static struct hda_verb alc861vd_volume_init_verbs[] = {
14528 * Unmute ADC0 and set the default input to mic-in
14530 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14533 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14534 * the analog-loopback mixer widget
14536 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14537 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14538 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14543 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14544 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14545 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14546 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14547 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14550 * Set up output mixers (0x02 - 0x05)
14552 /* set vol=0 to output mixers */
14553 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14554 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14555 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14556 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14558 /* set up input amps for analog loopback */
14559 /* Amp Indices: DAC = 0, mixer = 1 */
14560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14564 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14566 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14567 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14573 * 3-stack pin configuration:
14574 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14576 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14578 * Set pin mode and muting
14580 /* set front pin widgets 0x14 for output */
14581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14585 /* Mic (rear) pin: input vref at 80% */
14586 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14587 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14588 /* Front Mic pin: input vref at 80% */
14589 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14590 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14591 /* Line In pin: input */
14592 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14593 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14594 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14595 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14596 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14597 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14598 /* CD pin widget for input */
14599 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14605 * 6-stack pin configuration:
14607 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14609 * Set pin mode and muting
14611 /* set front pin widgets 0x14 for output */
14612 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14613 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14614 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14616 /* Rear Pin: output 1 (0x0d) */
14617 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14618 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14619 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14620 /* CLFE Pin: output 2 (0x0e) */
14621 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14622 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14623 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14624 /* Side Pin: output 3 (0x0f) */
14625 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14626 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14627 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14629 /* Mic (rear) pin: input vref at 80% */
14630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14632 /* Front Mic pin: input vref at 80% */
14633 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14635 /* Line In pin: input */
14636 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14638 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14639 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14640 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14641 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14642 /* CD pin widget for input */
14643 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14648 static struct hda_verb alc861vd_eapd_verbs[] = {
14649 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14653 static struct hda_verb alc660vd_eapd_verbs[] = {
14654 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14655 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14659 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14662 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14663 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14664 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14668 /* toggle speaker-output according to the hp-jack state */
14669 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14671 unsigned int present;
14672 unsigned char bits;
14674 present = snd_hda_codec_read(codec, 0x1b, 0,
14675 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14676 bits = present ? HDA_AMP_MUTE : 0;
14677 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14678 HDA_AMP_MUTE, bits);
14681 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14683 unsigned int present;
14684 unsigned char bits;
14686 present = snd_hda_codec_read(codec, 0x18, 0,
14687 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14688 bits = present ? HDA_AMP_MUTE : 0;
14689 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14690 HDA_AMP_MUTE, bits);
14693 static void alc861vd_lenovo_automute(struct hda_codec *codec)
14695 alc861vd_lenovo_hp_automute(codec);
14696 alc861vd_lenovo_mic_automute(codec);
14699 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14702 switch (res >> 26) {
14703 case ALC880_HP_EVENT:
14704 alc861vd_lenovo_hp_automute(codec);
14706 case ALC880_MIC_EVENT:
14707 alc861vd_lenovo_mic_automute(codec);
14712 static struct hda_verb alc861vd_dallas_verbs[] = {
14713 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14714 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14715 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14716 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14724 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14725 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14727 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14729 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14731 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14732 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14733 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14734 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14736 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14737 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14738 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14740 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14741 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14742 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14743 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14745 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14746 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14747 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14748 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14750 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14751 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14752 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14757 /* toggle speaker-output according to the hp-jack state */
14758 static void alc861vd_dallas_automute(struct hda_codec *codec)
14760 unsigned int present;
14762 present = snd_hda_codec_read(codec, 0x15, 0,
14763 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14764 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14765 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14768 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14770 if ((res >> 26) == ALC880_HP_EVENT)
14771 alc861vd_dallas_automute(codec);
14774 #ifdef CONFIG_SND_HDA_POWER_SAVE
14775 #define alc861vd_loopbacks alc880_loopbacks
14778 /* pcm configuration: identiacal with ALC880 */
14779 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14780 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14781 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14782 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14785 * configuration and preset
14787 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14788 [ALC660VD_3ST] = "3stack-660",
14789 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14790 [ALC660VD_ASUS_V1S] = "asus-v1s",
14791 [ALC861VD_3ST] = "3stack",
14792 [ALC861VD_3ST_DIG] = "3stack-digout",
14793 [ALC861VD_6ST_DIG] = "6stack-digout",
14794 [ALC861VD_LENOVO] = "lenovo",
14795 [ALC861VD_DALLAS] = "dallas",
14796 [ALC861VD_HP] = "hp",
14797 [ALC861VD_AUTO] = "auto",
14800 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14801 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14802 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14803 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14804 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14805 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14806 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14807 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14808 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14809 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14810 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14811 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14812 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14813 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14814 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14815 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14819 static struct alc_config_preset alc861vd_presets[] = {
14821 .mixers = { alc861vd_3st_mixer },
14822 .init_verbs = { alc861vd_volume_init_verbs,
14823 alc861vd_3stack_init_verbs },
14824 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14825 .dac_nids = alc660vd_dac_nids,
14826 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14827 .channel_mode = alc861vd_3stack_2ch_modes,
14828 .input_mux = &alc861vd_capture_source,
14830 [ALC660VD_3ST_DIG] = {
14831 .mixers = { alc861vd_3st_mixer },
14832 .init_verbs = { alc861vd_volume_init_verbs,
14833 alc861vd_3stack_init_verbs },
14834 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14835 .dac_nids = alc660vd_dac_nids,
14836 .dig_out_nid = ALC861VD_DIGOUT_NID,
14837 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14838 .channel_mode = alc861vd_3stack_2ch_modes,
14839 .input_mux = &alc861vd_capture_source,
14842 .mixers = { alc861vd_3st_mixer },
14843 .init_verbs = { alc861vd_volume_init_verbs,
14844 alc861vd_3stack_init_verbs },
14845 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14846 .dac_nids = alc861vd_dac_nids,
14847 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14848 .channel_mode = alc861vd_3stack_2ch_modes,
14849 .input_mux = &alc861vd_capture_source,
14851 [ALC861VD_3ST_DIG] = {
14852 .mixers = { alc861vd_3st_mixer },
14853 .init_verbs = { alc861vd_volume_init_verbs,
14854 alc861vd_3stack_init_verbs },
14855 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14856 .dac_nids = alc861vd_dac_nids,
14857 .dig_out_nid = ALC861VD_DIGOUT_NID,
14858 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14859 .channel_mode = alc861vd_3stack_2ch_modes,
14860 .input_mux = &alc861vd_capture_source,
14862 [ALC861VD_6ST_DIG] = {
14863 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14864 .init_verbs = { alc861vd_volume_init_verbs,
14865 alc861vd_6stack_init_verbs },
14866 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14867 .dac_nids = alc861vd_dac_nids,
14868 .dig_out_nid = ALC861VD_DIGOUT_NID,
14869 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14870 .channel_mode = alc861vd_6stack_modes,
14871 .input_mux = &alc861vd_capture_source,
14873 [ALC861VD_LENOVO] = {
14874 .mixers = { alc861vd_lenovo_mixer },
14875 .init_verbs = { alc861vd_volume_init_verbs,
14876 alc861vd_3stack_init_verbs,
14877 alc861vd_eapd_verbs,
14878 alc861vd_lenovo_unsol_verbs },
14879 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14880 .dac_nids = alc660vd_dac_nids,
14881 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14882 .channel_mode = alc861vd_3stack_2ch_modes,
14883 .input_mux = &alc861vd_capture_source,
14884 .unsol_event = alc861vd_lenovo_unsol_event,
14885 .init_hook = alc861vd_lenovo_automute,
14887 [ALC861VD_DALLAS] = {
14888 .mixers = { alc861vd_dallas_mixer },
14889 .init_verbs = { alc861vd_dallas_verbs },
14890 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14891 .dac_nids = alc861vd_dac_nids,
14892 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14893 .channel_mode = alc861vd_3stack_2ch_modes,
14894 .input_mux = &alc861vd_dallas_capture_source,
14895 .unsol_event = alc861vd_dallas_unsol_event,
14896 .init_hook = alc861vd_dallas_automute,
14899 .mixers = { alc861vd_hp_mixer },
14900 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14901 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14902 .dac_nids = alc861vd_dac_nids,
14903 .dig_out_nid = ALC861VD_DIGOUT_NID,
14904 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14905 .channel_mode = alc861vd_3stack_2ch_modes,
14906 .input_mux = &alc861vd_hp_capture_source,
14907 .unsol_event = alc861vd_dallas_unsol_event,
14908 .init_hook = alc861vd_dallas_automute,
14910 [ALC660VD_ASUS_V1S] = {
14911 .mixers = { alc861vd_lenovo_mixer },
14912 .init_verbs = { alc861vd_volume_init_verbs,
14913 alc861vd_3stack_init_verbs,
14914 alc861vd_eapd_verbs,
14915 alc861vd_lenovo_unsol_verbs },
14916 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14917 .dac_nids = alc660vd_dac_nids,
14918 .dig_out_nid = ALC861VD_DIGOUT_NID,
14919 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14920 .channel_mode = alc861vd_3stack_2ch_modes,
14921 .input_mux = &alc861vd_capture_source,
14922 .unsol_event = alc861vd_lenovo_unsol_event,
14923 .init_hook = alc861vd_lenovo_automute,
14928 * BIOS auto configuration
14930 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14931 hda_nid_t nid, int pin_type, int dac_idx)
14933 alc_set_pin_output(codec, nid, pin_type);
14936 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14938 struct alc_spec *spec = codec->spec;
14941 for (i = 0; i <= HDA_SIDE; i++) {
14942 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14943 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14945 alc861vd_auto_set_output_and_unmute(codec, nid,
14951 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14953 struct alc_spec *spec = codec->spec;
14956 pin = spec->autocfg.hp_pins[0];
14957 if (pin) /* connect to front and use dac 0 */
14958 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14959 pin = spec->autocfg.speaker_pins[0];
14961 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14964 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14965 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14967 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14969 struct alc_spec *spec = codec->spec;
14972 for (i = 0; i < AUTO_PIN_LAST; i++) {
14973 hda_nid_t nid = spec->autocfg.input_pins[i];
14974 if (alc861vd_is_input_pin(nid)) {
14975 alc_set_input_pin(codec, nid, i);
14976 if (nid != ALC861VD_PIN_CD_NID &&
14977 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14978 snd_hda_codec_write(codec, nid, 0,
14979 AC_VERB_SET_AMP_GAIN_MUTE,
14985 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14987 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14988 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14990 /* add playback controls from the parsed DAC table */
14991 /* Based on ALC880 version. But ALC861VD has separate,
14992 * different NIDs for mute/unmute switch and volume control */
14993 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14994 const struct auto_pin_cfg *cfg)
14997 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14998 hda_nid_t nid_v, nid_s;
15001 for (i = 0; i < cfg->line_outs; i++) {
15002 if (!spec->multiout.dac_nids[i])
15004 nid_v = alc861vd_idx_to_mixer_vol(
15006 spec->multiout.dac_nids[i]));
15007 nid_s = alc861vd_idx_to_mixer_switch(
15009 spec->multiout.dac_nids[i]));
15013 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15014 "Center Playback Volume",
15015 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15019 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15020 "LFE Playback Volume",
15021 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15025 err = add_control(spec, ALC_CTL_BIND_MUTE,
15026 "Center Playback Switch",
15027 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15031 err = add_control(spec, ALC_CTL_BIND_MUTE,
15032 "LFE Playback Switch",
15033 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15038 sprintf(name, "%s Playback Volume", chname[i]);
15039 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15040 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15044 sprintf(name, "%s Playback Switch", chname[i]);
15045 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15046 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15055 /* add playback controls for speaker and HP outputs */
15056 /* Based on ALC880 version. But ALC861VD has separate,
15057 * different NIDs for mute/unmute switch and volume control */
15058 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15059 hda_nid_t pin, const char *pfx)
15061 hda_nid_t nid_v, nid_s;
15068 if (alc880_is_fixed_pin(pin)) {
15069 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15070 /* specify the DAC as the extra output */
15071 if (!spec->multiout.hp_nid)
15072 spec->multiout.hp_nid = nid_v;
15074 spec->multiout.extra_out_nid[0] = nid_v;
15075 /* control HP volume/switch on the output mixer amp */
15076 nid_v = alc861vd_idx_to_mixer_vol(
15077 alc880_fixed_pin_idx(pin));
15078 nid_s = alc861vd_idx_to_mixer_switch(
15079 alc880_fixed_pin_idx(pin));
15081 sprintf(name, "%s Playback Volume", pfx);
15082 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15083 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15086 sprintf(name, "%s Playback Switch", pfx);
15087 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15088 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15091 } else if (alc880_is_multi_pin(pin)) {
15092 /* set manual connection */
15093 /* we have only a switch on HP-out PIN */
15094 sprintf(name, "%s Playback Switch", pfx);
15095 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15096 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15103 /* parse the BIOS configuration and set up the alc_spec
15104 * return 1 if successful, 0 if the proper config is not found,
15105 * or a negative error code
15106 * Based on ALC880 version - had to change it to override
15107 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15108 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15110 struct alc_spec *spec = codec->spec;
15112 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15114 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15118 if (!spec->autocfg.line_outs)
15119 return 0; /* can't find valid BIOS pin config */
15121 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15124 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15127 err = alc861vd_auto_create_extra_out(spec,
15128 spec->autocfg.speaker_pins[0],
15132 err = alc861vd_auto_create_extra_out(spec,
15133 spec->autocfg.hp_pins[0],
15137 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15141 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15143 if (spec->autocfg.dig_outs)
15144 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15146 if (spec->kctls.list)
15147 add_mixer(spec, spec->kctls.list);
15149 add_verb(spec, alc861vd_volume_init_verbs);
15151 spec->num_mux_defs = 1;
15152 spec->input_mux = &spec->private_imux[0];
15154 err = alc_auto_add_mic_boost(codec);
15158 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15163 /* additional initialization for auto-configuration model */
15164 static void alc861vd_auto_init(struct hda_codec *codec)
15166 struct alc_spec *spec = codec->spec;
15167 alc861vd_auto_init_multi_out(codec);
15168 alc861vd_auto_init_hp_out(codec);
15169 alc861vd_auto_init_analog_input(codec);
15170 alc861vd_auto_init_input_src(codec);
15171 if (spec->unsol_event)
15172 alc_inithook(codec);
15175 static int patch_alc861vd(struct hda_codec *codec)
15177 struct alc_spec *spec;
15178 int err, board_config;
15180 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15184 codec->spec = spec;
15186 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15190 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15191 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
15192 "ALC861VD, trying auto-probe from BIOS...\n");
15193 board_config = ALC861VD_AUTO;
15196 if (board_config == ALC861VD_AUTO) {
15197 /* automatic parse from the BIOS config */
15198 err = alc861vd_parse_auto_config(codec);
15204 "hda_codec: Cannot set up configuration "
15205 "from BIOS. Using base mode...\n");
15206 board_config = ALC861VD_3ST;
15210 err = snd_hda_attach_beep_device(codec, 0x23);
15216 if (board_config != ALC861VD_AUTO)
15217 setup_preset(spec, &alc861vd_presets[board_config]);
15219 if (codec->vendor_id == 0x10ec0660) {
15220 spec->stream_name_analog = "ALC660-VD Analog";
15221 spec->stream_name_digital = "ALC660-VD Digital";
15222 /* always turn on EAPD */
15223 add_verb(spec, alc660vd_eapd_verbs);
15225 spec->stream_name_analog = "ALC861VD Analog";
15226 spec->stream_name_digital = "ALC861VD Digital";
15229 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15230 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15232 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15233 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15235 spec->adc_nids = alc861vd_adc_nids;
15236 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15237 spec->capsrc_nids = alc861vd_capsrc_nids;
15238 spec->capture_style = CAPT_MIX;
15240 set_capture_mixer(spec);
15241 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15243 spec->vmaster_nid = 0x02;
15245 codec->patch_ops = alc_patch_ops;
15247 if (board_config == ALC861VD_AUTO)
15248 spec->init_hook = alc861vd_auto_init;
15249 #ifdef CONFIG_SND_HDA_POWER_SAVE
15250 if (!spec->loopback.amplist)
15251 spec->loopback.amplist = alc861vd_loopbacks;
15253 codec->proc_widget_hook = print_realtek_coef;
15261 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15262 * configuration. Each pin widget can choose any input DACs and a mixer.
15263 * Each ADC is connected from a mixer of all inputs. This makes possible
15264 * 6-channel independent captures.
15266 * In addition, an independent DAC for the multi-playback (not used in this
15269 #define ALC662_DIGOUT_NID 0x06
15270 #define ALC662_DIGIN_NID 0x0a
15272 static hda_nid_t alc662_dac_nids[4] = {
15273 /* front, rear, clfe, rear_surr */
15277 static hda_nid_t alc272_dac_nids[2] = {
15281 static hda_nid_t alc662_adc_nids[1] = {
15286 static hda_nid_t alc272_adc_nids[1] = {
15291 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15292 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15296 /* FIXME: should be a matrix-type input source selection */
15297 static struct hda_input_mux alc662_capture_source = {
15301 { "Front Mic", 0x1 },
15307 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15315 static struct hda_input_mux alc662_eeepc_capture_source = {
15323 static struct hda_input_mux alc663_capture_source = {
15327 { "Front Mic", 0x1 },
15332 static struct hda_input_mux alc663_m51va_capture_source = {
15335 { "Ext-Mic", 0x0 },
15343 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15350 static struct hda_verb alc662_3ST_ch2_init[] = {
15351 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15352 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15353 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15354 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15361 static struct hda_verb alc662_3ST_ch6_init[] = {
15362 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15363 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15364 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15365 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15366 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15367 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15371 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15372 { 2, alc662_3ST_ch2_init },
15373 { 6, alc662_3ST_ch6_init },
15379 static struct hda_verb alc662_sixstack_ch6_init[] = {
15380 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15381 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15382 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15389 static struct hda_verb alc662_sixstack_ch8_init[] = {
15390 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15391 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15392 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15396 static struct hda_channel_mode alc662_5stack_modes[2] = {
15397 { 2, alc662_sixstack_ch6_init },
15398 { 6, alc662_sixstack_ch8_init },
15401 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15402 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15405 static struct snd_kcontrol_new alc662_base_mixer[] = {
15406 /* output mixer control */
15407 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15408 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15409 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15410 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15411 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15412 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15413 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15414 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15415 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15417 /*Input mixer control */
15418 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15419 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15420 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15421 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15422 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15423 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15424 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15425 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15429 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15430 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15431 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15432 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15433 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15434 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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),
15439 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15440 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15444 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15445 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15447 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15448 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15449 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15450 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15451 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15452 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15453 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15454 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15455 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15456 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15457 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15460 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15461 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15465 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15466 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15467 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15468 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15469 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15470 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15471 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15472 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15473 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15474 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15478 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15479 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15481 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15482 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15484 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15485 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15486 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15488 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15489 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15490 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15494 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15495 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15496 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15497 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15498 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15499 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15500 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15501 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15502 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
15503 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15504 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15505 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15506 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15512 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15513 .ops = &snd_hda_bind_vol,
15515 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15516 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15521 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15522 .ops = &snd_hda_bind_sw,
15524 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15525 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15530 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15531 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15532 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15538 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15539 .ops = &snd_hda_bind_sw,
15541 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15542 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15543 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15548 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15549 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15550 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15551 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15552 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15553 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15554 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15559 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15560 .ops = &snd_hda_bind_sw,
15562 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15563 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15564 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15569 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15570 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15571 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15572 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15574 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15575 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15579 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15581 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15582 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15583 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15584 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15585 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15586 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15590 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15591 .ops = &snd_hda_bind_vol,
15593 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15594 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15599 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15600 .ops = &snd_hda_bind_sw,
15602 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15603 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15608 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15609 HDA_BIND_VOL("Master Playback Volume",
15610 &alc663_asus_two_bind_master_vol),
15611 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15612 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15613 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15615 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15619 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15620 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15621 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15622 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15629 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15630 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15631 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15632 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15633 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15638 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15639 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15643 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15644 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15645 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15646 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15650 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15651 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15652 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15653 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15657 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15659 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15660 .name = "Channel Mode",
15661 .info = alc_ch_mode_info,
15662 .get = alc_ch_mode_get,
15663 .put = alc_ch_mode_put,
15668 static struct hda_verb alc662_init_verbs[] = {
15669 /* ADC: mute amp left and right */
15670 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15671 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15672 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15674 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15675 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15676 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15677 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15678 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15682 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15683 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15684 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15685 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15687 /* Front Pin: output 0 (0x0c) */
15688 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15689 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15691 /* Rear Pin: output 1 (0x0d) */
15692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15695 /* CLFE Pin: output 2 (0x0e) */
15696 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15697 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15699 /* Mic (rear) pin: input vref at 80% */
15700 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15701 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15702 /* Front Mic pin: input vref at 80% */
15703 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15705 /* Line In pin: input */
15706 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15708 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15711 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15712 /* CD pin widget for input */
15713 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15715 /* FIXME: use matrix-type input source selection */
15716 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15721 /* always trun on EAPD */
15722 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15723 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15728 static struct hda_verb alc662_sue_init_verbs[] = {
15729 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15730 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15734 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15735 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15736 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15740 /* Set Unsolicited Event*/
15741 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15742 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15743 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15748 * generic initialization of ADC, input mixers and output mixers
15750 static struct hda_verb alc662_auto_init_verbs[] = {
15752 * Unmute ADC and set the default input to mic-in
15754 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15757 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15759 * Note: PASD motherboards uses the Line In 2 as the input for front
15760 * panel mic (mic 2)
15762 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15763 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15764 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15765 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15770 * Set up output mixers (0x0c - 0x0f)
15772 /* set vol=0 to output mixers */
15773 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15774 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15775 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15777 /* set up input amps for analog loopback */
15778 /* Amp Indices: DAC = 0, mixer = 1 */
15779 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15781 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15782 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15787 /* FIXME: use matrix-type input source selection */
15788 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15791 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15795 /* additional verbs for ALC663 */
15796 static struct hda_verb alc663_auto_init_verbs[] = {
15797 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15798 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15802 static struct hda_verb alc663_m51va_init_verbs[] = {
15803 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15804 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15805 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15806 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15807 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15808 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15809 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15810 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15811 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15815 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
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, 0x01}, /* Headphone */
15819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
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 alc662_1bjd_amic_init_verbs[] = {
15827 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15828 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15829 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15830 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15831 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15832 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15833 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15834 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15838 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15839 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15840 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15841 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15842 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15843 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15844 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15845 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15849 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15850 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15851 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15852 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15853 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15859 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15860 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15865 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15866 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15867 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15868 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15869 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15872 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15875 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15876 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15877 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15881 static struct hda_verb alc663_g71v_init_verbs[] = {
15882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15883 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15884 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15886 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15887 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15888 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15890 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15891 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15892 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15896 static struct hda_verb alc663_g50v_init_verbs[] = {
15897 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15898 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15899 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15901 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15902 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15906 static struct hda_verb alc662_ecs_init_verbs[] = {
15907 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15908 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15909 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15910 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15914 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15915 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15916 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15917 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15918 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15919 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15920 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15921 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15924 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15925 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15929 static struct hda_verb alc272_dell_init_verbs[] = {
15930 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15931 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15933 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15934 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15935 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15936 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15937 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15938 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15939 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15940 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15944 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15945 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15946 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15950 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15951 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15952 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15956 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15958 unsigned int present;
15959 unsigned char bits;
15961 present = snd_hda_codec_read(codec, 0x14, 0,
15962 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15963 bits = present ? HDA_AMP_MUTE : 0;
15964 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15965 HDA_AMP_MUTE, bits);
15968 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15970 unsigned int present;
15971 unsigned char bits;
15973 present = snd_hda_codec_read(codec, 0x1b, 0,
15974 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15975 bits = present ? HDA_AMP_MUTE : 0;
15976 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15977 HDA_AMP_MUTE, bits);
15978 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15979 HDA_AMP_MUTE, bits);
15982 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15985 if ((res >> 26) == ALC880_HP_EVENT)
15986 alc662_lenovo_101e_all_automute(codec);
15987 if ((res >> 26) == ALC880_FRONT_EVENT)
15988 alc662_lenovo_101e_ispeaker_automute(codec);
15991 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15993 unsigned int present;
15995 present = snd_hda_codec_read(codec, 0x18, 0,
15996 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15997 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15998 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15999 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16000 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16001 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16002 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16003 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16004 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16007 /* unsolicited event for HP jack sensing */
16008 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16011 if ((res >> 26) == ALC880_HP_EVENT)
16012 alc262_hippo1_automute( codec );
16014 if ((res >> 26) == ALC880_MIC_EVENT)
16015 alc662_eeepc_mic_automute(codec);
16018 static void alc662_eeepc_inithook(struct hda_codec *codec)
16020 alc262_hippo1_automute( codec );
16021 alc662_eeepc_mic_automute(codec);
16024 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
16027 unsigned int present;
16029 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
16030 present = snd_hda_codec_read(codec, 0x14, 0,
16031 AC_VERB_GET_PIN_SENSE, 0);
16032 present = (present & 0x80000000) != 0;
16034 /* mute internal speaker */
16035 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
16036 HDA_AMP_MUTE, HDA_AMP_MUTE);
16038 /* unmute internal speaker if necessary */
16039 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
16040 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
16041 HDA_AMP_MUTE, mute);
16045 /* unsolicited event for HP jack sensing */
16046 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
16049 if ((res >> 26) == ALC880_HP_EVENT)
16050 alc662_eeepc_ep20_automute(codec);
16053 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16055 alc662_eeepc_ep20_automute(codec);
16058 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16060 unsigned int present;
16061 unsigned char bits;
16063 present = snd_hda_codec_read(codec, 0x21, 0,
16064 AC_VERB_GET_PIN_SENSE, 0)
16065 & AC_PINSENSE_PRESENCE;
16066 bits = present ? HDA_AMP_MUTE : 0;
16067 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16068 AMP_IN_MUTE(0), bits);
16069 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16070 AMP_IN_MUTE(0), bits);
16073 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16075 unsigned int present;
16076 unsigned char bits;
16078 present = snd_hda_codec_read(codec, 0x21, 0,
16079 AC_VERB_GET_PIN_SENSE, 0)
16080 & AC_PINSENSE_PRESENCE;
16081 bits = present ? HDA_AMP_MUTE : 0;
16082 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16083 AMP_IN_MUTE(0), bits);
16084 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16085 AMP_IN_MUTE(0), bits);
16086 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16087 AMP_IN_MUTE(0), bits);
16088 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16089 AMP_IN_MUTE(0), bits);
16092 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16094 unsigned int present;
16095 unsigned char bits;
16097 present = snd_hda_codec_read(codec, 0x15, 0,
16098 AC_VERB_GET_PIN_SENSE, 0)
16099 & AC_PINSENSE_PRESENCE;
16100 bits = present ? HDA_AMP_MUTE : 0;
16101 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16102 AMP_IN_MUTE(0), bits);
16103 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16104 AMP_IN_MUTE(0), bits);
16105 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16106 AMP_IN_MUTE(0), bits);
16107 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16108 AMP_IN_MUTE(0), bits);
16111 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16113 unsigned int present;
16114 unsigned char bits;
16116 present = snd_hda_codec_read(codec, 0x1b, 0,
16117 AC_VERB_GET_PIN_SENSE, 0)
16118 & AC_PINSENSE_PRESENCE;
16119 bits = present ? 0 : PIN_OUT;
16120 snd_hda_codec_write(codec, 0x14, 0,
16121 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16124 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16126 unsigned int present1, present2;
16128 present1 = snd_hda_codec_read(codec, 0x21, 0,
16129 AC_VERB_GET_PIN_SENSE, 0)
16130 & AC_PINSENSE_PRESENCE;
16131 present2 = snd_hda_codec_read(codec, 0x15, 0,
16132 AC_VERB_GET_PIN_SENSE, 0)
16133 & AC_PINSENSE_PRESENCE;
16135 if (present1 || present2) {
16136 snd_hda_codec_write_cache(codec, 0x14, 0,
16137 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16139 snd_hda_codec_write_cache(codec, 0x14, 0,
16140 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16144 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16146 unsigned int present1, present2;
16148 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16149 AC_VERB_GET_PIN_SENSE, 0)
16150 & AC_PINSENSE_PRESENCE;
16151 present2 = snd_hda_codec_read(codec, 0x15, 0,
16152 AC_VERB_GET_PIN_SENSE, 0)
16153 & AC_PINSENSE_PRESENCE;
16155 if (present1 || present2) {
16156 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16157 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16158 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16159 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16161 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16162 AMP_IN_MUTE(0), 0);
16163 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16164 AMP_IN_MUTE(0), 0);
16168 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16170 unsigned int present;
16172 present = snd_hda_codec_read(codec, 0x18, 0,
16173 AC_VERB_GET_PIN_SENSE, 0)
16174 & AC_PINSENSE_PRESENCE;
16175 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16176 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16177 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16178 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16179 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16180 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16181 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16182 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16185 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16188 switch (res >> 26) {
16189 case ALC880_HP_EVENT:
16190 alc663_m51va_speaker_automute(codec);
16192 case ALC880_MIC_EVENT:
16193 alc663_m51va_mic_automute(codec);
16198 static void alc663_m51va_inithook(struct hda_codec *codec)
16200 alc663_m51va_speaker_automute(codec);
16201 alc663_m51va_mic_automute(codec);
16204 /* ***************** Mode1 ******************************/
16205 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16208 switch (res >> 26) {
16209 case ALC880_HP_EVENT:
16210 alc663_m51va_speaker_automute(codec);
16212 case ALC880_MIC_EVENT:
16213 alc662_eeepc_mic_automute(codec);
16218 static void alc663_mode1_inithook(struct hda_codec *codec)
16220 alc663_m51va_speaker_automute(codec);
16221 alc662_eeepc_mic_automute(codec);
16223 /* ***************** Mode2 ******************************/
16224 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16227 switch (res >> 26) {
16228 case ALC880_HP_EVENT:
16229 alc662_f5z_speaker_automute(codec);
16231 case ALC880_MIC_EVENT:
16232 alc662_eeepc_mic_automute(codec);
16237 static void alc662_mode2_inithook(struct hda_codec *codec)
16239 alc662_f5z_speaker_automute(codec);
16240 alc662_eeepc_mic_automute(codec);
16242 /* ***************** Mode3 ******************************/
16243 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16246 switch (res >> 26) {
16247 case ALC880_HP_EVENT:
16248 alc663_two_hp_m1_speaker_automute(codec);
16250 case ALC880_MIC_EVENT:
16251 alc662_eeepc_mic_automute(codec);
16256 static void alc663_mode3_inithook(struct hda_codec *codec)
16258 alc663_two_hp_m1_speaker_automute(codec);
16259 alc662_eeepc_mic_automute(codec);
16261 /* ***************** Mode4 ******************************/
16262 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16265 switch (res >> 26) {
16266 case ALC880_HP_EVENT:
16267 alc663_21jd_two_speaker_automute(codec);
16269 case ALC880_MIC_EVENT:
16270 alc662_eeepc_mic_automute(codec);
16275 static void alc663_mode4_inithook(struct hda_codec *codec)
16277 alc663_21jd_two_speaker_automute(codec);
16278 alc662_eeepc_mic_automute(codec);
16280 /* ***************** Mode5 ******************************/
16281 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16284 switch (res >> 26) {
16285 case ALC880_HP_EVENT:
16286 alc663_15jd_two_speaker_automute(codec);
16288 case ALC880_MIC_EVENT:
16289 alc662_eeepc_mic_automute(codec);
16294 static void alc663_mode5_inithook(struct hda_codec *codec)
16296 alc663_15jd_two_speaker_automute(codec);
16297 alc662_eeepc_mic_automute(codec);
16299 /* ***************** Mode6 ******************************/
16300 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16303 switch (res >> 26) {
16304 case ALC880_HP_EVENT:
16305 alc663_two_hp_m2_speaker_automute(codec);
16307 case ALC880_MIC_EVENT:
16308 alc662_eeepc_mic_automute(codec);
16313 static void alc663_mode6_inithook(struct hda_codec *codec)
16315 alc663_two_hp_m2_speaker_automute(codec);
16316 alc662_eeepc_mic_automute(codec);
16319 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16321 unsigned int present;
16322 unsigned char bits;
16324 present = snd_hda_codec_read(codec, 0x21, 0,
16325 AC_VERB_GET_PIN_SENSE, 0)
16326 & AC_PINSENSE_PRESENCE;
16327 bits = present ? HDA_AMP_MUTE : 0;
16328 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16329 HDA_AMP_MUTE, bits);
16330 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16331 HDA_AMP_MUTE, bits);
16334 static void alc663_g71v_front_automute(struct hda_codec *codec)
16336 unsigned int present;
16337 unsigned char bits;
16339 present = snd_hda_codec_read(codec, 0x15, 0,
16340 AC_VERB_GET_PIN_SENSE, 0)
16341 & AC_PINSENSE_PRESENCE;
16342 bits = present ? HDA_AMP_MUTE : 0;
16343 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16344 HDA_AMP_MUTE, bits);
16347 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16350 switch (res >> 26) {
16351 case ALC880_HP_EVENT:
16352 alc663_g71v_hp_automute(codec);
16354 case ALC880_FRONT_EVENT:
16355 alc663_g71v_front_automute(codec);
16357 case ALC880_MIC_EVENT:
16358 alc662_eeepc_mic_automute(codec);
16363 static void alc663_g71v_inithook(struct hda_codec *codec)
16365 alc663_g71v_front_automute(codec);
16366 alc663_g71v_hp_automute(codec);
16367 alc662_eeepc_mic_automute(codec);
16370 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16373 switch (res >> 26) {
16374 case ALC880_HP_EVENT:
16375 alc663_m51va_speaker_automute(codec);
16377 case ALC880_MIC_EVENT:
16378 alc662_eeepc_mic_automute(codec);
16383 static void alc663_g50v_inithook(struct hda_codec *codec)
16385 alc663_m51va_speaker_automute(codec);
16386 alc662_eeepc_mic_automute(codec);
16389 /* bind hp and internal speaker mute (with plug check) */
16390 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16391 struct snd_ctl_elem_value *ucontrol)
16393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16394 long *valp = ucontrol->value.integer.value;
16397 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16399 valp[0] ? 0 : HDA_AMP_MUTE);
16400 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16402 valp[1] ? 0 : HDA_AMP_MUTE);
16404 alc262_hippo1_automute(codec);
16408 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16409 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16412 .name = "Master Playback Switch",
16413 .info = snd_hda_mixer_amp_switch_info,
16414 .get = snd_hda_mixer_amp_switch_get,
16415 .put = alc662_ecs_master_sw_put,
16416 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16419 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16420 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16421 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16423 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16424 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16425 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16429 #ifdef CONFIG_SND_HDA_POWER_SAVE
16430 #define alc662_loopbacks alc880_loopbacks
16434 /* pcm configuration: identiacal with ALC880 */
16435 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16436 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16437 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16438 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16441 * configuration and preset
16443 static const char *alc662_models[ALC662_MODEL_LAST] = {
16444 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16445 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16446 [ALC662_3ST_6ch] = "3stack-6ch",
16447 [ALC662_5ST_DIG] = "6stack-dig",
16448 [ALC662_LENOVO_101E] = "lenovo-101e",
16449 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16450 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16451 [ALC662_ECS] = "ecs",
16452 [ALC663_ASUS_M51VA] = "m51va",
16453 [ALC663_ASUS_G71V] = "g71v",
16454 [ALC663_ASUS_H13] = "h13",
16455 [ALC663_ASUS_G50V] = "g50v",
16456 [ALC663_ASUS_MODE1] = "asus-mode1",
16457 [ALC662_ASUS_MODE2] = "asus-mode2",
16458 [ALC663_ASUS_MODE3] = "asus-mode3",
16459 [ALC663_ASUS_MODE4] = "asus-mode4",
16460 [ALC663_ASUS_MODE5] = "asus-mode5",
16461 [ALC663_ASUS_MODE6] = "asus-mode6",
16462 [ALC662_AUTO] = "auto",
16465 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16466 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16467 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16468 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16469 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16470 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16471 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16472 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16473 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16474 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16475 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16476 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16477 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16478 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16479 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16480 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16481 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16482 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16483 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16484 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16485 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16486 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16487 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16488 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16489 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16490 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16491 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16492 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16493 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16494 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16495 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16496 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16497 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16498 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16499 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16500 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16501 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16502 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16503 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16504 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16505 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16506 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16507 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16508 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16509 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16510 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16511 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16512 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16513 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16514 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16515 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16516 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16517 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16518 ALC662_3ST_6ch_DIG),
16519 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16520 ALC662_3ST_6ch_DIG),
16521 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16522 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16523 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16524 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16525 ALC662_3ST_6ch_DIG),
16526 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16531 static struct alc_config_preset alc662_presets[] = {
16532 [ALC662_3ST_2ch_DIG] = {
16533 .mixers = { alc662_3ST_2ch_mixer },
16534 .init_verbs = { alc662_init_verbs },
16535 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16536 .dac_nids = alc662_dac_nids,
16537 .dig_out_nid = ALC662_DIGOUT_NID,
16538 .dig_in_nid = ALC662_DIGIN_NID,
16539 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16540 .channel_mode = alc662_3ST_2ch_modes,
16541 .input_mux = &alc662_capture_source,
16543 [ALC662_3ST_6ch_DIG] = {
16544 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16545 .init_verbs = { alc662_init_verbs },
16546 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16547 .dac_nids = alc662_dac_nids,
16548 .dig_out_nid = ALC662_DIGOUT_NID,
16549 .dig_in_nid = ALC662_DIGIN_NID,
16550 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16551 .channel_mode = alc662_3ST_6ch_modes,
16553 .input_mux = &alc662_capture_source,
16555 [ALC662_3ST_6ch] = {
16556 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16557 .init_verbs = { alc662_init_verbs },
16558 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16559 .dac_nids = alc662_dac_nids,
16560 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16561 .channel_mode = alc662_3ST_6ch_modes,
16563 .input_mux = &alc662_capture_source,
16565 [ALC662_5ST_DIG] = {
16566 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16567 .init_verbs = { alc662_init_verbs },
16568 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16569 .dac_nids = alc662_dac_nids,
16570 .dig_out_nid = ALC662_DIGOUT_NID,
16571 .dig_in_nid = ALC662_DIGIN_NID,
16572 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16573 .channel_mode = alc662_5stack_modes,
16574 .input_mux = &alc662_capture_source,
16576 [ALC662_LENOVO_101E] = {
16577 .mixers = { alc662_lenovo_101e_mixer },
16578 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16579 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16580 .dac_nids = alc662_dac_nids,
16581 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16582 .channel_mode = alc662_3ST_2ch_modes,
16583 .input_mux = &alc662_lenovo_101e_capture_source,
16584 .unsol_event = alc662_lenovo_101e_unsol_event,
16585 .init_hook = alc662_lenovo_101e_all_automute,
16587 [ALC662_ASUS_EEEPC_P701] = {
16588 .mixers = { alc662_eeepc_p701_mixer },
16589 .init_verbs = { alc662_init_verbs,
16590 alc662_eeepc_sue_init_verbs },
16591 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16592 .dac_nids = alc662_dac_nids,
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_eeepc_unsol_event,
16597 .init_hook = alc662_eeepc_inithook,
16599 [ALC662_ASUS_EEEPC_EP20] = {
16600 .mixers = { alc662_eeepc_ep20_mixer,
16601 alc662_chmode_mixer },
16602 .init_verbs = { alc662_init_verbs,
16603 alc662_eeepc_ep20_sue_init_verbs },
16604 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16605 .dac_nids = alc662_dac_nids,
16606 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16607 .channel_mode = alc662_3ST_6ch_modes,
16608 .input_mux = &alc662_lenovo_101e_capture_source,
16609 .unsol_event = alc662_eeepc_ep20_unsol_event,
16610 .init_hook = alc662_eeepc_ep20_inithook,
16613 .mixers = { alc662_ecs_mixer },
16614 .init_verbs = { alc662_init_verbs,
16615 alc662_ecs_init_verbs },
16616 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16617 .dac_nids = alc662_dac_nids,
16618 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16619 .channel_mode = alc662_3ST_2ch_modes,
16620 .input_mux = &alc662_eeepc_capture_source,
16621 .unsol_event = alc662_eeepc_unsol_event,
16622 .init_hook = alc662_eeepc_inithook,
16624 [ALC663_ASUS_M51VA] = {
16625 .mixers = { alc663_m51va_mixer },
16626 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16627 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16628 .dac_nids = alc662_dac_nids,
16629 .dig_out_nid = ALC662_DIGOUT_NID,
16630 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16631 .channel_mode = alc662_3ST_2ch_modes,
16632 .input_mux = &alc663_m51va_capture_source,
16633 .unsol_event = alc663_m51va_unsol_event,
16634 .init_hook = alc663_m51va_inithook,
16636 [ALC663_ASUS_G71V] = {
16637 .mixers = { alc663_g71v_mixer },
16638 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16639 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16640 .dac_nids = alc662_dac_nids,
16641 .dig_out_nid = ALC662_DIGOUT_NID,
16642 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16643 .channel_mode = alc662_3ST_2ch_modes,
16644 .input_mux = &alc662_eeepc_capture_source,
16645 .unsol_event = alc663_g71v_unsol_event,
16646 .init_hook = alc663_g71v_inithook,
16648 [ALC663_ASUS_H13] = {
16649 .mixers = { alc663_m51va_mixer },
16650 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16651 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16652 .dac_nids = alc662_dac_nids,
16653 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16654 .channel_mode = alc662_3ST_2ch_modes,
16655 .input_mux = &alc663_m51va_capture_source,
16656 .unsol_event = alc663_m51va_unsol_event,
16657 .init_hook = alc663_m51va_inithook,
16659 [ALC663_ASUS_G50V] = {
16660 .mixers = { alc663_g50v_mixer },
16661 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16662 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16663 .dac_nids = alc662_dac_nids,
16664 .dig_out_nid = ALC662_DIGOUT_NID,
16665 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16666 .channel_mode = alc662_3ST_6ch_modes,
16667 .input_mux = &alc663_capture_source,
16668 .unsol_event = alc663_g50v_unsol_event,
16669 .init_hook = alc663_g50v_inithook,
16671 [ALC663_ASUS_MODE1] = {
16672 .mixers = { alc663_m51va_mixer },
16673 .cap_mixer = alc662_auto_capture_mixer,
16674 .init_verbs = { alc662_init_verbs,
16675 alc663_21jd_amic_init_verbs },
16676 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16678 .dac_nids = alc662_dac_nids,
16679 .dig_out_nid = ALC662_DIGOUT_NID,
16680 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16681 .channel_mode = alc662_3ST_2ch_modes,
16682 .input_mux = &alc662_eeepc_capture_source,
16683 .unsol_event = alc663_mode1_unsol_event,
16684 .init_hook = alc663_mode1_inithook,
16686 [ALC662_ASUS_MODE2] = {
16687 .mixers = { alc662_1bjd_mixer },
16688 .cap_mixer = alc662_auto_capture_mixer,
16689 .init_verbs = { alc662_init_verbs,
16690 alc662_1bjd_amic_init_verbs },
16691 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16692 .dac_nids = alc662_dac_nids,
16693 .dig_out_nid = ALC662_DIGOUT_NID,
16694 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16695 .channel_mode = alc662_3ST_2ch_modes,
16696 .input_mux = &alc662_eeepc_capture_source,
16697 .unsol_event = alc662_mode2_unsol_event,
16698 .init_hook = alc662_mode2_inithook,
16700 [ALC663_ASUS_MODE3] = {
16701 .mixers = { alc663_two_hp_m1_mixer },
16702 .cap_mixer = alc662_auto_capture_mixer,
16703 .init_verbs = { alc662_init_verbs,
16704 alc663_two_hp_amic_m1_init_verbs },
16705 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16707 .dac_nids = alc662_dac_nids,
16708 .dig_out_nid = ALC662_DIGOUT_NID,
16709 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16710 .channel_mode = alc662_3ST_2ch_modes,
16711 .input_mux = &alc662_eeepc_capture_source,
16712 .unsol_event = alc663_mode3_unsol_event,
16713 .init_hook = alc663_mode3_inithook,
16715 [ALC663_ASUS_MODE4] = {
16716 .mixers = { alc663_asus_21jd_clfe_mixer },
16717 .cap_mixer = alc662_auto_capture_mixer,
16718 .init_verbs = { alc662_init_verbs,
16719 alc663_21jd_amic_init_verbs},
16720 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16722 .dac_nids = alc662_dac_nids,
16723 .dig_out_nid = ALC662_DIGOUT_NID,
16724 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16725 .channel_mode = alc662_3ST_2ch_modes,
16726 .input_mux = &alc662_eeepc_capture_source,
16727 .unsol_event = alc663_mode4_unsol_event,
16728 .init_hook = alc663_mode4_inithook,
16730 [ALC663_ASUS_MODE5] = {
16731 .mixers = { alc663_asus_15jd_clfe_mixer },
16732 .cap_mixer = alc662_auto_capture_mixer,
16733 .init_verbs = { alc662_init_verbs,
16734 alc663_15jd_amic_init_verbs },
16735 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16737 .dac_nids = alc662_dac_nids,
16738 .dig_out_nid = ALC662_DIGOUT_NID,
16739 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16740 .channel_mode = alc662_3ST_2ch_modes,
16741 .input_mux = &alc662_eeepc_capture_source,
16742 .unsol_event = alc663_mode5_unsol_event,
16743 .init_hook = alc663_mode5_inithook,
16745 [ALC663_ASUS_MODE6] = {
16746 .mixers = { alc663_two_hp_m2_mixer },
16747 .cap_mixer = alc662_auto_capture_mixer,
16748 .init_verbs = { alc662_init_verbs,
16749 alc663_two_hp_amic_m2_init_verbs },
16750 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16752 .dac_nids = alc662_dac_nids,
16753 .dig_out_nid = ALC662_DIGOUT_NID,
16754 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16755 .channel_mode = alc662_3ST_2ch_modes,
16756 .input_mux = &alc662_eeepc_capture_source,
16757 .unsol_event = alc663_mode6_unsol_event,
16758 .init_hook = alc663_mode6_inithook,
16761 .mixers = { alc663_m51va_mixer },
16762 .cap_mixer = alc272_auto_capture_mixer,
16763 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16764 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16765 .dac_nids = alc662_dac_nids,
16766 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16767 .adc_nids = alc272_adc_nids,
16768 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16769 .capsrc_nids = alc272_capsrc_nids,
16770 .channel_mode = alc662_3ST_2ch_modes,
16771 .input_mux = &alc663_m51va_capture_source,
16772 .unsol_event = alc663_m51va_unsol_event,
16773 .init_hook = alc663_m51va_inithook,
16775 [ALC272_DELL_ZM1] = {
16776 .mixers = { alc663_m51va_mixer },
16777 .cap_mixer = alc662_auto_capture_mixer,
16778 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16779 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16780 .dac_nids = alc662_dac_nids,
16781 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16782 .adc_nids = alc662_adc_nids,
16783 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16784 .capsrc_nids = alc662_capsrc_nids,
16785 .channel_mode = alc662_3ST_2ch_modes,
16786 .input_mux = &alc663_m51va_capture_source,
16787 .unsol_event = alc663_m51va_unsol_event,
16788 .init_hook = alc663_m51va_inithook,
16794 * BIOS auto configuration
16797 /* add playback controls from the parsed DAC table */
16798 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16799 const struct auto_pin_cfg *cfg)
16802 static const char *chname[4] = {
16803 "Front", "Surround", NULL /*CLFE*/, "Side"
16808 for (i = 0; i < cfg->line_outs; i++) {
16809 if (!spec->multiout.dac_nids[i])
16811 nid = alc880_idx_to_dac(i);
16814 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16815 "Center Playback Volume",
16816 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16820 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16821 "LFE Playback Volume",
16822 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16826 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16827 "Center Playback Switch",
16828 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16832 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16833 "LFE Playback Switch",
16834 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16839 sprintf(name, "%s Playback Volume", chname[i]);
16840 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16841 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16845 sprintf(name, "%s Playback Switch", chname[i]);
16846 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16847 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16856 /* add playback controls for speaker and HP outputs */
16857 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16868 /* ALC663 has a mono output pin on 0x17 */
16869 sprintf(name, "%s Playback Switch", pfx);
16870 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16871 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16875 if (alc880_is_fixed_pin(pin)) {
16876 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16877 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16878 /* specify the DAC as the extra output */
16879 if (!spec->multiout.hp_nid)
16880 spec->multiout.hp_nid = nid;
16882 spec->multiout.extra_out_nid[0] = nid;
16883 /* control HP volume/switch on the output mixer amp */
16884 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16885 sprintf(name, "%s Playback Volume", pfx);
16886 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16887 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16890 sprintf(name, "%s Playback Switch", pfx);
16891 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16892 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16895 } else if (alc880_is_multi_pin(pin)) {
16896 /* set manual connection */
16897 /* we have only a switch on HP-out PIN */
16898 sprintf(name, "%s Playback Switch", pfx);
16899 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16900 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16907 /* return the index of the src widget from the connection list of the nid.
16908 * return -1 if not found
16910 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16913 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16916 conns = snd_hda_get_connections(codec, nid, conn_list,
16917 ARRAY_SIZE(conn_list));
16920 for (i = 0; i < conns; i++)
16921 if (conn_list[i] == src)
16926 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16928 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16929 return (pincap & AC_PINCAP_IN) != 0;
16932 /* create playback/capture controls for input pins */
16933 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16934 const struct auto_pin_cfg *cfg)
16936 struct alc_spec *spec = codec->spec;
16937 struct hda_input_mux *imux = &spec->private_imux[0];
16940 for (i = 0; i < AUTO_PIN_LAST; i++) {
16941 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16942 idx = alc662_input_pin_idx(codec, 0x0b,
16943 cfg->input_pins[i]);
16945 err = new_analog_input(spec, cfg->input_pins[i],
16946 auto_pin_cfg_labels[i],
16951 idx = alc662_input_pin_idx(codec, 0x22,
16952 cfg->input_pins[i]);
16954 imux->items[imux->num_items].label =
16955 auto_pin_cfg_labels[i];
16956 imux->items[imux->num_items].index = idx;
16964 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16965 hda_nid_t nid, int pin_type,
16968 alc_set_pin_output(codec, nid, pin_type);
16969 /* need the manual connection? */
16970 if (alc880_is_multi_pin(nid)) {
16971 struct alc_spec *spec = codec->spec;
16972 int idx = alc880_multi_pin_idx(nid);
16973 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16974 AC_VERB_SET_CONNECT_SEL,
16975 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16979 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16981 struct alc_spec *spec = codec->spec;
16984 for (i = 0; i <= HDA_SIDE; i++) {
16985 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16986 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16988 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16993 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16995 struct alc_spec *spec = codec->spec;
16998 pin = spec->autocfg.hp_pins[0];
16999 if (pin) /* connect to front */
17001 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17002 pin = spec->autocfg.speaker_pins[0];
17004 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17007 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17009 static void alc662_auto_init_analog_input(struct hda_codec *codec)
17011 struct alc_spec *spec = codec->spec;
17014 for (i = 0; i < AUTO_PIN_LAST; i++) {
17015 hda_nid_t nid = spec->autocfg.input_pins[i];
17016 if (alc662_is_input_pin(codec, nid)) {
17017 alc_set_input_pin(codec, nid, i);
17018 if (nid != ALC662_PIN_CD_NID &&
17019 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17020 snd_hda_codec_write(codec, nid, 0,
17021 AC_VERB_SET_AMP_GAIN_MUTE,
17027 #define alc662_auto_init_input_src alc882_auto_init_input_src
17029 static int alc662_parse_auto_config(struct hda_codec *codec)
17031 struct alc_spec *spec = codec->spec;
17033 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17035 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17039 if (!spec->autocfg.line_outs)
17040 return 0; /* can't find valid BIOS pin config */
17042 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17045 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
17048 err = alc662_auto_create_extra_out(spec,
17049 spec->autocfg.speaker_pins[0],
17053 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17057 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
17061 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17063 if (spec->autocfg.dig_outs)
17064 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17066 if (spec->kctls.list)
17067 add_mixer(spec, spec->kctls.list);
17069 spec->num_mux_defs = 1;
17070 spec->input_mux = &spec->private_imux[0];
17072 add_verb(spec, alc662_auto_init_verbs);
17073 if (codec->vendor_id == 0x10ec0663)
17074 add_verb(spec, alc663_auto_init_verbs);
17076 err = alc_auto_add_mic_boost(codec);
17080 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17085 /* additional initialization for auto-configuration model */
17086 static void alc662_auto_init(struct hda_codec *codec)
17088 struct alc_spec *spec = codec->spec;
17089 alc662_auto_init_multi_out(codec);
17090 alc662_auto_init_hp_out(codec);
17091 alc662_auto_init_analog_input(codec);
17092 alc662_auto_init_input_src(codec);
17093 if (spec->unsol_event)
17094 alc_inithook(codec);
17097 static int patch_alc662(struct hda_codec *codec)
17099 struct alc_spec *spec;
17100 int err, board_config;
17102 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17106 codec->spec = spec;
17108 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17110 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17113 if (board_config < 0) {
17114 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
17115 "trying auto-probe from BIOS...\n");
17116 board_config = ALC662_AUTO;
17119 if (board_config == ALC662_AUTO) {
17120 /* automatic parse from the BIOS config */
17121 err = alc662_parse_auto_config(codec);
17127 "hda_codec: Cannot set up configuration "
17128 "from BIOS. Using base mode...\n");
17129 board_config = ALC662_3ST_2ch_DIG;
17133 err = snd_hda_attach_beep_device(codec, 0x1);
17139 if (board_config != ALC662_AUTO)
17140 setup_preset(spec, &alc662_presets[board_config]);
17142 if (codec->vendor_id == 0x10ec0663) {
17143 spec->stream_name_analog = "ALC663 Analog";
17144 spec->stream_name_digital = "ALC663 Digital";
17145 } else if (codec->vendor_id == 0x10ec0272) {
17146 spec->stream_name_analog = "ALC272 Analog";
17147 spec->stream_name_digital = "ALC272 Digital";
17149 spec->stream_name_analog = "ALC662 Analog";
17150 spec->stream_name_digital = "ALC662 Digital";
17153 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17154 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17156 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17157 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17159 spec->adc_nids = alc662_adc_nids;
17160 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17161 spec->capsrc_nids = alc662_capsrc_nids;
17162 spec->capture_style = CAPT_MIX;
17164 if (!spec->cap_mixer)
17165 set_capture_mixer(spec);
17166 if (codec->vendor_id == 0x10ec0662)
17167 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17169 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17171 spec->vmaster_nid = 0x02;
17173 codec->patch_ops = alc_patch_ops;
17174 if (board_config == ALC662_AUTO)
17175 spec->init_hook = alc662_auto_init;
17176 #ifdef CONFIG_SND_HDA_POWER_SAVE
17177 if (!spec->loopback.amplist)
17178 spec->loopback.amplist = alc662_loopbacks;
17180 codec->proc_widget_hook = print_realtek_coef;
17188 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17189 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17190 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17191 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17192 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17193 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17194 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17195 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17196 .patch = patch_alc861 },
17197 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17198 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17199 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17200 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17201 .patch = patch_alc883 },
17202 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17203 .patch = patch_alc662 },
17204 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17205 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17206 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17207 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17208 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17209 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17210 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17211 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17212 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17213 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17214 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17215 .patch = patch_alc883 },
17216 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17217 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17218 {} /* terminator */
17221 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17223 MODULE_LICENSE("GPL");
17224 MODULE_DESCRIPTION("Realtek HD-audio codec");
17226 static struct hda_codec_preset_list realtek_list = {
17227 .preset = snd_hda_preset_realtek,
17228 .owner = THIS_MODULE,
17231 static int __init patch_realtek_init(void)
17233 return snd_hda_add_codec_preset(&realtek_list);
17236 static void __exit patch_realtek_exit(void)
17238 snd_hda_delete_codec_preset(&realtek_list);
17241 module_init(patch_realtek_init)
17242 module_exit(patch_realtek_exit)