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,
221 ALC883_TARGA_2ch_DIG,
224 ALC888_ACER_ASPIRE_4930G,
228 ALC883_LENOVO_101E_2ch,
229 ALC883_LENOVO_NB0763,
230 ALC888_LENOVO_MS7195_DIG,
237 ALC883_FUJITSU_PI2515,
238 ALC888_FUJITSU_XA3530,
239 ALC883_3ST_6ch_INTEL,
247 /* styles of capture selection */
249 CAPT_MUX = 0, /* only mux based */
250 CAPT_MIX, /* only mixer based */
251 CAPT_1MUX_MIX, /* first mux and other mixers */
255 #define GPIO_MASK 0x03
257 /* extra amp-initialization sequence types */
267 /* codec parameterization */
268 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
269 unsigned int num_mixers;
270 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
271 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
273 const struct hda_verb *init_verbs[5]; /* initialization verbs
277 unsigned int num_init_verbs;
279 char *stream_name_analog; /* analog PCM stream */
280 struct hda_pcm_stream *stream_analog_playback;
281 struct hda_pcm_stream *stream_analog_capture;
282 struct hda_pcm_stream *stream_analog_alt_playback;
283 struct hda_pcm_stream *stream_analog_alt_capture;
285 char *stream_name_digital; /* digital PCM stream */
286 struct hda_pcm_stream *stream_digital_playback;
287 struct hda_pcm_stream *stream_digital_capture;
290 struct hda_multi_out multiout; /* playback set-up
291 * max_channels, dacs must be set
292 * dig_out_nid and hp_nid are optional
294 hda_nid_t alt_dac_nid;
295 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
299 unsigned int num_adc_nids;
301 hda_nid_t *capsrc_nids;
302 hda_nid_t dig_in_nid; /* digital-in NID; optional */
303 int capture_style; /* capture style (CAPT_*) */
306 unsigned int num_mux_defs;
307 const struct hda_input_mux *input_mux;
308 unsigned int cur_mux[3];
311 const struct hda_channel_mode *channel_mode;
312 int num_channel_mode;
315 /* PCM information */
316 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
318 /* dynamic controls, init_verbs and input_mux */
319 struct auto_pin_cfg autocfg;
320 struct snd_array kctls;
321 struct hda_input_mux private_imux[3];
322 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
325 void (*init_hook)(struct hda_codec *codec);
326 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
328 /* for pin sensing */
329 unsigned int sense_updated: 1;
330 unsigned int jack_present: 1;
331 unsigned int master_sw: 1;
334 unsigned int no_analog :1; /* digital I/O only */
337 /* for virtual master */
338 hda_nid_t vmaster_nid;
339 #ifdef CONFIG_SND_HDA_POWER_SAVE
340 struct hda_loopback_check loopback;
345 unsigned int pll_coef_idx, pll_coef_bit;
349 * configuration template - to be copied to the spec instance
351 struct alc_config_preset {
352 struct snd_kcontrol_new *mixers[5]; /* should be identical size
355 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
356 const struct hda_verb *init_verbs[5];
357 unsigned int num_dacs;
359 hda_nid_t dig_out_nid; /* optional */
360 hda_nid_t hp_nid; /* optional */
361 hda_nid_t *slave_dig_outs;
362 unsigned int num_adc_nids;
364 hda_nid_t *capsrc_nids;
365 hda_nid_t dig_in_nid;
366 unsigned int num_channel_mode;
367 const struct hda_channel_mode *channel_mode;
369 unsigned int num_mux_defs;
370 const struct hda_input_mux *input_mux;
371 void (*unsol_event)(struct hda_codec *, unsigned int);
372 void (*init_hook)(struct hda_codec *);
373 #ifdef CONFIG_SND_HDA_POWER_SAVE
374 struct hda_amp_list *loopbacks;
382 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_info *uinfo)
385 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386 struct alc_spec *spec = codec->spec;
387 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
388 if (mux_idx >= spec->num_mux_defs)
390 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
393 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
396 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct alc_spec *spec = codec->spec;
398 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
400 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
404 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
405 struct snd_ctl_elem_value *ucontrol)
407 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
408 struct alc_spec *spec = codec->spec;
409 const struct hda_input_mux *imux;
410 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
411 unsigned int mux_idx;
412 hda_nid_t nid = spec->capsrc_nids ?
413 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
415 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
416 imux = &spec->input_mux[mux_idx];
418 if (spec->capture_style &&
419 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
420 /* Matrix-mixer style (e.g. ALC882) */
421 unsigned int *cur_val = &spec->cur_mux[adc_idx];
424 idx = ucontrol->value.enumerated.item[0];
425 if (idx >= imux->num_items)
426 idx = imux->num_items - 1;
429 for (i = 0; i < imux->num_items; i++) {
430 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
431 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
432 imux->items[i].index,
438 /* MUX style (e.g. ALC880) */
439 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
440 &spec->cur_mux[adc_idx]);
445 * channel mode setting
447 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_info *uinfo)
450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct alc_spec *spec = codec->spec;
452 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
453 spec->num_channel_mode);
456 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
457 struct snd_ctl_elem_value *ucontrol)
459 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
460 struct alc_spec *spec = codec->spec;
461 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
462 spec->num_channel_mode,
463 spec->multiout.max_channels);
466 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
467 struct snd_ctl_elem_value *ucontrol)
469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
470 struct alc_spec *spec = codec->spec;
471 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
472 spec->num_channel_mode,
473 &spec->multiout.max_channels);
474 if (err >= 0 && spec->need_dac_fix)
475 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
480 * Control the mode of pin widget settings via the mixer. "pc" is used
481 * instead of "%" to avoid consequences of accidently treating the % as
482 * being part of a format specifier. Maximum allowed length of a value is
483 * 63 characters plus NULL terminator.
485 * Note: some retasking pin complexes seem to ignore requests for input
486 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
487 * are requested. Therefore order this list so that this behaviour will not
488 * cause problems when mixer clients move through the enum sequentially.
489 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
492 static char *alc_pin_mode_names[] = {
493 "Mic 50pc bias", "Mic 80pc bias",
494 "Line in", "Line out", "Headphone out",
496 static unsigned char alc_pin_mode_values[] = {
497 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
499 /* The control can present all 5 options, or it can limit the options based
500 * in the pin being assumed to be exclusively an input or an output pin. In
501 * addition, "input" pins may or may not process the mic bias option
502 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
503 * accept requests for bias as of chip versions up to March 2006) and/or
504 * wiring in the computer.
506 #define ALC_PIN_DIR_IN 0x00
507 #define ALC_PIN_DIR_OUT 0x01
508 #define ALC_PIN_DIR_INOUT 0x02
509 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
510 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
512 /* Info about the pin modes supported by the different pin direction modes.
513 * For each direction the minimum and maximum values are given.
515 static signed char alc_pin_mode_dir_info[5][2] = {
516 { 0, 2 }, /* ALC_PIN_DIR_IN */
517 { 3, 4 }, /* ALC_PIN_DIR_OUT */
518 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
519 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
520 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
522 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
523 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
524 #define alc_pin_mode_n_items(_dir) \
525 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
527 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
528 struct snd_ctl_elem_info *uinfo)
530 unsigned int item_num = uinfo->value.enumerated.item;
531 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
533 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
535 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
537 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
538 item_num = alc_pin_mode_min(dir);
539 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
543 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol)
547 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548 hda_nid_t nid = kcontrol->private_value & 0xffff;
549 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
550 long *valp = ucontrol->value.integer.value;
551 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
552 AC_VERB_GET_PIN_WIDGET_CONTROL,
555 /* Find enumerated value for current pinctl setting */
556 i = alc_pin_mode_min(dir);
557 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
559 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
563 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
564 struct snd_ctl_elem_value *ucontrol)
567 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
568 hda_nid_t nid = kcontrol->private_value & 0xffff;
569 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
570 long val = *ucontrol->value.integer.value;
571 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
572 AC_VERB_GET_PIN_WIDGET_CONTROL,
575 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
576 val = alc_pin_mode_min(dir);
578 change = pinctl != alc_pin_mode_values[val];
580 /* Set pin mode to that requested */
581 snd_hda_codec_write_cache(codec, nid, 0,
582 AC_VERB_SET_PIN_WIDGET_CONTROL,
583 alc_pin_mode_values[val]);
585 /* Also enable the retasking pin's input/output as required
586 * for the requested pin mode. Enum values of 2 or less are
589 * Dynamically switching the input/output buffers probably
590 * reduces noise slightly (particularly on input) so we'll
591 * do it. However, having both input and output buffers
592 * enabled simultaneously doesn't seem to be problematic if
593 * this turns out to be necessary in the future.
596 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
597 HDA_AMP_MUTE, HDA_AMP_MUTE);
598 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
601 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
602 HDA_AMP_MUTE, HDA_AMP_MUTE);
603 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
610 #define ALC_PIN_MODE(xname, nid, dir) \
611 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
612 .info = alc_pin_mode_info, \
613 .get = alc_pin_mode_get, \
614 .put = alc_pin_mode_put, \
615 .private_value = nid | (dir<<16) }
617 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
618 * together using a mask with more than one bit set. This control is
619 * currently used only by the ALC260 test model. At this stage they are not
620 * needed for any "production" models.
622 #ifdef CONFIG_SND_DEBUG
623 #define alc_gpio_data_info snd_ctl_boolean_mono_info
625 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
626 struct snd_ctl_elem_value *ucontrol)
628 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
629 hda_nid_t nid = kcontrol->private_value & 0xffff;
630 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
631 long *valp = ucontrol->value.integer.value;
632 unsigned int val = snd_hda_codec_read(codec, nid, 0,
633 AC_VERB_GET_GPIO_DATA, 0x00);
635 *valp = (val & mask) != 0;
638 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
639 struct snd_ctl_elem_value *ucontrol)
642 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
643 hda_nid_t nid = kcontrol->private_value & 0xffff;
644 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
645 long val = *ucontrol->value.integer.value;
646 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
647 AC_VERB_GET_GPIO_DATA,
650 /* Set/unset the masked GPIO bit(s) as needed */
651 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
656 snd_hda_codec_write_cache(codec, nid, 0,
657 AC_VERB_SET_GPIO_DATA, gpio_data);
661 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
662 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
663 .info = alc_gpio_data_info, \
664 .get = alc_gpio_data_get, \
665 .put = alc_gpio_data_put, \
666 .private_value = nid | (mask<<16) }
667 #endif /* CONFIG_SND_DEBUG */
669 /* A switch control to allow the enabling of the digital IO pins on the
670 * ALC260. This is incredibly simplistic; the intention of this control is
671 * to provide something in the test model allowing digital outputs to be
672 * identified if present. If models are found which can utilise these
673 * outputs a more complete mixer control can be devised for those models if
676 #ifdef CONFIG_SND_DEBUG
677 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
679 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
680 struct snd_ctl_elem_value *ucontrol)
682 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
683 hda_nid_t nid = kcontrol->private_value & 0xffff;
684 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
685 long *valp = ucontrol->value.integer.value;
686 unsigned int val = snd_hda_codec_read(codec, nid, 0,
687 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
689 *valp = (val & mask) != 0;
692 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
693 struct snd_ctl_elem_value *ucontrol)
696 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
697 hda_nid_t nid = kcontrol->private_value & 0xffff;
698 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
699 long val = *ucontrol->value.integer.value;
700 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
701 AC_VERB_GET_DIGI_CONVERT_1,
704 /* Set/unset the masked control bit(s) as needed */
705 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
710 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
715 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
716 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
717 .info = alc_spdif_ctrl_info, \
718 .get = alc_spdif_ctrl_get, \
719 .put = alc_spdif_ctrl_put, \
720 .private_value = nid | (mask<<16) }
721 #endif /* CONFIG_SND_DEBUG */
723 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
724 * Again, this is only used in the ALC26x test models to help identify when
725 * the EAPD line must be asserted for features to work.
727 #ifdef CONFIG_SND_DEBUG
728 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
730 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
731 struct snd_ctl_elem_value *ucontrol)
733 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
734 hda_nid_t nid = kcontrol->private_value & 0xffff;
735 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
736 long *valp = ucontrol->value.integer.value;
737 unsigned int val = snd_hda_codec_read(codec, nid, 0,
738 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
740 *valp = (val & mask) != 0;
744 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
745 struct snd_ctl_elem_value *ucontrol)
748 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
749 hda_nid_t nid = kcontrol->private_value & 0xffff;
750 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
751 long val = *ucontrol->value.integer.value;
752 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
753 AC_VERB_GET_EAPD_BTLENABLE,
756 /* Set/unset the masked control bit(s) as needed */
757 change = (!val ? 0 : mask) != (ctrl_data & mask);
762 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
768 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
769 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
770 .info = alc_eapd_ctrl_info, \
771 .get = alc_eapd_ctrl_get, \
772 .put = alc_eapd_ctrl_put, \
773 .private_value = nid | (mask<<16) }
774 #endif /* CONFIG_SND_DEBUG */
777 * set up the input pin config (depending on the given auto-pin type)
779 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
782 unsigned int val = PIN_IN;
784 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
786 pincap = snd_hda_query_pin_caps(codec, nid);
787 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
788 if (pincap & AC_PINCAP_VREF_80)
791 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
796 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
798 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
800 spec->mixers[spec->num_mixers++] = mix;
803 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
805 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
807 spec->init_verbs[spec->num_init_verbs++] = verb;
810 #ifdef CONFIG_PROC_FS
814 static void print_realtek_coef(struct snd_info_buffer *buffer,
815 struct hda_codec *codec, hda_nid_t nid)
821 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
822 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
823 coeff = snd_hda_codec_read(codec, nid, 0,
824 AC_VERB_GET_COEF_INDEX, 0);
825 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
828 #define print_realtek_coef NULL
832 * set up from the preset table
834 static void setup_preset(struct alc_spec *spec,
835 const struct alc_config_preset *preset)
839 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
840 add_mixer(spec, preset->mixers[i]);
841 spec->cap_mixer = preset->cap_mixer;
842 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
844 add_verb(spec, preset->init_verbs[i]);
846 spec->channel_mode = preset->channel_mode;
847 spec->num_channel_mode = preset->num_channel_mode;
848 spec->need_dac_fix = preset->need_dac_fix;
850 spec->multiout.max_channels = spec->channel_mode[0].channels;
852 spec->multiout.num_dacs = preset->num_dacs;
853 spec->multiout.dac_nids = preset->dac_nids;
854 spec->multiout.dig_out_nid = preset->dig_out_nid;
855 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
856 spec->multiout.hp_nid = preset->hp_nid;
858 spec->num_mux_defs = preset->num_mux_defs;
859 if (!spec->num_mux_defs)
860 spec->num_mux_defs = 1;
861 spec->input_mux = preset->input_mux;
863 spec->num_adc_nids = preset->num_adc_nids;
864 spec->adc_nids = preset->adc_nids;
865 spec->capsrc_nids = preset->capsrc_nids;
866 spec->dig_in_nid = preset->dig_in_nid;
868 spec->unsol_event = preset->unsol_event;
869 spec->init_hook = preset->init_hook;
870 #ifdef CONFIG_SND_HDA_POWER_SAVE
871 spec->loopback.amplist = preset->loopbacks;
875 /* Enable GPIO mask and set output */
876 static struct hda_verb alc_gpio1_init_verbs[] = {
877 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
878 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
879 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
883 static struct hda_verb alc_gpio2_init_verbs[] = {
884 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
885 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
886 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
890 static struct hda_verb alc_gpio3_init_verbs[] = {
891 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
892 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
893 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
898 * Fix hardware PLL issue
899 * On some codecs, the analog PLL gating control must be off while
900 * the default value is 1.
902 static void alc_fix_pll(struct hda_codec *codec)
904 struct alc_spec *spec = codec->spec;
909 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
911 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
912 AC_VERB_GET_PROC_COEF, 0);
913 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
915 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
916 val & ~(1 << spec->pll_coef_bit));
919 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
920 unsigned int coef_idx, unsigned int coef_bit)
922 struct alc_spec *spec = codec->spec;
924 spec->pll_coef_idx = coef_idx;
925 spec->pll_coef_bit = coef_bit;
929 static void alc_automute_pin(struct hda_codec *codec)
931 struct alc_spec *spec = codec->spec;
932 unsigned int present;
933 unsigned int nid = spec->autocfg.hp_pins[0];
936 /* need to execute and sync at first */
937 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
938 present = snd_hda_codec_read(codec, nid, 0,
939 AC_VERB_GET_PIN_SENSE, 0);
940 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
941 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
942 nid = spec->autocfg.speaker_pins[i];
945 snd_hda_codec_write(codec, nid, 0,
946 AC_VERB_SET_PIN_WIDGET_CONTROL,
947 spec->jack_present ? 0 : PIN_OUT);
951 #if 0 /* it's broken in some acses -- temporarily disabled */
952 static void alc_mic_automute(struct hda_codec *codec)
954 struct alc_spec *spec = codec->spec;
955 unsigned int present;
956 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
957 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
958 unsigned int mix_nid = spec->capsrc_nids[0];
959 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
961 capsrc_idx_mic = mic_nid - 0x18;
962 capsrc_idx_fmic = fmic_nid - 0x18;
963 present = snd_hda_codec_read(codec, mic_nid, 0,
964 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
965 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
966 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
967 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
968 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
969 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
970 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
973 #define alc_mic_automute(codec) do {} while(0) /* NOP */
974 #endif /* disabled */
976 /* unsolicited event for HP jack sensing */
977 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
979 if (codec->vendor_id == 0x10ec0880)
984 case ALC880_HP_EVENT:
985 alc_automute_pin(codec);
987 case ALC880_MIC_EVENT:
988 alc_mic_automute(codec);
993 static void alc_inithook(struct hda_codec *codec)
995 alc_automute_pin(codec);
996 alc_mic_automute(codec);
999 /* additional initialization for ALC888 variants */
1000 static void alc888_coef_init(struct hda_codec *codec)
1004 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1005 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1006 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1007 if ((tmp & 0xf0) == 0x20)
1009 snd_hda_codec_read(codec, 0x20, 0,
1010 AC_VERB_SET_PROC_COEF, 0x830);
1013 snd_hda_codec_read(codec, 0x20, 0,
1014 AC_VERB_SET_PROC_COEF, 0x3030);
1017 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1022 case ALC_INIT_GPIO1:
1023 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1025 case ALC_INIT_GPIO2:
1026 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1028 case ALC_INIT_GPIO3:
1029 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1031 case ALC_INIT_DEFAULT:
1032 switch (codec->vendor_id) {
1034 snd_hda_codec_write(codec, 0x0f, 0,
1035 AC_VERB_SET_EAPD_BTLENABLE, 2);
1036 snd_hda_codec_write(codec, 0x10, 0,
1037 AC_VERB_SET_EAPD_BTLENABLE, 2);
1049 snd_hda_codec_write(codec, 0x14, 0,
1050 AC_VERB_SET_EAPD_BTLENABLE, 2);
1051 snd_hda_codec_write(codec, 0x15, 0,
1052 AC_VERB_SET_EAPD_BTLENABLE, 2);
1055 switch (codec->vendor_id) {
1057 snd_hda_codec_write(codec, 0x1a, 0,
1058 AC_VERB_SET_COEF_INDEX, 7);
1059 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1060 AC_VERB_GET_PROC_COEF, 0);
1061 snd_hda_codec_write(codec, 0x1a, 0,
1062 AC_VERB_SET_COEF_INDEX, 7);
1063 snd_hda_codec_write(codec, 0x1a, 0,
1064 AC_VERB_SET_PROC_COEF,
1074 snd_hda_codec_write(codec, 0x20, 0,
1075 AC_VERB_SET_COEF_INDEX, 7);
1076 tmp = snd_hda_codec_read(codec, 0x20, 0,
1077 AC_VERB_GET_PROC_COEF, 0);
1078 snd_hda_codec_write(codec, 0x20, 0,
1079 AC_VERB_SET_COEF_INDEX, 7);
1080 snd_hda_codec_write(codec, 0x20, 0,
1081 AC_VERB_SET_PROC_COEF,
1085 alc888_coef_init(codec);
1089 snd_hda_codec_write(codec, 0x20, 0,
1090 AC_VERB_SET_COEF_INDEX, 7);
1091 tmp = snd_hda_codec_read(codec, 0x20, 0,
1092 AC_VERB_GET_PROC_COEF, 0);
1093 snd_hda_codec_write(codec, 0x20, 0,
1094 AC_VERB_SET_COEF_INDEX, 7);
1095 snd_hda_codec_write(codec, 0x20, 0,
1096 AC_VERB_SET_PROC_COEF,
1104 static void alc_init_auto_hp(struct hda_codec *codec)
1106 struct alc_spec *spec = codec->spec;
1108 if (!spec->autocfg.hp_pins[0])
1111 if (!spec->autocfg.speaker_pins[0]) {
1112 if (spec->autocfg.line_out_pins[0] &&
1113 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1114 spec->autocfg.speaker_pins[0] =
1115 spec->autocfg.line_out_pins[0];
1120 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1121 spec->autocfg.hp_pins[0]);
1122 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1123 AC_VERB_SET_UNSOLICITED_ENABLE,
1124 AC_USRSP_EN | ALC880_HP_EVENT);
1125 spec->unsol_event = alc_sku_unsol_event;
1128 /* check subsystem ID and set up device-specific initialization;
1129 * return 1 if initialized, 0 if invalid SSID
1131 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1132 * 31 ~ 16 : Manufacture ID
1134 * 7 ~ 0 : Assembly ID
1135 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1137 static int alc_subsystem_id(struct hda_codec *codec,
1138 hda_nid_t porta, hda_nid_t porte,
1141 unsigned int ass, tmp, i;
1143 struct alc_spec *spec = codec->spec;
1145 ass = codec->subsystem_id & 0xffff;
1146 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1149 /* invalid SSID, check the special NID pin defcfg instead */
1151 * 31~30 : port conetcivity
1154 * 19~16 : Check sum (15:1)
1159 if (codec->vendor_id == 0x10ec0260)
1161 ass = snd_hda_codec_get_pincfg(codec, nid);
1162 snd_printd("realtek: No valid SSID, "
1163 "checking pincfg 0x%08x for NID 0x%x\n",
1165 if (!(ass & 1) && !(ass & 0x100000))
1167 if ((ass >> 30) != 1) /* no physical connection */
1172 for (i = 1; i < 16; i++) {
1176 if (((ass >> 16) & 0xf) != tmp)
1179 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1180 ass & 0xffff, codec->vendor_id);
1184 * 2 : 0 --> Desktop, 1 --> Laptop
1185 * 3~5 : External Amplifier control
1188 tmp = (ass & 0x38) >> 3; /* external Amp control */
1191 spec->init_amp = ALC_INIT_GPIO1;
1194 spec->init_amp = ALC_INIT_GPIO2;
1197 spec->init_amp = ALC_INIT_GPIO3;
1200 spec->init_amp = ALC_INIT_DEFAULT;
1204 /* is laptop or Desktop and enable the function "Mute internal speaker
1205 * when the external headphone out jack is plugged"
1207 if (!(ass & 0x8000))
1210 * 10~8 : Jack location
1211 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1213 * 15 : 1 --> enable the function "Mute internal speaker
1214 * when the external headphone out jack is plugged"
1216 if (!spec->autocfg.hp_pins[0]) {
1217 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1219 spec->autocfg.hp_pins[0] = porta;
1221 spec->autocfg.hp_pins[0] = porte;
1223 spec->autocfg.hp_pins[0] = portd;
1228 alc_init_auto_hp(codec);
1232 static void alc_ssid_check(struct hda_codec *codec,
1233 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1235 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1236 struct alc_spec *spec = codec->spec;
1237 snd_printd("realtek: "
1238 "Enable default setup for auto mode as fallback\n");
1239 spec->init_amp = ALC_INIT_DEFAULT;
1240 alc_init_auto_hp(codec);
1245 * Fix-up pin default configurations
1253 static void alc_fix_pincfg(struct hda_codec *codec,
1254 const struct snd_pci_quirk *quirk,
1255 const struct alc_pincfg **pinfix)
1257 const struct alc_pincfg *cfg;
1259 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1263 cfg = pinfix[quirk->value];
1264 for (; cfg->nid; cfg++)
1265 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1275 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1276 /* Mic-in jack as mic in */
1277 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1278 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1279 /* Line-in jack as Line in */
1280 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1281 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1282 /* Line-Out as Front */
1283 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1290 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1291 /* Mic-in jack as mic in */
1292 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1293 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1294 /* Line-in jack as Surround */
1295 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1296 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1297 /* Line-Out as Front */
1298 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1305 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1306 /* Mic-in jack as CLFE */
1307 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1308 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1309 /* Line-in jack as Surround */
1310 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1311 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1312 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1313 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1320 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1321 /* Mic-in jack as CLFE */
1322 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1323 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1324 /* Line-in jack as Surround */
1325 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1326 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1327 /* Line-Out as Side */
1328 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1332 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1333 { 2, alc888_4ST_ch2_intel_init },
1334 { 4, alc888_4ST_ch4_intel_init },
1335 { 6, alc888_4ST_ch6_intel_init },
1336 { 8, alc888_4ST_ch8_intel_init },
1340 * ALC888 Fujitsu Siemens Amillo xa3530
1343 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1344 /* Front Mic: set to PIN_IN (empty by default) */
1345 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1346 /* Connect Internal HP to Front */
1347 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1348 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1349 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1350 /* Connect Bass HP to Front */
1351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1352 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1353 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1354 /* Connect Line-Out side jack (SPDIF) to Side */
1355 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1356 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1357 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1358 /* Connect Mic jack to CLFE */
1359 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1360 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1361 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1362 /* Connect Line-in jack to Surround */
1363 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1364 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1365 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1366 /* Connect HP out jack to Front */
1367 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1368 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1370 /* Enable unsolicited event for HP jack and Line-out jack */
1371 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1372 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1376 static void alc_automute_amp(struct hda_codec *codec)
1378 struct alc_spec *spec = codec->spec;
1379 unsigned int val, mute;
1383 spec->jack_present = 0;
1384 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1385 nid = spec->autocfg.hp_pins[i];
1388 val = snd_hda_codec_read(codec, nid, 0,
1389 AC_VERB_GET_PIN_SENSE, 0);
1390 if (val & AC_PINSENSE_PRESENCE) {
1391 spec->jack_present = 1;
1396 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1397 /* Toggle internal speakers muting */
1398 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1399 nid = spec->autocfg.speaker_pins[i];
1402 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1403 HDA_AMP_MUTE, mute);
1407 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1410 if (codec->vendor_id == 0x10ec0880)
1414 if (res == ALC880_HP_EVENT)
1415 alc_automute_amp(codec);
1418 static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1420 struct alc_spec *spec = codec->spec;
1422 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1423 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1424 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1425 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1426 alc_automute_amp(codec);
1430 * ALC888 Acer Aspire 4930G model
1433 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1434 /* Front Mic: set to PIN_IN (empty by default) */
1435 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1436 /* Unselect Front Mic by default in input mixer 3 */
1437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1438 /* Enable unsolicited event for HP jack */
1439 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1440 /* Connect Internal HP to front */
1441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1442 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1443 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1444 /* Connect HP out to front */
1445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1447 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1451 static struct hda_input_mux alc888_2_capture_sources[2] = {
1452 /* Front mic only available on one ADC */
1459 { "Front Mic", 0xb },
1472 static struct snd_kcontrol_new alc888_base_mixer[] = {
1473 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1474 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1475 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1476 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1477 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1479 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1480 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1481 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1482 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1483 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1484 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1485 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1486 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1487 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1489 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1490 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1494 static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1496 struct alc_spec *spec = codec->spec;
1498 spec->autocfg.hp_pins[0] = 0x15;
1499 spec->autocfg.speaker_pins[0] = 0x14;
1500 alc_automute_amp(codec);
1504 * ALC880 3-stack model
1506 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1507 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1508 * F-Mic = 0x1b, HP = 0x19
1511 static hda_nid_t alc880_dac_nids[4] = {
1512 /* front, rear, clfe, rear_surr */
1513 0x02, 0x05, 0x04, 0x03
1516 static hda_nid_t alc880_adc_nids[3] = {
1521 /* The datasheet says the node 0x07 is connected from inputs,
1522 * but it shows zero connection in the real implementation on some devices.
1523 * Note: this is a 915GAV bug, fixed on 915GLV
1525 static hda_nid_t alc880_adc_nids_alt[2] = {
1530 #define ALC880_DIGOUT_NID 0x06
1531 #define ALC880_DIGIN_NID 0x0a
1533 static struct hda_input_mux alc880_capture_source = {
1537 { "Front Mic", 0x3 },
1543 /* channel source setting (2/6 channel selection for 3-stack) */
1545 static struct hda_verb alc880_threestack_ch2_init[] = {
1546 /* set line-in to input, mute it */
1547 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1548 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1549 /* set mic-in to input vref 80%, mute it */
1550 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1551 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1556 static struct hda_verb alc880_threestack_ch6_init[] = {
1557 /* set line-in to output, unmute it */
1558 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1559 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1560 /* set mic-in to output, unmute it */
1561 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1562 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1566 static struct hda_channel_mode alc880_threestack_modes[2] = {
1567 { 2, alc880_threestack_ch2_init },
1568 { 6, alc880_threestack_ch6_init },
1571 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1572 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1573 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1574 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1575 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1576 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1577 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1578 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1579 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1580 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1581 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1582 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1583 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1584 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1585 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1586 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1587 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1588 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1590 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1591 .name = "Channel Mode",
1592 .info = alc_ch_mode_info,
1593 .get = alc_ch_mode_get,
1594 .put = alc_ch_mode_put,
1599 /* capture mixer elements */
1600 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1601 struct snd_ctl_elem_info *uinfo)
1603 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1604 struct alc_spec *spec = codec->spec;
1607 mutex_lock(&codec->control_mutex);
1608 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1610 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1611 mutex_unlock(&codec->control_mutex);
1615 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1616 unsigned int size, unsigned int __user *tlv)
1618 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1619 struct alc_spec *spec = codec->spec;
1622 mutex_lock(&codec->control_mutex);
1623 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1625 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1626 mutex_unlock(&codec->control_mutex);
1630 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1631 struct snd_ctl_elem_value *ucontrol);
1633 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1634 struct snd_ctl_elem_value *ucontrol,
1637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1638 struct alc_spec *spec = codec->spec;
1639 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1642 mutex_lock(&codec->control_mutex);
1643 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1645 err = func(kcontrol, ucontrol);
1646 mutex_unlock(&codec->control_mutex);
1650 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1651 struct snd_ctl_elem_value *ucontrol)
1653 return alc_cap_getput_caller(kcontrol, ucontrol,
1654 snd_hda_mixer_amp_volume_get);
1657 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1658 struct snd_ctl_elem_value *ucontrol)
1660 return alc_cap_getput_caller(kcontrol, ucontrol,
1661 snd_hda_mixer_amp_volume_put);
1664 /* capture mixer elements */
1665 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1667 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1668 struct snd_ctl_elem_value *ucontrol)
1670 return alc_cap_getput_caller(kcontrol, ucontrol,
1671 snd_hda_mixer_amp_switch_get);
1674 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1675 struct snd_ctl_elem_value *ucontrol)
1677 return alc_cap_getput_caller(kcontrol, ucontrol,
1678 snd_hda_mixer_amp_switch_put);
1681 #define _DEFINE_CAPMIX(num) \
1683 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1684 .name = "Capture Switch", \
1685 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1687 .info = alc_cap_sw_info, \
1688 .get = alc_cap_sw_get, \
1689 .put = alc_cap_sw_put, \
1692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1693 .name = "Capture Volume", \
1694 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1695 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1696 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1698 .info = alc_cap_vol_info, \
1699 .get = alc_cap_vol_get, \
1700 .put = alc_cap_vol_put, \
1701 .tlv = { .c = alc_cap_vol_tlv }, \
1704 #define _DEFINE_CAPSRC(num) \
1706 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1707 /* .name = "Capture Source", */ \
1708 .name = "Input Source", \
1710 .info = alc_mux_enum_info, \
1711 .get = alc_mux_enum_get, \
1712 .put = alc_mux_enum_put, \
1715 #define DEFINE_CAPMIX(num) \
1716 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1717 _DEFINE_CAPMIX(num), \
1718 _DEFINE_CAPSRC(num), \
1722 #define DEFINE_CAPMIX_NOSRC(num) \
1723 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1724 _DEFINE_CAPMIX(num), \
1728 /* up to three ADCs */
1732 DEFINE_CAPMIX_NOSRC(1);
1733 DEFINE_CAPMIX_NOSRC(2);
1734 DEFINE_CAPMIX_NOSRC(3);
1737 * ALC880 5-stack model
1739 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1741 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1742 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1745 /* additional mixers to alc880_three_stack_mixer */
1746 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1747 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1748 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1752 /* channel source setting (6/8 channel selection for 5-stack) */
1754 static struct hda_verb alc880_fivestack_ch6_init[] = {
1755 /* set line-in to input, mute it */
1756 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1757 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1762 static struct hda_verb alc880_fivestack_ch8_init[] = {
1763 /* set line-in to output, unmute it */
1764 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1765 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1769 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1770 { 6, alc880_fivestack_ch6_init },
1771 { 8, alc880_fivestack_ch8_init },
1776 * ALC880 6-stack model
1778 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1779 * Side = 0x05 (0x0f)
1780 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1781 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1784 static hda_nid_t alc880_6st_dac_nids[4] = {
1785 /* front, rear, clfe, rear_surr */
1786 0x02, 0x03, 0x04, 0x05
1789 static struct hda_input_mux alc880_6stack_capture_source = {
1793 { "Front Mic", 0x1 },
1799 /* fixed 8-channels */
1800 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1804 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1805 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1806 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1807 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1808 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1809 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1810 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1811 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1812 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1813 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1814 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1815 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1816 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1821 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1822 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1825 .name = "Channel Mode",
1826 .info = alc_ch_mode_info,
1827 .get = alc_ch_mode_get,
1828 .put = alc_ch_mode_put,
1837 * W810 has rear IO for:
1840 * Center/LFE (DAC 04)
1843 * The system also has a pair of internal speakers, and a headphone jack.
1844 * These are both connected to Line2 on the codec, hence to DAC 02.
1846 * There is a variable resistor to control the speaker or headphone
1847 * volume. This is a hardware-only device without a software API.
1849 * Plugging headphones in will disable the internal speakers. This is
1850 * implemented in hardware, not via the driver using jack sense. In
1851 * a similar fashion, plugging into the rear socket marked "front" will
1852 * disable both the speakers and headphones.
1854 * For input, there's a microphone jack, and an "audio in" jack.
1855 * These may not do anything useful with this driver yet, because I
1856 * haven't setup any initialization verbs for these yet...
1859 static hda_nid_t alc880_w810_dac_nids[3] = {
1860 /* front, rear/surround, clfe */
1864 /* fixed 6 channels */
1865 static struct hda_channel_mode alc880_w810_modes[1] = {
1869 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1870 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1871 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1872 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1873 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1874 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1875 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1876 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1877 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1878 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1879 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1887 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1888 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1892 static hda_nid_t alc880_z71v_dac_nids[1] = {
1895 #define ALC880_Z71V_HP_DAC 0x03
1897 /* fixed 2 channels */
1898 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1902 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1903 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1904 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1905 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1906 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1916 * ALC880 F1734 model
1918 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1919 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1922 static hda_nid_t alc880_f1734_dac_nids[1] = {
1925 #define ALC880_F1734_HP_DAC 0x02
1927 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1928 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1929 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1930 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1931 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1932 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1933 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1939 static struct hda_input_mux alc880_f1734_capture_source = {
1951 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1952 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1953 * Mic = 0x18, Line = 0x1a
1956 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1957 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1959 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1965 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1966 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1967 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1968 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1969 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1970 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1971 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1975 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1976 .name = "Channel Mode",
1977 .info = alc_ch_mode_info,
1978 .get = alc_ch_mode_get,
1979 .put = alc_ch_mode_put,
1985 * ALC880 ASUS W1V model
1987 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1988 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1989 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1992 /* additional mixers to alc880_asus_mixer */
1993 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1994 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1995 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2000 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2001 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2002 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2004 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2005 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2008 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2009 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2014 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2015 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2016 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2017 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2018 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2019 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2020 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2021 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2022 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2023 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2024 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2025 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2026 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2027 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2028 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2029 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2032 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2033 .name = "Channel Mode",
2034 .info = alc_ch_mode_info,
2035 .get = alc_ch_mode_get,
2036 .put = alc_ch_mode_put,
2041 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2042 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2043 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2044 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2045 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2046 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2047 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2048 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2049 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2050 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2051 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2055 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2056 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2057 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2058 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2059 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2066 * virtual master controls
2070 * slave controls for virtual master
2072 static const char *alc_slave_vols[] = {
2073 "Front Playback Volume",
2074 "Surround Playback Volume",
2075 "Center Playback Volume",
2076 "LFE Playback Volume",
2077 "Side Playback Volume",
2078 "Headphone Playback Volume",
2079 "Speaker Playback Volume",
2080 "Mono Playback Volume",
2081 "Line-Out Playback Volume",
2082 "PCM Playback Volume",
2086 static const char *alc_slave_sws[] = {
2087 "Front Playback Switch",
2088 "Surround Playback Switch",
2089 "Center Playback Switch",
2090 "LFE Playback Switch",
2091 "Side Playback Switch",
2092 "Headphone Playback Switch",
2093 "Speaker Playback Switch",
2094 "Mono Playback Switch",
2095 "IEC958 Playback Switch",
2100 * build control elements
2103 static void alc_free_kctls(struct hda_codec *codec);
2105 /* additional beep mixers; the actual parameters are overwritten at build */
2106 static struct snd_kcontrol_new alc_beep_mixer[] = {
2107 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2108 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2112 static int alc_build_controls(struct hda_codec *codec)
2114 struct alc_spec *spec = codec->spec;
2118 for (i = 0; i < spec->num_mixers; i++) {
2119 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2123 if (spec->cap_mixer) {
2124 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2128 if (spec->multiout.dig_out_nid) {
2129 err = snd_hda_create_spdif_out_ctls(codec,
2130 spec->multiout.dig_out_nid);
2133 if (!spec->no_analog) {
2134 err = snd_hda_create_spdif_share_sw(codec,
2138 spec->multiout.share_spdif = 1;
2141 if (spec->dig_in_nid) {
2142 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2147 /* create beep controls if needed */
2148 if (spec->beep_amp) {
2149 struct snd_kcontrol_new *knew;
2150 for (knew = alc_beep_mixer; knew->name; knew++) {
2151 struct snd_kcontrol *kctl;
2152 kctl = snd_ctl_new1(knew, codec);
2155 kctl->private_value = spec->beep_amp;
2156 err = snd_hda_ctl_add(codec, kctl);
2162 /* if we have no master control, let's create it */
2163 if (!spec->no_analog &&
2164 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2165 unsigned int vmaster_tlv[4];
2166 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2167 HDA_OUTPUT, vmaster_tlv);
2168 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2169 vmaster_tlv, alc_slave_vols);
2173 if (!spec->no_analog &&
2174 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2175 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2176 NULL, alc_slave_sws);
2181 alc_free_kctls(codec); /* no longer needed */
2187 * initialize the codec volumes, etc
2191 * generic initialization of ADC, input mixers and output mixers
2193 static struct hda_verb alc880_volume_init_verbs[] = {
2195 * Unmute ADC0-2 and set the default input to mic-in
2197 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2199 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2201 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2204 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2206 * Note: PASD motherboards uses the Line In 2 as the input for front
2209 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2215 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2216 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2219 * Set up output mixers (0x0c - 0x0f)
2221 /* set vol=0 to output mixers */
2222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2225 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2226 /* set up input amps for analog loopback */
2227 /* Amp Indices: DAC = 0, mixer = 1 */
2228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2230 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2231 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2233 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2234 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2235 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2241 * 3-stack pin configuration:
2242 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2244 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2246 * preset connection lists of input pins
2247 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2249 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2250 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2251 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2254 * Set pin mode and muting
2256 /* set front pin widgets 0x14 for output */
2257 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2258 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2260 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2261 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2262 /* Mic2 (as headphone out) for HP output */
2263 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2264 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2265 /* Line In pin widget for input */
2266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2267 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2268 /* Line2 (as front mic) pin widget for input and vref at 80% */
2269 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2270 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2271 /* CD pin widget for input */
2272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2278 * 5-stack pin configuration:
2279 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2280 * line-in/side = 0x1a, f-mic = 0x1b
2282 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2284 * preset connection lists of input pins
2285 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2287 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2288 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2291 * Set pin mode and muting
2293 /* set pin widgets 0x14-0x17 for output */
2294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2296 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2297 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2298 /* unmute pins for output (no gain on this amp) */
2299 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2300 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2301 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2302 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2304 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2305 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2306 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2307 /* Mic2 (as headphone out) for HP output */
2308 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2309 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310 /* Line In pin widget for input */
2311 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2312 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2313 /* Line2 (as front mic) pin widget for input and vref at 80% */
2314 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2315 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2316 /* CD pin widget for input */
2317 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2323 * W810 pin configuration:
2324 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2326 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2327 /* hphone/speaker input selector: front DAC */
2328 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2330 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2331 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2333 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2334 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2337 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2338 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2344 * Z71V pin configuration:
2345 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2347 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2348 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2349 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2350 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2351 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2353 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2354 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2362 * 6-stack pin configuration:
2363 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2364 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2366 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2367 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2370 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2373 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
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},
2378 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2379 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2380 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2381 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2382 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2383 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2384 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2385 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2386 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2392 * Uniwill pin configuration:
2393 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2396 static struct hda_verb alc880_uniwill_init_verbs[] = {
2397 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2399 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2400 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2401 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2402 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2403 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2404 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2405 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2406 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2407 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2410 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2412 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2414 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2415 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2417 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2418 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2419 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2420 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2421 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2422 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2424 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2425 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2432 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2434 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2435 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2437 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2438 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2439 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2440 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2441 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2442 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2443 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2444 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2445 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2446 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2447 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2448 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2452 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2453 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2454 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2455 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2457 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2458 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2463 static struct hda_verb alc880_beep_init_verbs[] = {
2464 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2468 /* auto-toggle front mic */
2469 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2471 unsigned int present;
2474 present = snd_hda_codec_read(codec, 0x18, 0,
2475 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2476 bits = present ? HDA_AMP_MUTE : 0;
2477 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2480 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2482 struct alc_spec *spec = codec->spec;
2484 spec->autocfg.hp_pins[0] = 0x14;
2485 spec->autocfg.speaker_pins[0] = 0x15;
2486 spec->autocfg.speaker_pins[0] = 0x16;
2487 alc_automute_amp(codec);
2488 alc880_uniwill_mic_automute(codec);
2491 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2494 /* Looks like the unsol event is incompatible with the standard
2495 * definition. 4bit tag is placed at 28 bit!
2497 switch (res >> 28) {
2498 case ALC880_MIC_EVENT:
2499 alc880_uniwill_mic_automute(codec);
2502 alc_automute_amp_unsol_event(codec, res);
2507 static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2509 struct alc_spec *spec = codec->spec;
2511 spec->autocfg.hp_pins[0] = 0x14;
2512 spec->autocfg.speaker_pins[0] = 0x15;
2513 alc_automute_amp(codec);
2516 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2518 unsigned int present;
2520 present = snd_hda_codec_read(codec, 0x21, 0,
2521 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2522 present &= HDA_AMP_VOLMASK;
2523 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2524 HDA_AMP_VOLMASK, present);
2525 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2526 HDA_AMP_VOLMASK, present);
2529 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2532 /* Looks like the unsol event is incompatible with the standard
2533 * definition. 4bit tag is placed at 28 bit!
2535 if ((res >> 28) == ALC880_DCVOL_EVENT)
2536 alc880_uniwill_p53_dcvol_automute(codec);
2538 alc_automute_amp_unsol_event(codec, res);
2542 * F1734 pin configuration:
2543 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2545 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2546 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2547 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2548 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2549 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2550 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2552 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2554 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2557 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2558 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2559 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2560 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2562 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2563 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2564 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2565 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2567 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2568 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2574 * ASUS pin configuration:
2575 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2577 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2578 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2579 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2580 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2581 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2584 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2585 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2587 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2589 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2593 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2594 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2595 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2596 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2597 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2598 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2599 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2600 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2605 /* Enable GPIO mask and set output */
2606 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2607 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2609 /* Clevo m520g init */
2610 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2611 /* headphone output */
2612 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2615 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2618 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2620 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2621 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2622 /* Mic1 (rear panel) */
2623 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2624 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2625 /* Mic2 (front panel) */
2626 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2627 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2629 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2630 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2631 /* change to EAPD mode */
2632 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2633 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2638 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2639 /* change to EAPD mode */
2640 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2641 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2643 /* Headphone output */
2644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2646 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2647 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2649 /* Line In pin widget for input */
2650 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2651 /* CD pin widget for input */
2652 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2653 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2654 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2656 /* change to EAPD mode */
2657 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2658 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2664 * LG m1 express dual
2667 * Rear Line-In/Out (blue): 0x14
2668 * Build-in Mic-In: 0x15
2670 * HP-Out (green): 0x1b
2671 * Mic-In/Out (red): 0x19
2675 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2676 static hda_nid_t alc880_lg_dac_nids[3] = {
2680 /* seems analog CD is not working */
2681 static struct hda_input_mux alc880_lg_capture_source = {
2686 { "Internal Mic", 0x6 },
2690 /* 2,4,6 channel modes */
2691 static struct hda_verb alc880_lg_ch2_init[] = {
2692 /* set line-in and mic-in to input */
2693 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2694 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2698 static struct hda_verb alc880_lg_ch4_init[] = {
2699 /* set line-in to out and mic-in to input */
2700 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2701 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2705 static struct hda_verb alc880_lg_ch6_init[] = {
2706 /* set line-in and mic-in to output */
2707 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2708 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2712 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2713 { 2, alc880_lg_ch2_init },
2714 { 4, alc880_lg_ch4_init },
2715 { 6, alc880_lg_ch6_init },
2718 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2720 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2721 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2722 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2723 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2724 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2725 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2726 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2730 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2731 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2732 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2735 .name = "Channel Mode",
2736 .info = alc_ch_mode_info,
2737 .get = alc_ch_mode_get,
2738 .put = alc_ch_mode_put,
2743 static struct hda_verb alc880_lg_init_verbs[] = {
2744 /* set capture source to mic-in */
2745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2747 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2748 /* mute all amp mixer inputs */
2749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2752 /* line-in to input */
2753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2756 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2757 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2759 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2760 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2761 /* mic-in to input */
2762 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2763 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2766 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2767 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2768 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2770 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2774 /* toggle speaker-output according to the hp-jack state */
2775 static void alc880_lg_init_hook(struct hda_codec *codec)
2777 struct alc_spec *spec = codec->spec;
2779 spec->autocfg.hp_pins[0] = 0x1b;
2780 spec->autocfg.speaker_pins[0] = 0x17;
2781 alc_automute_amp(codec);
2790 * Built-in Mic-In: 0x19
2796 static struct hda_input_mux alc880_lg_lw_capture_source = {
2800 { "Internal Mic", 0x1 },
2805 #define alc880_lg_lw_modes alc880_threestack_modes
2807 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2808 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2809 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2810 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2811 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2812 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2813 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2814 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2815 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2816 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2817 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2818 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2820 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2821 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2824 .name = "Channel Mode",
2825 .info = alc_ch_mode_info,
2826 .get = alc_ch_mode_get,
2827 .put = alc_ch_mode_put,
2832 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2833 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2834 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2835 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2837 /* set capture source to mic-in */
2838 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2839 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2840 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2843 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2846 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2847 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2848 /* mic-in to input */
2849 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2850 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2852 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2853 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2855 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2859 /* toggle speaker-output according to the hp-jack state */
2860 static void alc880_lg_lw_init_hook(struct hda_codec *codec)
2862 struct alc_spec *spec = codec->spec;
2864 spec->autocfg.hp_pins[0] = 0x1b;
2865 spec->autocfg.speaker_pins[0] = 0x14;
2866 alc_automute_amp(codec);
2869 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2870 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2871 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2872 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2873 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2874 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2875 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2879 static struct hda_input_mux alc880_medion_rim_capture_source = {
2883 { "Internal Mic", 0x1 },
2887 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2888 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2893 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2894 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2895 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2896 /* Mic2 (as headphone out) for HP output */
2897 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2898 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2899 /* Internal Speaker */
2900 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2901 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2903 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2904 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2906 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2910 /* toggle speaker-output according to the hp-jack state */
2911 static void alc880_medion_rim_automute(struct hda_codec *codec)
2913 struct alc_spec *spec = codec->spec;
2914 alc_automute_amp(codec);
2916 if (spec->jack_present)
2917 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2919 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2922 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2925 /* Looks like the unsol event is incompatible with the standard
2926 * definition. 4bit tag is placed at 28 bit!
2928 if ((res >> 28) == ALC880_HP_EVENT)
2929 alc880_medion_rim_automute(codec);
2932 static void alc880_medion_rim_init_hook(struct hda_codec *codec)
2934 struct alc_spec *spec = codec->spec;
2936 spec->autocfg.hp_pins[0] = 0x14;
2937 spec->autocfg.speaker_pins[0] = 0x1b;
2938 alc880_medion_rim_automute(codec);
2941 #ifdef CONFIG_SND_HDA_POWER_SAVE
2942 static struct hda_amp_list alc880_loopbacks[] = {
2943 { 0x0b, HDA_INPUT, 0 },
2944 { 0x0b, HDA_INPUT, 1 },
2945 { 0x0b, HDA_INPUT, 2 },
2946 { 0x0b, HDA_INPUT, 3 },
2947 { 0x0b, HDA_INPUT, 4 },
2951 static struct hda_amp_list alc880_lg_loopbacks[] = {
2952 { 0x0b, HDA_INPUT, 1 },
2953 { 0x0b, HDA_INPUT, 6 },
2954 { 0x0b, HDA_INPUT, 7 },
2963 static int alc_init(struct hda_codec *codec)
2965 struct alc_spec *spec = codec->spec;
2969 alc_auto_init_amp(codec, spec->init_amp);
2971 for (i = 0; i < spec->num_init_verbs; i++)
2972 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2974 if (spec->init_hook)
2975 spec->init_hook(codec);
2980 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2982 struct alc_spec *spec = codec->spec;
2984 if (spec->unsol_event)
2985 spec->unsol_event(codec, res);
2988 #ifdef CONFIG_SND_HDA_POWER_SAVE
2989 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2991 struct alc_spec *spec = codec->spec;
2992 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2997 * Analog playback callbacks
2999 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3000 struct hda_codec *codec,
3001 struct snd_pcm_substream *substream)
3003 struct alc_spec *spec = codec->spec;
3004 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3008 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3009 struct hda_codec *codec,
3010 unsigned int stream_tag,
3011 unsigned int format,
3012 struct snd_pcm_substream *substream)
3014 struct alc_spec *spec = codec->spec;
3015 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3016 stream_tag, format, substream);
3019 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3020 struct hda_codec *codec,
3021 struct snd_pcm_substream *substream)
3023 struct alc_spec *spec = codec->spec;
3024 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3030 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3031 struct hda_codec *codec,
3032 struct snd_pcm_substream *substream)
3034 struct alc_spec *spec = codec->spec;
3035 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3038 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3039 struct hda_codec *codec,
3040 unsigned int stream_tag,
3041 unsigned int format,
3042 struct snd_pcm_substream *substream)
3044 struct alc_spec *spec = codec->spec;
3045 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3046 stream_tag, format, substream);
3049 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3050 struct hda_codec *codec,
3051 struct snd_pcm_substream *substream)
3053 struct alc_spec *spec = codec->spec;
3054 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3057 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3058 struct hda_codec *codec,
3059 struct snd_pcm_substream *substream)
3061 struct alc_spec *spec = codec->spec;
3062 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3068 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3069 struct hda_codec *codec,
3070 unsigned int stream_tag,
3071 unsigned int format,
3072 struct snd_pcm_substream *substream)
3074 struct alc_spec *spec = codec->spec;
3076 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3077 stream_tag, 0, format);
3081 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3082 struct hda_codec *codec,
3083 struct snd_pcm_substream *substream)
3085 struct alc_spec *spec = codec->spec;
3087 snd_hda_codec_cleanup_stream(codec,
3088 spec->adc_nids[substream->number + 1]);
3095 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3099 /* NID is set in alc_build_pcms */
3101 .open = alc880_playback_pcm_open,
3102 .prepare = alc880_playback_pcm_prepare,
3103 .cleanup = alc880_playback_pcm_cleanup
3107 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3111 /* NID is set in alc_build_pcms */
3114 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3118 /* NID is set in alc_build_pcms */
3121 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3122 .substreams = 2, /* can be overridden */
3125 /* NID is set in alc_build_pcms */
3127 .prepare = alc880_alt_capture_pcm_prepare,
3128 .cleanup = alc880_alt_capture_pcm_cleanup
3132 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3136 /* NID is set in alc_build_pcms */
3138 .open = alc880_dig_playback_pcm_open,
3139 .close = alc880_dig_playback_pcm_close,
3140 .prepare = alc880_dig_playback_pcm_prepare,
3141 .cleanup = alc880_dig_playback_pcm_cleanup
3145 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3149 /* NID is set in alc_build_pcms */
3152 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3153 static struct hda_pcm_stream alc_pcm_null_stream = {
3159 static int alc_build_pcms(struct hda_codec *codec)
3161 struct alc_spec *spec = codec->spec;
3162 struct hda_pcm *info = spec->pcm_rec;
3165 codec->num_pcms = 1;
3166 codec->pcm_info = info;
3168 if (spec->no_analog)
3171 info->name = spec->stream_name_analog;
3172 if (spec->stream_analog_playback) {
3173 if (snd_BUG_ON(!spec->multiout.dac_nids))
3175 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3176 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3178 if (spec->stream_analog_capture) {
3179 if (snd_BUG_ON(!spec->adc_nids))
3181 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3182 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3185 if (spec->channel_mode) {
3186 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3187 for (i = 0; i < spec->num_channel_mode; i++) {
3188 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3189 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3195 /* SPDIF for stream index #1 */
3196 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3197 codec->num_pcms = 2;
3198 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3199 info = spec->pcm_rec + 1;
3200 info->name = spec->stream_name_digital;
3201 if (spec->dig_out_type)
3202 info->pcm_type = spec->dig_out_type;
3204 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3205 if (spec->multiout.dig_out_nid &&
3206 spec->stream_digital_playback) {
3207 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3208 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3210 if (spec->dig_in_nid &&
3211 spec->stream_digital_capture) {
3212 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3213 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3215 /* FIXME: do we need this for all Realtek codec models? */
3216 codec->spdif_status_reset = 1;
3219 if (spec->no_analog)
3222 /* If the use of more than one ADC is requested for the current
3223 * model, configure a second analog capture-only PCM.
3225 /* Additional Analaog capture for index #2 */
3226 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3227 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3228 codec->num_pcms = 3;
3229 info = spec->pcm_rec + 2;
3230 info->name = spec->stream_name_analog;
3231 if (spec->alt_dac_nid) {
3232 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3233 *spec->stream_analog_alt_playback;
3234 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3237 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3238 alc_pcm_null_stream;
3239 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3241 if (spec->num_adc_nids > 1) {
3242 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3243 *spec->stream_analog_alt_capture;
3244 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3246 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3247 spec->num_adc_nids - 1;
3249 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3250 alc_pcm_null_stream;
3251 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3258 static void alc_free_kctls(struct hda_codec *codec)
3260 struct alc_spec *spec = codec->spec;
3262 if (spec->kctls.list) {
3263 struct snd_kcontrol_new *kctl = spec->kctls.list;
3265 for (i = 0; i < spec->kctls.used; i++)
3266 kfree(kctl[i].name);
3268 snd_array_free(&spec->kctls);
3271 static void alc_free(struct hda_codec *codec)
3273 struct alc_spec *spec = codec->spec;
3278 alc_free_kctls(codec);
3280 snd_hda_detach_beep_device(codec);
3283 #ifdef SND_HDA_NEEDS_RESUME
3284 static int alc_resume(struct hda_codec *codec)
3286 codec->patch_ops.init(codec);
3287 snd_hda_codec_resume_amp(codec);
3288 snd_hda_codec_resume_cache(codec);
3295 static struct hda_codec_ops alc_patch_ops = {
3296 .build_controls = alc_build_controls,
3297 .build_pcms = alc_build_pcms,
3300 .unsol_event = alc_unsol_event,
3301 #ifdef SND_HDA_NEEDS_RESUME
3302 .resume = alc_resume,
3304 #ifdef CONFIG_SND_HDA_POWER_SAVE
3305 .check_power_status = alc_check_power_status,
3311 * Test configuration for debugging
3313 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3316 #ifdef CONFIG_SND_DEBUG
3317 static hda_nid_t alc880_test_dac_nids[4] = {
3318 0x02, 0x03, 0x04, 0x05
3321 static struct hda_input_mux alc880_test_capture_source = {
3330 { "Surround", 0x6 },
3334 static struct hda_channel_mode alc880_test_modes[4] = {
3341 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3342 struct snd_ctl_elem_info *uinfo)
3344 static char *texts[] = {
3345 "N/A", "Line Out", "HP Out",
3346 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3348 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3350 uinfo->value.enumerated.items = 8;
3351 if (uinfo->value.enumerated.item >= 8)
3352 uinfo->value.enumerated.item = 7;
3353 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3357 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3358 struct snd_ctl_elem_value *ucontrol)
3360 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3361 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3362 unsigned int pin_ctl, item = 0;
3364 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3365 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3366 if (pin_ctl & AC_PINCTL_OUT_EN) {
3367 if (pin_ctl & AC_PINCTL_HP_EN)
3371 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3372 switch (pin_ctl & AC_PINCTL_VREFEN) {
3373 case AC_PINCTL_VREF_HIZ: item = 3; break;
3374 case AC_PINCTL_VREF_50: item = 4; break;
3375 case AC_PINCTL_VREF_GRD: item = 5; break;
3376 case AC_PINCTL_VREF_80: item = 6; break;
3377 case AC_PINCTL_VREF_100: item = 7; break;
3380 ucontrol->value.enumerated.item[0] = item;
3384 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3385 struct snd_ctl_elem_value *ucontrol)
3387 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3388 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3389 static unsigned int ctls[] = {
3390 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3391 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3392 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3393 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3394 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3395 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3397 unsigned int old_ctl, new_ctl;
3399 old_ctl = snd_hda_codec_read(codec, nid, 0,
3400 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3401 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3402 if (old_ctl != new_ctl) {
3404 snd_hda_codec_write_cache(codec, nid, 0,
3405 AC_VERB_SET_PIN_WIDGET_CONTROL,
3407 val = ucontrol->value.enumerated.item[0] >= 3 ?
3409 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3416 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3417 struct snd_ctl_elem_info *uinfo)
3419 static char *texts[] = {
3420 "Front", "Surround", "CLFE", "Side"
3422 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3424 uinfo->value.enumerated.items = 4;
3425 if (uinfo->value.enumerated.item >= 4)
3426 uinfo->value.enumerated.item = 3;
3427 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3431 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3432 struct snd_ctl_elem_value *ucontrol)
3434 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3435 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3438 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3439 ucontrol->value.enumerated.item[0] = sel & 3;
3443 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3444 struct snd_ctl_elem_value *ucontrol)
3446 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3447 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3450 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3451 if (ucontrol->value.enumerated.item[0] != sel) {
3452 sel = ucontrol->value.enumerated.item[0] & 3;
3453 snd_hda_codec_write_cache(codec, nid, 0,
3454 AC_VERB_SET_CONNECT_SEL, sel);
3460 #define PIN_CTL_TEST(xname,nid) { \
3461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3463 .info = alc_test_pin_ctl_info, \
3464 .get = alc_test_pin_ctl_get, \
3465 .put = alc_test_pin_ctl_put, \
3466 .private_value = nid \
3469 #define PIN_SRC_TEST(xname,nid) { \
3470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3472 .info = alc_test_pin_src_info, \
3473 .get = alc_test_pin_src_get, \
3474 .put = alc_test_pin_src_put, \
3475 .private_value = nid \
3478 static struct snd_kcontrol_new alc880_test_mixer[] = {
3479 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3480 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3481 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3482 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3483 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3484 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3485 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3486 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3487 PIN_CTL_TEST("Front Pin Mode", 0x14),
3488 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3489 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3490 PIN_CTL_TEST("Side Pin Mode", 0x17),
3491 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3492 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3493 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3494 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3495 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3496 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3497 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3498 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3499 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3500 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3501 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3502 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3503 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3504 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3505 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3506 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3507 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3508 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3511 .name = "Channel Mode",
3512 .info = alc_ch_mode_info,
3513 .get = alc_ch_mode_get,
3514 .put = alc_ch_mode_put,
3519 static struct hda_verb alc880_test_init_verbs[] = {
3520 /* Unmute inputs of 0x0c - 0x0f */
3521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3523 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3524 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3525 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3526 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3527 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3528 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3529 /* Vol output for 0x0c-0x0f */
3530 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3531 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3532 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3533 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3534 /* Set output pins 0x14-0x17 */
3535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3536 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3538 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3539 /* Unmute output pins 0x14-0x17 */
3540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3543 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544 /* Set input pins 0x18-0x1c */
3545 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3546 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3550 /* Mute input pins 0x18-0x1b */
3551 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3552 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3554 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3556 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3557 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3559 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3560 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3561 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3562 /* Analog input/passthru */
3563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3566 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3575 static const char *alc880_models[ALC880_MODEL_LAST] = {
3576 [ALC880_3ST] = "3stack",
3577 [ALC880_TCL_S700] = "tcl",
3578 [ALC880_3ST_DIG] = "3stack-digout",
3579 [ALC880_CLEVO] = "clevo",
3580 [ALC880_5ST] = "5stack",
3581 [ALC880_5ST_DIG] = "5stack-digout",
3582 [ALC880_W810] = "w810",
3583 [ALC880_Z71V] = "z71v",
3584 [ALC880_6ST] = "6stack",
3585 [ALC880_6ST_DIG] = "6stack-digout",
3586 [ALC880_ASUS] = "asus",
3587 [ALC880_ASUS_W1V] = "asus-w1v",
3588 [ALC880_ASUS_DIG] = "asus-dig",
3589 [ALC880_ASUS_DIG2] = "asus-dig2",
3590 [ALC880_UNIWILL_DIG] = "uniwill",
3591 [ALC880_UNIWILL_P53] = "uniwill-p53",
3592 [ALC880_FUJITSU] = "fujitsu",
3593 [ALC880_F1734] = "F1734",
3595 [ALC880_LG_LW] = "lg-lw",
3596 [ALC880_MEDION_RIM] = "medion",
3597 #ifdef CONFIG_SND_DEBUG
3598 [ALC880_TEST] = "test",
3600 [ALC880_AUTO] = "auto",
3603 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3604 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3605 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3606 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3607 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3608 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3609 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3610 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3611 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3612 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3613 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3614 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3615 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3616 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3617 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3618 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3619 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3620 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3621 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3622 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3623 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3624 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3625 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3626 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3627 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3628 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3629 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3630 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3631 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3632 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3633 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3634 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3635 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3636 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3637 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3638 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3639 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3640 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3641 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3642 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3643 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3644 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3645 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3646 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3647 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3648 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3649 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3650 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3651 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3652 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3653 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3654 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3655 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3656 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3657 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3658 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3659 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3660 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3661 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3662 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3663 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3664 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3665 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3666 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3667 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3668 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3669 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3670 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3671 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3673 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3674 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3675 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3680 * ALC880 codec presets
3682 static struct alc_config_preset alc880_presets[] = {
3684 .mixers = { alc880_three_stack_mixer },
3685 .init_verbs = { alc880_volume_init_verbs,
3686 alc880_pin_3stack_init_verbs },
3687 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3688 .dac_nids = alc880_dac_nids,
3689 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3690 .channel_mode = alc880_threestack_modes,
3692 .input_mux = &alc880_capture_source,
3694 [ALC880_3ST_DIG] = {
3695 .mixers = { alc880_three_stack_mixer },
3696 .init_verbs = { alc880_volume_init_verbs,
3697 alc880_pin_3stack_init_verbs },
3698 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3699 .dac_nids = alc880_dac_nids,
3700 .dig_out_nid = ALC880_DIGOUT_NID,
3701 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3702 .channel_mode = alc880_threestack_modes,
3704 .input_mux = &alc880_capture_source,
3706 [ALC880_TCL_S700] = {
3707 .mixers = { alc880_tcl_s700_mixer },
3708 .init_verbs = { alc880_volume_init_verbs,
3709 alc880_pin_tcl_S700_init_verbs,
3710 alc880_gpio2_init_verbs },
3711 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3712 .dac_nids = alc880_dac_nids,
3713 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3714 .num_adc_nids = 1, /* single ADC */
3716 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3717 .channel_mode = alc880_2_jack_modes,
3718 .input_mux = &alc880_capture_source,
3721 .mixers = { alc880_three_stack_mixer,
3722 alc880_five_stack_mixer},
3723 .init_verbs = { alc880_volume_init_verbs,
3724 alc880_pin_5stack_init_verbs },
3725 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3726 .dac_nids = alc880_dac_nids,
3727 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3728 .channel_mode = alc880_fivestack_modes,
3729 .input_mux = &alc880_capture_source,
3731 [ALC880_5ST_DIG] = {
3732 .mixers = { alc880_three_stack_mixer,
3733 alc880_five_stack_mixer },
3734 .init_verbs = { alc880_volume_init_verbs,
3735 alc880_pin_5stack_init_verbs },
3736 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3737 .dac_nids = alc880_dac_nids,
3738 .dig_out_nid = ALC880_DIGOUT_NID,
3739 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3740 .channel_mode = alc880_fivestack_modes,
3741 .input_mux = &alc880_capture_source,
3744 .mixers = { alc880_six_stack_mixer },
3745 .init_verbs = { alc880_volume_init_verbs,
3746 alc880_pin_6stack_init_verbs },
3747 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3748 .dac_nids = alc880_6st_dac_nids,
3749 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3750 .channel_mode = alc880_sixstack_modes,
3751 .input_mux = &alc880_6stack_capture_source,
3753 [ALC880_6ST_DIG] = {
3754 .mixers = { alc880_six_stack_mixer },
3755 .init_verbs = { alc880_volume_init_verbs,
3756 alc880_pin_6stack_init_verbs },
3757 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3758 .dac_nids = alc880_6st_dac_nids,
3759 .dig_out_nid = ALC880_DIGOUT_NID,
3760 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3761 .channel_mode = alc880_sixstack_modes,
3762 .input_mux = &alc880_6stack_capture_source,
3765 .mixers = { alc880_w810_base_mixer },
3766 .init_verbs = { alc880_volume_init_verbs,
3767 alc880_pin_w810_init_verbs,
3768 alc880_gpio2_init_verbs },
3769 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3770 .dac_nids = alc880_w810_dac_nids,
3771 .dig_out_nid = ALC880_DIGOUT_NID,
3772 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3773 .channel_mode = alc880_w810_modes,
3774 .input_mux = &alc880_capture_source,
3777 .mixers = { alc880_z71v_mixer },
3778 .init_verbs = { alc880_volume_init_verbs,
3779 alc880_pin_z71v_init_verbs },
3780 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3781 .dac_nids = alc880_z71v_dac_nids,
3782 .dig_out_nid = ALC880_DIGOUT_NID,
3784 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3785 .channel_mode = alc880_2_jack_modes,
3786 .input_mux = &alc880_capture_source,
3789 .mixers = { alc880_f1734_mixer },
3790 .init_verbs = { alc880_volume_init_verbs,
3791 alc880_pin_f1734_init_verbs },
3792 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3793 .dac_nids = alc880_f1734_dac_nids,
3795 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3796 .channel_mode = alc880_2_jack_modes,
3797 .input_mux = &alc880_f1734_capture_source,
3798 .unsol_event = alc880_uniwill_p53_unsol_event,
3799 .init_hook = alc880_uniwill_p53_init_hook,
3802 .mixers = { alc880_asus_mixer },
3803 .init_verbs = { alc880_volume_init_verbs,
3804 alc880_pin_asus_init_verbs,
3805 alc880_gpio1_init_verbs },
3806 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3807 .dac_nids = alc880_asus_dac_nids,
3808 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3809 .channel_mode = alc880_asus_modes,
3811 .input_mux = &alc880_capture_source,
3813 [ALC880_ASUS_DIG] = {
3814 .mixers = { alc880_asus_mixer },
3815 .init_verbs = { alc880_volume_init_verbs,
3816 alc880_pin_asus_init_verbs,
3817 alc880_gpio1_init_verbs },
3818 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3819 .dac_nids = alc880_asus_dac_nids,
3820 .dig_out_nid = ALC880_DIGOUT_NID,
3821 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3822 .channel_mode = alc880_asus_modes,
3824 .input_mux = &alc880_capture_source,
3826 [ALC880_ASUS_DIG2] = {
3827 .mixers = { alc880_asus_mixer },
3828 .init_verbs = { alc880_volume_init_verbs,
3829 alc880_pin_asus_init_verbs,
3830 alc880_gpio2_init_verbs }, /* use GPIO2 */
3831 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3832 .dac_nids = alc880_asus_dac_nids,
3833 .dig_out_nid = ALC880_DIGOUT_NID,
3834 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3835 .channel_mode = alc880_asus_modes,
3837 .input_mux = &alc880_capture_source,
3839 [ALC880_ASUS_W1V] = {
3840 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3841 .init_verbs = { alc880_volume_init_verbs,
3842 alc880_pin_asus_init_verbs,
3843 alc880_gpio1_init_verbs },
3844 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3845 .dac_nids = alc880_asus_dac_nids,
3846 .dig_out_nid = ALC880_DIGOUT_NID,
3847 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3848 .channel_mode = alc880_asus_modes,
3850 .input_mux = &alc880_capture_source,
3852 [ALC880_UNIWILL_DIG] = {
3853 .mixers = { alc880_asus_mixer },
3854 .init_verbs = { alc880_volume_init_verbs,
3855 alc880_pin_asus_init_verbs },
3856 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3857 .dac_nids = alc880_asus_dac_nids,
3858 .dig_out_nid = ALC880_DIGOUT_NID,
3859 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3860 .channel_mode = alc880_asus_modes,
3862 .input_mux = &alc880_capture_source,
3864 [ALC880_UNIWILL] = {
3865 .mixers = { alc880_uniwill_mixer },
3866 .init_verbs = { alc880_volume_init_verbs,
3867 alc880_uniwill_init_verbs },
3868 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3869 .dac_nids = alc880_asus_dac_nids,
3870 .dig_out_nid = ALC880_DIGOUT_NID,
3871 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3872 .channel_mode = alc880_threestack_modes,
3874 .input_mux = &alc880_capture_source,
3875 .unsol_event = alc880_uniwill_unsol_event,
3876 .init_hook = alc880_uniwill_init_hook,
3878 [ALC880_UNIWILL_P53] = {
3879 .mixers = { alc880_uniwill_p53_mixer },
3880 .init_verbs = { alc880_volume_init_verbs,
3881 alc880_uniwill_p53_init_verbs },
3882 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3883 .dac_nids = alc880_asus_dac_nids,
3884 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3885 .channel_mode = alc880_threestack_modes,
3886 .input_mux = &alc880_capture_source,
3887 .unsol_event = alc880_uniwill_p53_unsol_event,
3888 .init_hook = alc880_uniwill_p53_init_hook,
3890 [ALC880_FUJITSU] = {
3891 .mixers = { alc880_fujitsu_mixer },
3892 .init_verbs = { alc880_volume_init_verbs,
3893 alc880_uniwill_p53_init_verbs,
3894 alc880_beep_init_verbs },
3895 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3896 .dac_nids = alc880_dac_nids,
3897 .dig_out_nid = ALC880_DIGOUT_NID,
3898 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3899 .channel_mode = alc880_2_jack_modes,
3900 .input_mux = &alc880_capture_source,
3901 .unsol_event = alc880_uniwill_p53_unsol_event,
3902 .init_hook = alc880_uniwill_p53_init_hook,
3905 .mixers = { alc880_three_stack_mixer },
3906 .init_verbs = { alc880_volume_init_verbs,
3907 alc880_pin_clevo_init_verbs },
3908 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3909 .dac_nids = alc880_dac_nids,
3911 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3912 .channel_mode = alc880_threestack_modes,
3914 .input_mux = &alc880_capture_source,
3917 .mixers = { alc880_lg_mixer },
3918 .init_verbs = { alc880_volume_init_verbs,
3919 alc880_lg_init_verbs },
3920 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3921 .dac_nids = alc880_lg_dac_nids,
3922 .dig_out_nid = ALC880_DIGOUT_NID,
3923 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3924 .channel_mode = alc880_lg_ch_modes,
3926 .input_mux = &alc880_lg_capture_source,
3927 .unsol_event = alc_automute_amp_unsol_event,
3928 .init_hook = alc880_lg_init_hook,
3929 #ifdef CONFIG_SND_HDA_POWER_SAVE
3930 .loopbacks = alc880_lg_loopbacks,
3934 .mixers = { alc880_lg_lw_mixer },
3935 .init_verbs = { alc880_volume_init_verbs,
3936 alc880_lg_lw_init_verbs },
3937 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3938 .dac_nids = alc880_dac_nids,
3939 .dig_out_nid = ALC880_DIGOUT_NID,
3940 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3941 .channel_mode = alc880_lg_lw_modes,
3942 .input_mux = &alc880_lg_lw_capture_source,
3943 .unsol_event = alc_automute_amp_unsol_event,
3944 .init_hook = alc880_lg_lw_init_hook,
3946 [ALC880_MEDION_RIM] = {
3947 .mixers = { alc880_medion_rim_mixer },
3948 .init_verbs = { alc880_volume_init_verbs,
3949 alc880_medion_rim_init_verbs,
3950 alc_gpio2_init_verbs },
3951 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3952 .dac_nids = alc880_dac_nids,
3953 .dig_out_nid = ALC880_DIGOUT_NID,
3954 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3955 .channel_mode = alc880_2_jack_modes,
3956 .input_mux = &alc880_medion_rim_capture_source,
3957 .unsol_event = alc880_medion_rim_unsol_event,
3958 .init_hook = alc880_medion_rim_init_hook,
3960 #ifdef CONFIG_SND_DEBUG
3962 .mixers = { alc880_test_mixer },
3963 .init_verbs = { alc880_test_init_verbs },
3964 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3965 .dac_nids = alc880_test_dac_nids,
3966 .dig_out_nid = ALC880_DIGOUT_NID,
3967 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3968 .channel_mode = alc880_test_modes,
3969 .input_mux = &alc880_test_capture_source,
3975 * Automatic parse of I/O pins from the BIOS configuration
3980 ALC_CTL_WIDGET_MUTE,
3983 static struct snd_kcontrol_new alc880_control_templates[] = {
3984 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3985 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3986 HDA_BIND_MUTE(NULL, 0, 0, 0),
3989 /* add dynamic controls */
3990 static int add_control(struct alc_spec *spec, int type, const char *name,
3993 struct snd_kcontrol_new *knew;
3995 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3996 knew = snd_array_new(&spec->kctls);
3999 *knew = alc880_control_templates[type];
4000 knew->name = kstrdup(name, GFP_KERNEL);
4003 knew->private_value = val;
4007 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4008 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4009 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4010 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4011 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4012 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4013 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4014 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4015 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4016 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4017 #define ALC880_PIN_CD_NID 0x1c
4019 /* fill in the dac_nids table from the parsed pin configuration */
4020 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4021 const struct auto_pin_cfg *cfg)
4027 memset(assigned, 0, sizeof(assigned));
4028 spec->multiout.dac_nids = spec->private_dac_nids;
4030 /* check the pins hardwired to audio widget */
4031 for (i = 0; i < cfg->line_outs; i++) {
4032 nid = cfg->line_out_pins[i];
4033 if (alc880_is_fixed_pin(nid)) {
4034 int idx = alc880_fixed_pin_idx(nid);
4035 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4039 /* left pins can be connect to any audio widget */
4040 for (i = 0; i < cfg->line_outs; i++) {
4041 nid = cfg->line_out_pins[i];
4042 if (alc880_is_fixed_pin(nid))
4044 /* search for an empty channel */
4045 for (j = 0; j < cfg->line_outs; j++) {
4047 spec->multiout.dac_nids[i] =
4048 alc880_idx_to_dac(j);
4054 spec->multiout.num_dacs = cfg->line_outs;
4058 /* add playback controls from the parsed DAC table */
4059 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4060 const struct auto_pin_cfg *cfg)
4063 static const char *chname[4] = {
4064 "Front", "Surround", NULL /*CLFE*/, "Side"
4069 for (i = 0; i < cfg->line_outs; i++) {
4070 if (!spec->multiout.dac_nids[i])
4072 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4075 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4076 "Center Playback Volume",
4077 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4081 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4082 "LFE Playback Volume",
4083 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4087 err = add_control(spec, ALC_CTL_BIND_MUTE,
4088 "Center Playback Switch",
4089 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4093 err = add_control(spec, ALC_CTL_BIND_MUTE,
4094 "LFE Playback Switch",
4095 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4100 sprintf(name, "%s Playback Volume", chname[i]);
4101 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4102 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4106 sprintf(name, "%s Playback Switch", chname[i]);
4107 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4108 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4117 /* add playback controls for speaker and HP outputs */
4118 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4128 if (alc880_is_fixed_pin(pin)) {
4129 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4130 /* specify the DAC as the extra output */
4131 if (!spec->multiout.hp_nid)
4132 spec->multiout.hp_nid = nid;
4134 spec->multiout.extra_out_nid[0] = nid;
4135 /* control HP volume/switch on the output mixer amp */
4136 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4137 sprintf(name, "%s Playback Volume", pfx);
4138 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4139 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4142 sprintf(name, "%s Playback Switch", pfx);
4143 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4144 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4147 } else if (alc880_is_multi_pin(pin)) {
4148 /* set manual connection */
4149 /* we have only a switch on HP-out PIN */
4150 sprintf(name, "%s Playback Switch", pfx);
4151 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4152 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4159 /* create input playback/capture controls for the given pin */
4160 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4161 const char *ctlname,
4162 int idx, hda_nid_t mix_nid)
4167 sprintf(name, "%s Playback Volume", ctlname);
4168 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4169 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4172 sprintf(name, "%s Playback Switch", ctlname);
4173 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4174 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4180 /* create playback/capture controls for input pins */
4181 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4182 const struct auto_pin_cfg *cfg)
4184 struct hda_input_mux *imux = &spec->private_imux[0];
4187 for (i = 0; i < AUTO_PIN_LAST; i++) {
4188 if (alc880_is_input_pin(cfg->input_pins[i])) {
4189 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4190 err = new_analog_input(spec, cfg->input_pins[i],
4191 auto_pin_cfg_labels[i],
4195 imux->items[imux->num_items].label =
4196 auto_pin_cfg_labels[i];
4197 imux->items[imux->num_items].index =
4198 alc880_input_pin_idx(cfg->input_pins[i]);
4205 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4206 unsigned int pin_type)
4208 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4211 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4215 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4216 hda_nid_t nid, int pin_type,
4219 alc_set_pin_output(codec, nid, pin_type);
4220 /* need the manual connection? */
4221 if (alc880_is_multi_pin(nid)) {
4222 struct alc_spec *spec = codec->spec;
4223 int idx = alc880_multi_pin_idx(nid);
4224 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4225 AC_VERB_SET_CONNECT_SEL,
4226 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4230 static int get_pin_type(int line_out_type)
4232 if (line_out_type == AUTO_PIN_HP_OUT)
4238 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4240 struct alc_spec *spec = codec->spec;
4243 for (i = 0; i < spec->autocfg.line_outs; i++) {
4244 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4245 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4246 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4250 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4252 struct alc_spec *spec = codec->spec;
4255 pin = spec->autocfg.speaker_pins[0];
4256 if (pin) /* connect to front */
4257 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4258 pin = spec->autocfg.hp_pins[0];
4259 if (pin) /* connect to front */
4260 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4263 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4265 struct alc_spec *spec = codec->spec;
4268 for (i = 0; i < AUTO_PIN_LAST; i++) {
4269 hda_nid_t nid = spec->autocfg.input_pins[i];
4270 if (alc880_is_input_pin(nid)) {
4271 alc_set_input_pin(codec, nid, i);
4272 if (nid != ALC880_PIN_CD_NID &&
4273 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4274 snd_hda_codec_write(codec, nid, 0,
4275 AC_VERB_SET_AMP_GAIN_MUTE,
4281 /* parse the BIOS configuration and set up the alc_spec */
4282 /* return 1 if successful, 0 if the proper config is not found,
4283 * or a negative error code
4285 static int alc880_parse_auto_config(struct hda_codec *codec)
4287 struct alc_spec *spec = codec->spec;
4289 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4291 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4295 if (!spec->autocfg.line_outs)
4296 return 0; /* can't find valid BIOS pin config */
4298 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4301 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4304 err = alc880_auto_create_extra_out(spec,
4305 spec->autocfg.speaker_pins[0],
4309 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4313 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4317 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4319 /* check multiple SPDIF-out (for recent codecs) */
4320 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4322 err = snd_hda_get_connections(codec,
4323 spec->autocfg.dig_out_pins[i],
4328 spec->multiout.dig_out_nid = dig_nid;
4330 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4331 spec->slave_dig_outs[i - 1] = dig_nid;
4332 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4336 if (spec->autocfg.dig_in_pin)
4337 spec->dig_in_nid = ALC880_DIGIN_NID;
4339 if (spec->kctls.list)
4340 add_mixer(spec, spec->kctls.list);
4342 add_verb(spec, alc880_volume_init_verbs);
4344 spec->num_mux_defs = 1;
4345 spec->input_mux = &spec->private_imux[0];
4347 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4352 /* additional initialization for auto-configuration model */
4353 static void alc880_auto_init(struct hda_codec *codec)
4355 struct alc_spec *spec = codec->spec;
4356 alc880_auto_init_multi_out(codec);
4357 alc880_auto_init_extra_out(codec);
4358 alc880_auto_init_analog_input(codec);
4359 if (spec->unsol_event)
4360 alc_inithook(codec);
4363 static void set_capture_mixer(struct alc_spec *spec)
4365 static struct snd_kcontrol_new *caps[2][3] = {
4366 { alc_capture_mixer_nosrc1,
4367 alc_capture_mixer_nosrc2,
4368 alc_capture_mixer_nosrc3 },
4369 { alc_capture_mixer1,
4371 alc_capture_mixer3 },
4373 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4375 if (spec->input_mux && spec->input_mux->num_items > 1)
4379 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4383 #define set_beep_amp(spec, nid, idx, dir) \
4384 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4387 * OK, here we have finally the patch for ALC880
4390 static int patch_alc880(struct hda_codec *codec)
4392 struct alc_spec *spec;
4396 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4402 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4405 if (board_config < 0) {
4406 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4407 "trying auto-probe from BIOS...\n");
4408 board_config = ALC880_AUTO;
4411 if (board_config == ALC880_AUTO) {
4412 /* automatic parse from the BIOS config */
4413 err = alc880_parse_auto_config(codec);
4419 "hda_codec: Cannot set up configuration "
4420 "from BIOS. Using 3-stack mode...\n");
4421 board_config = ALC880_3ST;
4425 err = snd_hda_attach_beep_device(codec, 0x1);
4431 if (board_config != ALC880_AUTO)
4432 setup_preset(spec, &alc880_presets[board_config]);
4434 spec->stream_name_analog = "ALC880 Analog";
4435 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4436 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4437 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4439 spec->stream_name_digital = "ALC880 Digital";
4440 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4441 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4443 if (!spec->adc_nids && spec->input_mux) {
4444 /* check whether NID 0x07 is valid */
4445 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4447 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4448 if (wcap != AC_WID_AUD_IN) {
4449 spec->adc_nids = alc880_adc_nids_alt;
4450 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4452 spec->adc_nids = alc880_adc_nids;
4453 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4456 set_capture_mixer(spec);
4457 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4459 spec->vmaster_nid = 0x0c;
4461 codec->patch_ops = alc_patch_ops;
4462 if (board_config == ALC880_AUTO)
4463 spec->init_hook = alc880_auto_init;
4464 #ifdef CONFIG_SND_HDA_POWER_SAVE
4465 if (!spec->loopback.amplist)
4466 spec->loopback.amplist = alc880_loopbacks;
4468 codec->proc_widget_hook = print_realtek_coef;
4478 static hda_nid_t alc260_dac_nids[1] = {
4483 static hda_nid_t alc260_adc_nids[1] = {
4488 static hda_nid_t alc260_adc_nids_alt[1] = {
4493 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4494 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4496 static hda_nid_t alc260_dual_adc_nids[2] = {
4501 #define ALC260_DIGOUT_NID 0x03
4502 #define ALC260_DIGIN_NID 0x06
4504 static struct hda_input_mux alc260_capture_source = {
4508 { "Front Mic", 0x1 },
4514 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4515 * headphone jack and the internal CD lines since these are the only pins at
4516 * which audio can appear. For flexibility, also allow the option of
4517 * recording the mixer output on the second ADC (ADC0 doesn't have a
4518 * connection to the mixer output).
4520 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4524 { "Mic/Line", 0x0 },
4526 { "Headphone", 0x2 },
4532 { "Mic/Line", 0x0 },
4534 { "Headphone", 0x2 },
4541 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4542 * the Fujitsu S702x, but jacks are marked differently.
4544 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4551 { "Headphone", 0x5 },
4560 { "Headphone", 0x6 },
4566 /* Maxdata Favorit 100XS */
4567 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4571 { "Line/Mic", 0x0 },
4578 { "Line/Mic", 0x0 },
4586 * This is just place-holder, so there's something for alc_build_pcms to look
4587 * at when it calculates the maximum number of channels. ALC260 has no mixer
4588 * element which allows changing the channel mode, so the verb list is
4591 static struct hda_channel_mode alc260_modes[1] = {
4596 /* Mixer combinations
4598 * basic: base_output + input + pc_beep + capture
4599 * HP: base_output + input + capture_alt
4600 * HP_3013: hp_3013 + input + capture
4601 * fujitsu: fujitsu + capture
4602 * acer: acer + capture
4605 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4606 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4607 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4608 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4609 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4610 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4611 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4615 static struct snd_kcontrol_new alc260_input_mixer[] = {
4616 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4617 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4618 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4619 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4621 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4622 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4623 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4627 /* update HP, line and mono out pins according to the master switch */
4628 static void alc260_hp_master_update(struct hda_codec *codec,
4629 hda_nid_t hp, hda_nid_t line,
4632 struct alc_spec *spec = codec->spec;
4633 unsigned int val = spec->master_sw ? PIN_HP : 0;
4634 /* change HP and line-out pins */
4635 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4637 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4639 /* mono (speaker) depending on the HP jack sense */
4640 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4641 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4645 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4646 struct snd_ctl_elem_value *ucontrol)
4648 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4649 struct alc_spec *spec = codec->spec;
4650 *ucontrol->value.integer.value = spec->master_sw;
4654 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4655 struct snd_ctl_elem_value *ucontrol)
4657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4658 struct alc_spec *spec = codec->spec;
4659 int val = !!*ucontrol->value.integer.value;
4660 hda_nid_t hp, line, mono;
4662 if (val == spec->master_sw)
4664 spec->master_sw = val;
4665 hp = (kcontrol->private_value >> 16) & 0xff;
4666 line = (kcontrol->private_value >> 8) & 0xff;
4667 mono = kcontrol->private_value & 0xff;
4668 alc260_hp_master_update(codec, hp, line, mono);
4672 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4675 .name = "Master Playback Switch",
4676 .info = snd_ctl_boolean_mono_info,
4677 .get = alc260_hp_master_sw_get,
4678 .put = alc260_hp_master_sw_put,
4679 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4681 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4682 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4684 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4687 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4691 static struct hda_verb alc260_hp_unsol_verbs[] = {
4692 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4696 static void alc260_hp_automute(struct hda_codec *codec)
4698 struct alc_spec *spec = codec->spec;
4699 unsigned int present;
4701 present = snd_hda_codec_read(codec, 0x10, 0,
4702 AC_VERB_GET_PIN_SENSE, 0);
4703 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4704 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4707 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4709 if ((res >> 26) == ALC880_HP_EVENT)
4710 alc260_hp_automute(codec);
4713 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4716 .name = "Master Playback Switch",
4717 .info = snd_ctl_boolean_mono_info,
4718 .get = alc260_hp_master_sw_get,
4719 .put = alc260_hp_master_sw_put,
4720 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4722 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4723 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4724 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4725 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4726 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4727 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4728 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4729 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4733 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4734 .ops = &snd_hda_bind_vol,
4736 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4737 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4738 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4743 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4744 .ops = &snd_hda_bind_sw,
4746 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4747 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4752 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4753 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4754 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4755 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4756 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4760 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4761 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4765 static void alc260_hp_3013_automute(struct hda_codec *codec)
4767 struct alc_spec *spec = codec->spec;
4768 unsigned int present;
4770 present = snd_hda_codec_read(codec, 0x15, 0,
4771 AC_VERB_GET_PIN_SENSE, 0);
4772 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4773 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4776 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4779 if ((res >> 26) == ALC880_HP_EVENT)
4780 alc260_hp_3013_automute(codec);
4783 static void alc260_hp_3012_automute(struct hda_codec *codec)
4785 unsigned int present, bits;
4787 present = snd_hda_codec_read(codec, 0x10, 0,
4788 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4790 bits = present ? 0 : PIN_OUT;
4791 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4793 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4795 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4799 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4802 if ((res >> 26) == ALC880_HP_EVENT)
4803 alc260_hp_3012_automute(codec);
4806 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4807 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4809 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4811 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4812 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4813 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4814 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4815 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4816 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4817 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4818 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4819 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4823 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4824 * versions of the ALC260 don't act on requests to enable mic bias from NID
4825 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4826 * datasheet doesn't mention this restriction. At this stage it's not clear
4827 * whether this behaviour is intentional or is a hardware bug in chip
4828 * revisions available in early 2006. Therefore for now allow the
4829 * "Headphone Jack Mode" control to span all choices, but if it turns out
4830 * that the lack of mic bias for this NID is intentional we could change the
4831 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4833 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4834 * don't appear to make the mic bias available from the "line" jack, even
4835 * though the NID used for this jack (0x14) can supply it. The theory is
4836 * that perhaps Acer have included blocking capacitors between the ALC260
4837 * and the output jack. If this turns out to be the case for all such
4838 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4839 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4841 * The C20x Tablet series have a mono internal speaker which is controlled
4842 * via the chip's Mono sum widget and pin complex, so include the necessary
4843 * controls for such models. On models without a "mono speaker" the control
4844 * won't do anything.
4846 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4847 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4848 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4849 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4850 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4852 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4854 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4855 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4857 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4858 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4859 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4860 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4861 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4865 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4867 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4868 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4869 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4870 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4871 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4872 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4873 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4877 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4878 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4880 static struct snd_kcontrol_new alc260_will_mixer[] = {
4881 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4882 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4884 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4885 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4886 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4887 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4888 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4889 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4890 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4894 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4895 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4897 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4898 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4899 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4901 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4902 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4903 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4904 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4905 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4906 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4907 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4912 * initialization verbs
4914 static struct hda_verb alc260_init_verbs[] = {
4915 /* Line In pin widget for input */
4916 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4917 /* CD pin widget for input */
4918 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4919 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4920 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4921 /* Mic2 (front panel) pin widget for input and vref at 80% */
4922 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4923 /* LINE-2 is used for line-out in rear */
4924 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4925 /* select line-out */
4926 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4928 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4930 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4932 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4933 /* mute capture amp left and right */
4934 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4935 /* set connection select to line in (default select for this ADC) */
4936 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4937 /* mute capture amp left and right */
4938 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4939 /* set connection select to line in (default select for this ADC) */
4940 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4941 /* set vol=0 Line-Out mixer amp left and right */
4942 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4943 /* unmute pin widget amp left and right (no gain on this amp) */
4944 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4945 /* set vol=0 HP mixer amp left and right */
4946 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4947 /* unmute pin widget amp left and right (no gain on this amp) */
4948 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4949 /* set vol=0 Mono mixer amp left and right */
4950 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4951 /* unmute pin widget amp left and right (no gain on this amp) */
4952 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4953 /* unmute LINE-2 out pin */
4954 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4955 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4958 /* mute analog inputs */
4959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4964 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4965 /* mute Front out path */
4966 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4968 /* mute Headphone out path */
4969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4971 /* mute Mono out path */
4972 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4973 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4977 #if 0 /* should be identical with alc260_init_verbs? */
4978 static struct hda_verb alc260_hp_init_verbs[] = {
4979 /* Headphone and output */
4980 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4982 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4983 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4985 /* Mic2 (front panel) pin widget for input and vref at 80% */
4986 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4987 /* Line In pin widget for input */
4988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4989 /* Line-2 pin widget for output */
4990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4991 /* CD pin widget for input */
4992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4993 /* unmute amp left and right */
4994 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4995 /* set connection select to line in (default select for this ADC) */
4996 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4997 /* unmute Line-Out mixer amp left and right (volume = 0) */
4998 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4999 /* mute pin widget amp left and right (no gain on this amp) */
5000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5001 /* unmute HP mixer amp left and right (volume = 0) */
5002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5003 /* mute pin widget amp left and right (no gain on this amp) */
5004 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5005 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5008 /* mute analog inputs */
5009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5014 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5015 /* Unmute Front out path */
5016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5018 /* Unmute Headphone out path */
5019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5021 /* Unmute Mono out path */
5022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5028 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5029 /* Line out and output */
5030 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5032 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5033 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5034 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5035 /* Mic2 (front panel) pin widget for input and vref at 80% */
5036 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5037 /* Line In pin widget for input */
5038 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5039 /* Headphone pin widget for output */
5040 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5041 /* CD pin widget for input */
5042 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5043 /* unmute amp left and right */
5044 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5045 /* set connection select to line in (default select for this ADC) */
5046 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5047 /* unmute Line-Out mixer amp left and right (volume = 0) */
5048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5049 /* mute pin widget amp left and right (no gain on this amp) */
5050 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5051 /* unmute HP mixer amp left and right (volume = 0) */
5052 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5053 /* mute pin widget amp left and right (no gain on this amp) */
5054 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5055 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5058 /* mute analog inputs */
5059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5063 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5064 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5065 /* Unmute Front out path */
5066 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5068 /* Unmute Headphone out path */
5069 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5071 /* Unmute Mono out path */
5072 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5077 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5078 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5079 * audio = 0x16, internal speaker = 0x10.
5081 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5082 /* Disable all GPIOs */
5083 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5084 /* Internal speaker is connected to headphone pin */
5085 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5086 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5087 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5088 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5089 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5090 /* Ensure all other unused pins are disabled and muted. */
5091 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5092 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5093 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5094 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5095 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5096 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5100 /* Disable digital (SPDIF) pins */
5101 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5102 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5104 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5105 * when acting as an output.
5107 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5109 /* Start with output sum widgets muted and their output gains at min */
5110 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5111 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5112 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5113 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5114 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5115 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5116 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5117 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5118 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5120 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5121 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5122 /* Unmute Line1 pin widget output buffer since it starts as an output.
5123 * If the pin mode is changed by the user the pin mode control will
5124 * take care of enabling the pin's input/output buffers as needed.
5125 * Therefore there's no need to enable the input buffer at this
5128 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5129 /* Unmute input buffer of pin widget used for Line-in (no equiv
5132 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5134 /* Mute capture amp left and right */
5135 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5136 /* Set ADC connection select to match default mixer setting - line
5139 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5141 /* Do the same for the second ADC: mute capture input amp and
5142 * set ADC connection to line in (on mic1 pin)
5144 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5145 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5147 /* Mute all inputs to mixer widget (even unconnected ones) */
5148 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5160 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5161 * similar laptops (adapted from Fujitsu init verbs).
5163 static struct hda_verb alc260_acer_init_verbs[] = {
5164 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5165 * the headphone jack. Turn this on and rely on the standard mute
5166 * methods whenever the user wants to turn these outputs off.
5168 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5169 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5170 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5171 /* Internal speaker/Headphone jack is connected to Line-out pin */
5172 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5173 /* Internal microphone/Mic jack is connected to Mic1 pin */
5174 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5175 /* Line In jack is connected to Line1 pin */
5176 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5177 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5178 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5179 /* Ensure all other unused pins are disabled and muted. */
5180 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5181 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5182 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5183 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5184 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5185 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5186 /* Disable digital (SPDIF) pins */
5187 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5188 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5190 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5191 * bus when acting as outputs.
5193 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5194 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5196 /* Start with output sum widgets muted and their output gains at min */
5197 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5198 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5199 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5201 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5203 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5204 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5205 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5207 /* Unmute Line-out pin widget amp left and right
5208 * (no equiv mixer ctrl)
5210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5211 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5212 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5213 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5214 * inputs. If the pin mode is changed by the user the pin mode control
5215 * will take care of enabling the pin's input/output buffers as needed.
5216 * Therefore there's no need to enable the input buffer at this
5219 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5222 /* Mute capture amp left and right */
5223 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5224 /* Set ADC connection select to match default mixer setting - mic
5227 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5229 /* Do similar with the second ADC: mute capture input amp and
5230 * set ADC connection to mic to match ALSA's default state.
5232 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5233 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5235 /* Mute all inputs to mixer widget (even unconnected ones) */
5236 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5237 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5238 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5239 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5241 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5243 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5248 /* Initialisation sequence for Maxdata Favorit 100XS
5249 * (adapted from Acer init verbs).
5251 static struct hda_verb alc260_favorit100_init_verbs[] = {
5252 /* GPIO 0 enables the output jack.
5253 * Turn this on and rely on the standard mute
5254 * methods whenever the user wants to turn these outputs off.
5256 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5257 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5258 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5259 /* Line/Mic input jack is connected to Mic1 pin */
5260 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5261 /* Ensure all other unused pins are disabled and muted. */
5262 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5263 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5264 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5265 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5266 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5267 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5272 /* Disable digital (SPDIF) pins */
5273 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5274 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5276 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5277 * bus when acting as outputs.
5279 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5280 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5282 /* Start with output sum widgets muted and their output gains at min */
5283 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5284 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5286 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5287 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5289 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5290 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5291 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5293 /* Unmute Line-out pin widget amp left and right
5294 * (no equiv mixer ctrl)
5296 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5297 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5298 * inputs. If the pin mode is changed by the user the pin mode control
5299 * will take care of enabling the pin's input/output buffers as needed.
5300 * Therefore there's no need to enable the input buffer at this
5303 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5305 /* Mute capture amp left and right */
5306 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5307 /* Set ADC connection select to match default mixer setting - mic
5310 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5312 /* Do similar with the second ADC: mute capture input amp and
5313 * set ADC connection to mic to match ALSA's default state.
5315 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5316 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5318 /* Mute all inputs to mixer widget (even unconnected ones) */
5319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5331 static struct hda_verb alc260_will_verbs[] = {
5332 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5333 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5334 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5335 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5336 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5337 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5341 static struct hda_verb alc260_replacer_672v_verbs[] = {
5342 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5343 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5344 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5346 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5347 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5348 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5350 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5354 /* toggle speaker-output according to the hp-jack state */
5355 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5357 unsigned int present;
5359 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5360 present = snd_hda_codec_read(codec, 0x0f, 0,
5361 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5363 snd_hda_codec_write_cache(codec, 0x01, 0,
5364 AC_VERB_SET_GPIO_DATA, 1);
5365 snd_hda_codec_write_cache(codec, 0x0f, 0,
5366 AC_VERB_SET_PIN_WIDGET_CONTROL,
5369 snd_hda_codec_write_cache(codec, 0x01, 0,
5370 AC_VERB_SET_GPIO_DATA, 0);
5371 snd_hda_codec_write_cache(codec, 0x0f, 0,
5372 AC_VERB_SET_PIN_WIDGET_CONTROL,
5377 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5380 if ((res >> 26) == ALC880_HP_EVENT)
5381 alc260_replacer_672v_automute(codec);
5384 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5385 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5386 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5387 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5388 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5389 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5390 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5391 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5392 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5393 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5394 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5398 /* Test configuration for debugging, modelled after the ALC880 test
5401 #ifdef CONFIG_SND_DEBUG
5402 static hda_nid_t alc260_test_dac_nids[1] = {
5405 static hda_nid_t alc260_test_adc_nids[2] = {
5408 /* For testing the ALC260, each input MUX needs its own definition since
5409 * the signal assignments are different. This assumes that the first ADC
5412 static struct hda_input_mux alc260_test_capture_sources[2] = {
5416 { "MIC1 pin", 0x0 },
5417 { "MIC2 pin", 0x1 },
5418 { "LINE1 pin", 0x2 },
5419 { "LINE2 pin", 0x3 },
5421 { "LINE-OUT pin", 0x5 },
5422 { "HP-OUT pin", 0x6 },
5428 { "MIC1 pin", 0x0 },
5429 { "MIC2 pin", 0x1 },
5430 { "LINE1 pin", 0x2 },
5431 { "LINE2 pin", 0x3 },
5434 { "LINE-OUT pin", 0x6 },
5435 { "HP-OUT pin", 0x7 },
5439 static struct snd_kcontrol_new alc260_test_mixer[] = {
5440 /* Output driver widgets */
5441 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5442 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5443 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5444 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5445 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5446 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5448 /* Modes for retasking pin widgets
5449 * Note: the ALC260 doesn't seem to act on requests to enable mic
5450 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5451 * mention this restriction. At this stage it's not clear whether
5452 * this behaviour is intentional or is a hardware bug in chip
5453 * revisions available at least up until early 2006. Therefore for
5454 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5455 * choices, but if it turns out that the lack of mic bias for these
5456 * NIDs is intentional we could change their modes from
5457 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5459 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5460 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5461 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5462 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5463 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5464 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5466 /* Loopback mixer controls */
5467 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5468 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5469 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5470 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5471 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5472 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5473 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5474 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5475 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5476 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5477 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5478 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5479 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5480 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5482 /* Controls for GPIO pins, assuming they are configured as outputs */
5483 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5484 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5485 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5486 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5488 /* Switches to allow the digital IO pins to be enabled. The datasheet
5489 * is ambigious as to which NID is which; testing on laptops which
5490 * make this output available should provide clarification.
5492 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5493 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5495 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5496 * this output to turn on an external amplifier.
5498 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5499 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5503 static struct hda_verb alc260_test_init_verbs[] = {
5504 /* Enable all GPIOs as outputs with an initial value of 0 */
5505 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5506 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5507 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5509 /* Enable retasking pins as output, initially without power amp */
5510 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5511 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5514 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5515 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5517 /* Disable digital (SPDIF) pins initially, but users can enable
5518 * them via a mixer switch. In the case of SPDIF-out, this initverb
5519 * payload also sets the generation to 0, output to be in "consumer"
5520 * PCM format, copyright asserted, no pre-emphasis and no validity
5523 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5524 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5526 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5527 * OUT1 sum bus when acting as an output.
5529 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5530 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5531 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5532 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5534 /* Start with output sum widgets muted and their output gains at min */
5535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5536 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5539 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5541 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5542 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5543 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5545 /* Unmute retasking pin widget output buffers since the default
5546 * state appears to be output. As the pin mode is changed by the
5547 * user the pin mode control will take care of enabling the pin's
5548 * input/output buffers as needed.
5550 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5551 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5554 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5555 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5556 /* Also unmute the mono-out pin widget */
5557 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5559 /* Mute capture amp left and right */
5560 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5561 /* Set ADC connection select to match default mixer setting (mic1
5564 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5566 /* Do the same for the second ADC: mute capture input amp and
5567 * set ADC connection to mic1 pin
5569 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5570 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5572 /* Mute all inputs to mixer widget (even unconnected ones) */
5573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5580 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5586 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5587 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5589 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5590 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5593 * for BIOS auto-configuration
5596 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5597 const char *pfx, int *vol_bits)
5600 unsigned long vol_val, sw_val;
5604 if (nid >= 0x0f && nid < 0x11) {
5605 nid_vol = nid - 0x7;
5606 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5607 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5608 } else if (nid == 0x11) {
5609 nid_vol = nid - 0x7;
5610 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5611 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5612 } else if (nid >= 0x12 && nid <= 0x15) {
5614 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5615 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5619 if (!(*vol_bits & (1 << nid_vol))) {
5620 /* first control for the volume widget */
5621 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5622 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5625 *vol_bits |= (1 << nid_vol);
5627 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5628 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5634 /* add playback controls from the parsed DAC table */
5635 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5636 const struct auto_pin_cfg *cfg)
5642 spec->multiout.num_dacs = 1;
5643 spec->multiout.dac_nids = spec->private_dac_nids;
5644 spec->multiout.dac_nids[0] = 0x02;
5646 nid = cfg->line_out_pins[0];
5648 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5653 nid = cfg->speaker_pins[0];
5655 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5660 nid = cfg->hp_pins[0];
5662 err = alc260_add_playback_controls(spec, nid, "Headphone",
5670 /* create playback/capture controls for input pins */
5671 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5672 const struct auto_pin_cfg *cfg)
5674 struct hda_input_mux *imux = &spec->private_imux[0];
5677 for (i = 0; i < AUTO_PIN_LAST; i++) {
5678 if (cfg->input_pins[i] >= 0x12) {
5679 idx = cfg->input_pins[i] - 0x12;
5680 err = new_analog_input(spec, cfg->input_pins[i],
5681 auto_pin_cfg_labels[i], idx,
5685 imux->items[imux->num_items].label =
5686 auto_pin_cfg_labels[i];
5687 imux->items[imux->num_items].index = idx;
5690 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5691 idx = cfg->input_pins[i] - 0x09;
5692 err = new_analog_input(spec, cfg->input_pins[i],
5693 auto_pin_cfg_labels[i], idx,
5697 imux->items[imux->num_items].label =
5698 auto_pin_cfg_labels[i];
5699 imux->items[imux->num_items].index = idx;
5706 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5707 hda_nid_t nid, int pin_type,
5710 alc_set_pin_output(codec, nid, pin_type);
5711 /* need the manual connection? */
5713 int idx = nid - 0x12;
5714 snd_hda_codec_write(codec, idx + 0x0b, 0,
5715 AC_VERB_SET_CONNECT_SEL, sel_idx);
5719 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5721 struct alc_spec *spec = codec->spec;
5724 nid = spec->autocfg.line_out_pins[0];
5726 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5727 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5730 nid = spec->autocfg.speaker_pins[0];
5732 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5734 nid = spec->autocfg.hp_pins[0];
5736 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5739 #define ALC260_PIN_CD_NID 0x16
5740 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5742 struct alc_spec *spec = codec->spec;
5745 for (i = 0; i < AUTO_PIN_LAST; i++) {
5746 hda_nid_t nid = spec->autocfg.input_pins[i];
5748 alc_set_input_pin(codec, nid, i);
5749 if (nid != ALC260_PIN_CD_NID &&
5750 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5751 snd_hda_codec_write(codec, nid, 0,
5752 AC_VERB_SET_AMP_GAIN_MUTE,
5759 * generic initialization of ADC, input mixers and output mixers
5761 static struct hda_verb alc260_volume_init_verbs[] = {
5763 * Unmute ADC0-1 and set the default input to mic-in
5765 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5766 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5767 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5768 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5770 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5772 * Note: PASD motherboards uses the Line In 2 as the input for
5773 * front panel mic (mic 2)
5775 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5776 /* mute analog inputs */
5777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5784 * Set up output mixers (0x08 - 0x0a)
5786 /* set vol=0 to output mixers */
5787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5789 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5790 /* set up input amps for analog loopback */
5791 /* Amp Indices: DAC = 0, mixer = 1 */
5792 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5793 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5795 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5796 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5797 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5802 static int alc260_parse_auto_config(struct hda_codec *codec)
5804 struct alc_spec *spec = codec->spec;
5806 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5808 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5812 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5815 if (!spec->kctls.list)
5816 return 0; /* can't find valid BIOS pin config */
5817 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5821 spec->multiout.max_channels = 2;
5823 if (spec->autocfg.dig_outs)
5824 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5825 if (spec->kctls.list)
5826 add_mixer(spec, spec->kctls.list);
5828 add_verb(spec, alc260_volume_init_verbs);
5830 spec->num_mux_defs = 1;
5831 spec->input_mux = &spec->private_imux[0];
5833 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5838 /* additional initialization for auto-configuration model */
5839 static void alc260_auto_init(struct hda_codec *codec)
5841 struct alc_spec *spec = codec->spec;
5842 alc260_auto_init_multi_out(codec);
5843 alc260_auto_init_analog_input(codec);
5844 if (spec->unsol_event)
5845 alc_inithook(codec);
5848 #ifdef CONFIG_SND_HDA_POWER_SAVE
5849 static struct hda_amp_list alc260_loopbacks[] = {
5850 { 0x07, HDA_INPUT, 0 },
5851 { 0x07, HDA_INPUT, 1 },
5852 { 0x07, HDA_INPUT, 2 },
5853 { 0x07, HDA_INPUT, 3 },
5854 { 0x07, HDA_INPUT, 4 },
5860 * ALC260 configurations
5862 static const char *alc260_models[ALC260_MODEL_LAST] = {
5863 [ALC260_BASIC] = "basic",
5865 [ALC260_HP_3013] = "hp-3013",
5866 [ALC260_HP_DC7600] = "hp-dc7600",
5867 [ALC260_FUJITSU_S702X] = "fujitsu",
5868 [ALC260_ACER] = "acer",
5869 [ALC260_WILL] = "will",
5870 [ALC260_REPLACER_672V] = "replacer",
5871 [ALC260_FAVORIT100] = "favorit100",
5872 #ifdef CONFIG_SND_DEBUG
5873 [ALC260_TEST] = "test",
5875 [ALC260_AUTO] = "auto",
5878 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5879 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5880 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5881 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5882 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5883 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5884 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5885 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5886 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5887 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5888 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5889 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5890 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5891 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5892 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5893 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5894 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5895 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5896 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5897 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5901 static struct alc_config_preset alc260_presets[] = {
5903 .mixers = { alc260_base_output_mixer,
5904 alc260_input_mixer },
5905 .init_verbs = { alc260_init_verbs },
5906 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5907 .dac_nids = alc260_dac_nids,
5908 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5909 .adc_nids = alc260_adc_nids,
5910 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5911 .channel_mode = alc260_modes,
5912 .input_mux = &alc260_capture_source,
5915 .mixers = { alc260_hp_output_mixer,
5916 alc260_input_mixer },
5917 .init_verbs = { alc260_init_verbs,
5918 alc260_hp_unsol_verbs },
5919 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5920 .dac_nids = alc260_dac_nids,
5921 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5922 .adc_nids = alc260_adc_nids_alt,
5923 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5924 .channel_mode = alc260_modes,
5925 .input_mux = &alc260_capture_source,
5926 .unsol_event = alc260_hp_unsol_event,
5927 .init_hook = alc260_hp_automute,
5929 [ALC260_HP_DC7600] = {
5930 .mixers = { alc260_hp_dc7600_mixer,
5931 alc260_input_mixer },
5932 .init_verbs = { alc260_init_verbs,
5933 alc260_hp_dc7600_verbs },
5934 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5935 .dac_nids = alc260_dac_nids,
5936 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5937 .adc_nids = alc260_adc_nids_alt,
5938 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5939 .channel_mode = alc260_modes,
5940 .input_mux = &alc260_capture_source,
5941 .unsol_event = alc260_hp_3012_unsol_event,
5942 .init_hook = alc260_hp_3012_automute,
5944 [ALC260_HP_3013] = {
5945 .mixers = { alc260_hp_3013_mixer,
5946 alc260_input_mixer },
5947 .init_verbs = { alc260_hp_3013_init_verbs,
5948 alc260_hp_3013_unsol_verbs },
5949 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5950 .dac_nids = alc260_dac_nids,
5951 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5952 .adc_nids = alc260_adc_nids_alt,
5953 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5954 .channel_mode = alc260_modes,
5955 .input_mux = &alc260_capture_source,
5956 .unsol_event = alc260_hp_3013_unsol_event,
5957 .init_hook = alc260_hp_3013_automute,
5959 [ALC260_FUJITSU_S702X] = {
5960 .mixers = { alc260_fujitsu_mixer },
5961 .init_verbs = { alc260_fujitsu_init_verbs },
5962 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5963 .dac_nids = alc260_dac_nids,
5964 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5965 .adc_nids = alc260_dual_adc_nids,
5966 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5967 .channel_mode = alc260_modes,
5968 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5969 .input_mux = alc260_fujitsu_capture_sources,
5972 .mixers = { alc260_acer_mixer },
5973 .init_verbs = { alc260_acer_init_verbs },
5974 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5975 .dac_nids = alc260_dac_nids,
5976 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5977 .adc_nids = alc260_dual_adc_nids,
5978 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5979 .channel_mode = alc260_modes,
5980 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5981 .input_mux = alc260_acer_capture_sources,
5983 [ALC260_FAVORIT100] = {
5984 .mixers = { alc260_favorit100_mixer },
5985 .init_verbs = { alc260_favorit100_init_verbs },
5986 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5987 .dac_nids = alc260_dac_nids,
5988 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5989 .adc_nids = alc260_dual_adc_nids,
5990 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5991 .channel_mode = alc260_modes,
5992 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5993 .input_mux = alc260_favorit100_capture_sources,
5996 .mixers = { alc260_will_mixer },
5997 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5998 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5999 .dac_nids = alc260_dac_nids,
6000 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6001 .adc_nids = alc260_adc_nids,
6002 .dig_out_nid = ALC260_DIGOUT_NID,
6003 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6004 .channel_mode = alc260_modes,
6005 .input_mux = &alc260_capture_source,
6007 [ALC260_REPLACER_672V] = {
6008 .mixers = { alc260_replacer_672v_mixer },
6009 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6010 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6011 .dac_nids = alc260_dac_nids,
6012 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6013 .adc_nids = alc260_adc_nids,
6014 .dig_out_nid = ALC260_DIGOUT_NID,
6015 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6016 .channel_mode = alc260_modes,
6017 .input_mux = &alc260_capture_source,
6018 .unsol_event = alc260_replacer_672v_unsol_event,
6019 .init_hook = alc260_replacer_672v_automute,
6021 #ifdef CONFIG_SND_DEBUG
6023 .mixers = { alc260_test_mixer },
6024 .init_verbs = { alc260_test_init_verbs },
6025 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6026 .dac_nids = alc260_test_dac_nids,
6027 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6028 .adc_nids = alc260_test_adc_nids,
6029 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6030 .channel_mode = alc260_modes,
6031 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6032 .input_mux = alc260_test_capture_sources,
6037 static int patch_alc260(struct hda_codec *codec)
6039 struct alc_spec *spec;
6040 int err, board_config;
6042 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6048 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6051 if (board_config < 0) {
6052 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
6053 "trying auto-probe from BIOS...\n");
6054 board_config = ALC260_AUTO;
6057 if (board_config == ALC260_AUTO) {
6058 /* automatic parse from the BIOS config */
6059 err = alc260_parse_auto_config(codec);
6065 "hda_codec: Cannot set up configuration "
6066 "from BIOS. Using base mode...\n");
6067 board_config = ALC260_BASIC;
6071 err = snd_hda_attach_beep_device(codec, 0x1);
6077 if (board_config != ALC260_AUTO)
6078 setup_preset(spec, &alc260_presets[board_config]);
6080 spec->stream_name_analog = "ALC260 Analog";
6081 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6082 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6084 spec->stream_name_digital = "ALC260 Digital";
6085 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6086 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6088 if (!spec->adc_nids && spec->input_mux) {
6089 /* check whether NID 0x04 is valid */
6090 unsigned int wcap = get_wcaps(codec, 0x04);
6091 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6093 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6094 spec->adc_nids = alc260_adc_nids_alt;
6095 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6097 spec->adc_nids = alc260_adc_nids;
6098 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6101 set_capture_mixer(spec);
6102 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6104 spec->vmaster_nid = 0x08;
6106 codec->patch_ops = alc_patch_ops;
6107 if (board_config == ALC260_AUTO)
6108 spec->init_hook = alc260_auto_init;
6109 #ifdef CONFIG_SND_HDA_POWER_SAVE
6110 if (!spec->loopback.amplist)
6111 spec->loopback.amplist = alc260_loopbacks;
6113 codec->proc_widget_hook = print_realtek_coef;
6122 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6123 * configuration. Each pin widget can choose any input DACs and a mixer.
6124 * Each ADC is connected from a mixer of all inputs. This makes possible
6125 * 6-channel independent captures.
6127 * In addition, an independent DAC for the multi-playback (not used in this
6130 #define ALC882_DIGOUT_NID 0x06
6131 #define ALC882_DIGIN_NID 0x0a
6133 static struct hda_channel_mode alc882_ch_modes[1] = {
6137 static hda_nid_t alc882_dac_nids[4] = {
6138 /* front, rear, clfe, rear_surr */
6139 0x02, 0x03, 0x04, 0x05
6142 /* identical with ALC880 */
6143 #define alc882_adc_nids alc880_adc_nids
6144 #define alc882_adc_nids_alt alc880_adc_nids_alt
6146 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6147 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6150 /* FIXME: should be a matrix-type input source selection */
6152 static struct hda_input_mux alc882_capture_source = {
6156 { "Front Mic", 0x1 },
6162 static struct hda_input_mux mb5_capture_source = {
6174 static struct hda_verb alc882_3ST_ch2_init[] = {
6175 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6176 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6177 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6178 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6185 static struct hda_verb alc882_3ST_ch6_init[] = {
6186 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6187 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6188 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6189 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6190 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6191 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6195 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6196 { 2, alc882_3ST_ch2_init },
6197 { 6, alc882_3ST_ch6_init },
6203 static struct hda_verb alc882_sixstack_ch6_init[] = {
6204 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6205 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6206 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6207 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6214 static struct hda_verb alc882_sixstack_ch8_init[] = {
6215 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6216 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6217 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6218 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6222 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6223 { 6, alc882_sixstack_ch6_init },
6224 { 8, alc882_sixstack_ch8_init },
6228 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6234 static struct hda_verb alc885_mbp_ch2_init[] = {
6235 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6236 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6237 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6244 static struct hda_verb alc885_mbp_ch6_init[] = {
6245 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6246 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6247 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6248 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6249 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6253 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6254 { 2, alc885_mbp_ch2_init },
6255 { 6, alc885_mbp_ch6_init },
6259 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6260 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6262 static struct snd_kcontrol_new alc882_base_mixer[] = {
6263 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6264 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6265 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6266 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6267 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6268 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6269 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6270 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6271 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6272 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6276 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6277 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6279 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6280 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6281 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6282 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6283 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6287 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6289 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6290 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6291 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6292 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6293 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6295 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6296 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6297 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6301 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6302 HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6303 HDA_BIND_MUTE ("Front Playback Switch", 0x0d, 0x02, HDA_INPUT),
6304 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6305 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
6306 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6307 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6309 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6310 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6311 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6314 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6315 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6316 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6317 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6318 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6319 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6320 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6323 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6327 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6328 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6329 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6330 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6336 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6337 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6338 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6339 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6340 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6344 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6345 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6347 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6349 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6351 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6352 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6353 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6354 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6355 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6356 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6357 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6358 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6359 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6360 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6364 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6365 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6366 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6367 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6368 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6369 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6370 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6371 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6372 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6373 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6378 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6381 .name = "Channel Mode",
6382 .info = alc_ch_mode_info,
6383 .get = alc_ch_mode_get,
6384 .put = alc_ch_mode_put,
6389 static struct hda_verb alc882_init_verbs[] = {
6390 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6399 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6401 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6403 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6404 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6405 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6407 /* Front Pin: output 0 (0x0c) */
6408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6409 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6410 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6411 /* Rear Pin: output 1 (0x0d) */
6412 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6413 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6414 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6415 /* CLFE Pin: output 2 (0x0e) */
6416 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6417 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6418 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6419 /* Side Pin: output 3 (0x0f) */
6420 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6421 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6422 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6423 /* Mic (rear) pin: input vref at 80% */
6424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6425 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6426 /* Front Mic pin: input vref at 80% */
6427 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6428 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6429 /* Line In pin: input */
6430 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6431 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6432 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6434 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6435 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6436 /* CD pin widget for input */
6437 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6439 /* FIXME: use matrix-type input source selection */
6440 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6441 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6456 /* ADC1: mute amp left and right */
6457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6458 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6459 /* ADC2: mute amp left and right */
6460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6461 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6462 /* ADC3: mute amp left and right */
6463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6469 static struct hda_verb alc882_eapd_verbs[] = {
6470 /* change to EAPD mode */
6471 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6472 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6477 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6478 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6479 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6483 /* FIXME: this looks suspicious...
6484 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6485 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6490 static struct hda_verb alc882_macpro_init_verbs[] = {
6491 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6492 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6493 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6495 /* Front Pin: output 0 (0x0c) */
6496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6498 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6499 /* Front Mic pin: input vref at 80% */
6500 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6501 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6502 /* Speaker: output */
6503 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6504 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6505 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6506 /* Headphone output (output 0 - 0x0c) */
6507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6509 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6511 /* FIXME: use matrix-type input source selection */
6512 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6513 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6514 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6528 /* ADC1: mute amp left and right */
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6530 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6531 /* ADC2: mute amp left and right */
6532 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6534 /* ADC3: mute amp left and right */
6535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6536 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6542 static struct hda_verb alc885_mb5_init_verbs[] = {
6544 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6546 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6548 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6551 /* Front Pin: output 0 (0x0d) */
6552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6554 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},
6555 /* HP Pin: output 0 (0x0c) */
6556 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6557 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6558 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6559 /* Front Mic pin: input vref at 80% */
6560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6561 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6569 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6573 /* Macbook Pro rev3 */
6574 static struct hda_verb alc885_mbp3_init_verbs[] = {
6575 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6576 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6580 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6581 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6583 /* Front Pin: output 0 (0x0c) */
6584 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6585 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6586 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6587 /* HP Pin: output 0 (0x0d) */
6588 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6591 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6592 /* Mic (rear) pin: input vref at 80% */
6593 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6594 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6595 /* Front Mic pin: input vref at 80% */
6596 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6597 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6598 /* Line In pin: use output 1 when in LineOut mode */
6599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6601 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6603 /* FIXME: use matrix-type input source selection */
6604 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6605 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6606 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6611 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6616 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6620 /* ADC1: mute amp left and right */
6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6622 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6623 /* ADC2: mute amp left and right */
6624 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6625 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6626 /* ADC3: mute amp left and right */
6627 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6628 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6633 /* iMac 24 mixer. */
6634 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6635 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6636 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6640 /* iMac 24 init verbs. */
6641 static struct hda_verb alc885_imac24_init_verbs[] = {
6642 /* Internal speakers: output 0 (0x0c) */
6643 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6644 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6645 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6646 /* Internal speakers: output 0 (0x0c) */
6647 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6648 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6649 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6650 /* Headphone: output 0 (0x0c) */
6651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6652 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6653 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6654 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6655 /* Front Mic: input vref at 80% */
6656 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6657 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6661 /* Toggle speaker-output according to the hp-jack state */
6662 static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
6664 struct alc_spec *spec = codec->spec;
6666 spec->autocfg.hp_pins[0] = 0x14;
6667 spec->autocfg.speaker_pins[0] = 0x18;
6668 spec->autocfg.speaker_pins[1] = 0x1a;
6669 alc_automute_amp(codec);
6672 static void alc885_mbp3_init_hook(struct hda_codec *codec)
6674 struct alc_spec *spec = codec->spec;
6676 spec->autocfg.hp_pins[0] = 0x15;
6677 spec->autocfg.speaker_pins[0] = 0x14;
6678 alc_automute_amp(codec);
6682 static struct hda_verb alc882_targa_verbs[] = {
6683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6686 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6687 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6689 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6690 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6691 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6693 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6694 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6695 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6696 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6700 /* toggle speaker-output according to the hp-jack state */
6701 static void alc882_targa_automute(struct hda_codec *codec)
6703 struct alc_spec *spec = codec->spec;
6704 alc_automute_amp(codec);
6705 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6706 spec->jack_present ? 1 : 3);
6709 static void alc882_targa_init_hook(struct hda_codec *codec)
6711 struct alc_spec *spec = codec->spec;
6713 spec->autocfg.hp_pins[0] = 0x14;
6714 spec->autocfg.speaker_pins[0] = 0x1b;
6715 alc882_targa_automute(codec);
6718 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6720 if ((res >> 26) == ALC880_HP_EVENT)
6721 alc882_targa_automute(codec);
6724 static struct hda_verb alc882_asus_a7j_verbs[] = {
6725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6728 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6730 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6732 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6733 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6734 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6736 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6737 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6738 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6742 static struct hda_verb alc882_asus_a7m_verbs[] = {
6743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6746 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6748 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6750 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6751 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6752 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6754 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6755 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6756 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6760 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6762 unsigned int gpiostate, gpiomask, gpiodir;
6764 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6765 AC_VERB_GET_GPIO_DATA, 0);
6768 gpiostate |= (1 << pin);
6770 gpiostate &= ~(1 << pin);
6772 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6773 AC_VERB_GET_GPIO_MASK, 0);
6774 gpiomask |= (1 << pin);
6776 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6777 AC_VERB_GET_GPIO_DIRECTION, 0);
6778 gpiodir |= (1 << pin);
6781 snd_hda_codec_write(codec, codec->afg, 0,
6782 AC_VERB_SET_GPIO_MASK, gpiomask);
6783 snd_hda_codec_write(codec, codec->afg, 0,
6784 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6788 snd_hda_codec_write(codec, codec->afg, 0,
6789 AC_VERB_SET_GPIO_DATA, gpiostate);
6792 /* set up GPIO at initialization */
6793 static void alc885_macpro_init_hook(struct hda_codec *codec)
6795 alc882_gpio_mute(codec, 0, 0);
6796 alc882_gpio_mute(codec, 1, 0);
6799 /* set up GPIO and update auto-muting at initialization */
6800 static void alc885_imac24_init_hook(struct hda_codec *codec)
6802 alc885_macpro_init_hook(codec);
6803 alc885_imac24_automute_init_hook(codec);
6807 * generic initialization of ADC, input mixers and output mixers
6809 static struct hda_verb alc882_auto_init_verbs[] = {
6811 * Unmute ADC0-2 and set the default input to mic-in
6813 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6814 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6815 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6816 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6817 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6818 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6820 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6822 * Note: PASD motherboards uses the Line In 2 as the input for
6823 * front panel mic (mic 2)
6825 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6826 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6833 * Set up output mixers (0x0c - 0x0f)
6835 /* set vol=0 to output mixers */
6836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6838 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6839 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6840 /* set up input amps for analog loopback */
6841 /* Amp Indices: DAC = 0, mixer = 1 */
6842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6844 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6845 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6847 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6850 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6851 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6853 /* FIXME: use matrix-type input source selection */
6854 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6855 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6856 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6857 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6858 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6859 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6861 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6862 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6863 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6864 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6866 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6867 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6868 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6869 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6874 #ifdef CONFIG_SND_HDA_POWER_SAVE
6875 #define alc882_loopbacks alc880_loopbacks
6878 /* pcm configuration: identiacal with ALC880 */
6879 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6880 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6881 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6882 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6885 * configuration and preset
6887 static const char *alc882_models[ALC882_MODEL_LAST] = {
6888 [ALC882_3ST_DIG] = "3stack-dig",
6889 [ALC882_6ST_DIG] = "6stack-dig",
6890 [ALC882_ARIMA] = "arima",
6891 [ALC882_W2JC] = "w2jc",
6892 [ALC882_TARGA] = "targa",
6893 [ALC882_ASUS_A7J] = "asus-a7j",
6894 [ALC882_ASUS_A7M] = "asus-a7m",
6895 [ALC885_MACPRO] = "macpro",
6896 [ALC885_MB5] = "mb5",
6897 [ALC885_MBP3] = "mbp3",
6898 [ALC885_IMAC24] = "imac24",
6899 [ALC882_AUTO] = "auto",
6902 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6903 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6904 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6905 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6906 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6907 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6908 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6909 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6910 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6911 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6912 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6913 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6914 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6918 static struct alc_config_preset alc882_presets[] = {
6919 [ALC882_3ST_DIG] = {
6920 .mixers = { alc882_base_mixer },
6921 .init_verbs = { alc882_init_verbs },
6922 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6923 .dac_nids = alc882_dac_nids,
6924 .dig_out_nid = ALC882_DIGOUT_NID,
6925 .dig_in_nid = ALC882_DIGIN_NID,
6926 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6927 .channel_mode = alc882_ch_modes,
6929 .input_mux = &alc882_capture_source,
6931 [ALC882_6ST_DIG] = {
6932 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6933 .init_verbs = { alc882_init_verbs },
6934 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6935 .dac_nids = alc882_dac_nids,
6936 .dig_out_nid = ALC882_DIGOUT_NID,
6937 .dig_in_nid = ALC882_DIGIN_NID,
6938 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6939 .channel_mode = alc882_sixstack_modes,
6940 .input_mux = &alc882_capture_source,
6943 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6944 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6945 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6946 .dac_nids = alc882_dac_nids,
6947 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6948 .channel_mode = alc882_sixstack_modes,
6949 .input_mux = &alc882_capture_source,
6952 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6953 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6954 alc880_gpio1_init_verbs },
6955 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6956 .dac_nids = alc882_dac_nids,
6957 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6958 .channel_mode = alc880_threestack_modes,
6960 .input_mux = &alc882_capture_source,
6961 .dig_out_nid = ALC882_DIGOUT_NID,
6964 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6965 .init_verbs = { alc885_mbp3_init_verbs,
6966 alc880_gpio1_init_verbs },
6967 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6968 .dac_nids = alc882_dac_nids,
6969 .channel_mode = alc885_mbp_6ch_modes,
6970 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6971 .input_mux = &alc882_capture_source,
6972 .dig_out_nid = ALC882_DIGOUT_NID,
6973 .dig_in_nid = ALC882_DIGIN_NID,
6974 .unsol_event = alc_automute_amp_unsol_event,
6975 .init_hook = alc885_mbp3_init_hook,
6978 .mixers = { alc885_mb5_mixer },
6979 .init_verbs = { alc885_mb5_init_verbs,
6980 alc880_gpio1_init_verbs },
6981 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6982 .dac_nids = alc882_dac_nids,
6983 .channel_mode = alc885_mbp_6ch_modes,
6984 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6985 .input_mux = &mb5_capture_source,
6986 .dig_out_nid = ALC882_DIGOUT_NID,
6987 .dig_in_nid = ALC882_DIGIN_NID,
6990 .mixers = { alc882_macpro_mixer },
6991 .init_verbs = { alc882_macpro_init_verbs },
6992 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6993 .dac_nids = alc882_dac_nids,
6994 .dig_out_nid = ALC882_DIGOUT_NID,
6995 .dig_in_nid = ALC882_DIGIN_NID,
6996 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6997 .channel_mode = alc882_ch_modes,
6998 .input_mux = &alc882_capture_source,
6999 .init_hook = alc885_macpro_init_hook,
7002 .mixers = { alc885_imac24_mixer },
7003 .init_verbs = { alc885_imac24_init_verbs },
7004 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7005 .dac_nids = alc882_dac_nids,
7006 .dig_out_nid = ALC882_DIGOUT_NID,
7007 .dig_in_nid = ALC882_DIGIN_NID,
7008 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7009 .channel_mode = alc882_ch_modes,
7010 .input_mux = &alc882_capture_source,
7011 .unsol_event = alc_automute_amp_unsol_event,
7012 .init_hook = alc885_imac24_init_hook,
7015 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7016 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7017 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7018 .dac_nids = alc882_dac_nids,
7019 .dig_out_nid = ALC882_DIGOUT_NID,
7020 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7021 .adc_nids = alc882_adc_nids,
7022 .capsrc_nids = alc882_capsrc_nids,
7023 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7024 .channel_mode = alc882_3ST_6ch_modes,
7026 .input_mux = &alc882_capture_source,
7027 .unsol_event = alc882_targa_unsol_event,
7028 .init_hook = alc882_targa_init_hook,
7030 [ALC882_ASUS_A7J] = {
7031 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7032 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7033 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7034 .dac_nids = alc882_dac_nids,
7035 .dig_out_nid = ALC882_DIGOUT_NID,
7036 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7037 .adc_nids = alc882_adc_nids,
7038 .capsrc_nids = alc882_capsrc_nids,
7039 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7040 .channel_mode = alc882_3ST_6ch_modes,
7042 .input_mux = &alc882_capture_source,
7044 [ALC882_ASUS_A7M] = {
7045 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7046 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7047 alc880_gpio1_init_verbs,
7048 alc882_asus_a7m_verbs },
7049 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7050 .dac_nids = alc882_dac_nids,
7051 .dig_out_nid = ALC882_DIGOUT_NID,
7052 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7053 .channel_mode = alc880_threestack_modes,
7055 .input_mux = &alc882_capture_source,
7064 PINFIX_ABIT_AW9D_MAX
7067 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7068 { 0x15, 0x01080104 }, /* side */
7069 { 0x16, 0x01011012 }, /* rear */
7070 { 0x17, 0x01016011 }, /* clfe */
7074 static const struct alc_pincfg *alc882_pin_fixes[] = {
7075 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7078 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7079 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7084 * BIOS auto configuration
7086 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7087 hda_nid_t nid, int pin_type,
7091 struct alc_spec *spec = codec->spec;
7094 alc_set_pin_output(codec, nid, pin_type);
7095 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7098 idx = spec->multiout.dac_nids[dac_idx] - 2;
7099 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7103 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7105 struct alc_spec *spec = codec->spec;
7108 for (i = 0; i <= HDA_SIDE; i++) {
7109 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7110 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7112 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7117 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7119 struct alc_spec *spec = codec->spec;
7122 pin = spec->autocfg.hp_pins[0];
7123 if (pin) /* connect to front */
7125 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7126 pin = spec->autocfg.speaker_pins[0];
7128 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7131 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7132 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7134 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7136 struct alc_spec *spec = codec->spec;
7139 for (i = 0; i < AUTO_PIN_LAST; i++) {
7140 hda_nid_t nid = spec->autocfg.input_pins[i];
7143 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7144 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7145 snd_hda_codec_write(codec, nid, 0,
7146 AC_VERB_SET_AMP_GAIN_MUTE,
7151 static void alc882_auto_init_input_src(struct hda_codec *codec)
7153 struct alc_spec *spec = codec->spec;
7156 for (c = 0; c < spec->num_adc_nids; c++) {
7157 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7158 hda_nid_t nid = spec->capsrc_nids[c];
7159 unsigned int mux_idx;
7160 const struct hda_input_mux *imux;
7161 int conns, mute, idx, item;
7163 conns = snd_hda_get_connections(codec, nid, conn_list,
7164 ARRAY_SIZE(conn_list));
7167 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7168 imux = &spec->input_mux[mux_idx];
7169 for (idx = 0; idx < conns; idx++) {
7170 /* if the current connection is the selected one,
7171 * unmute it as default - otherwise mute it
7173 mute = AMP_IN_MUTE(idx);
7174 for (item = 0; item < imux->num_items; item++) {
7175 if (imux->items[item].index == idx) {
7176 if (spec->cur_mux[c] == item)
7177 mute = AMP_IN_UNMUTE(idx);
7181 /* check if we have a selector or mixer
7182 * we could check for the widget type instead, but
7183 * just check for Amp-In presence (in case of mixer
7184 * without amp-in there is something wrong, this
7185 * function shouldn't be used or capsrc nid is wrong)
7187 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7188 snd_hda_codec_write(codec, nid, 0,
7189 AC_VERB_SET_AMP_GAIN_MUTE,
7191 else if (mute != AMP_IN_MUTE(idx))
7192 snd_hda_codec_write(codec, nid, 0,
7193 AC_VERB_SET_CONNECT_SEL,
7199 /* add mic boosts if needed */
7200 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7202 struct alc_spec *spec = codec->spec;
7206 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7207 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7208 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7210 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7214 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7215 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7216 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7218 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7225 /* almost identical with ALC880 parser... */
7226 static int alc882_parse_auto_config(struct hda_codec *codec)
7228 struct alc_spec *spec = codec->spec;
7229 int err = alc880_parse_auto_config(codec);
7234 return 0; /* no config found */
7236 err = alc_auto_add_mic_boost(codec);
7240 /* hack - override the init verbs */
7241 spec->init_verbs[0] = alc882_auto_init_verbs;
7243 return 1; /* config found */
7246 /* additional initialization for auto-configuration model */
7247 static void alc882_auto_init(struct hda_codec *codec)
7249 struct alc_spec *spec = codec->spec;
7250 alc882_auto_init_multi_out(codec);
7251 alc882_auto_init_hp_out(codec);
7252 alc882_auto_init_analog_input(codec);
7253 alc882_auto_init_input_src(codec);
7254 if (spec->unsol_event)
7255 alc_inithook(codec);
7258 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7260 static int patch_alc882(struct hda_codec *codec)
7262 struct alc_spec *spec;
7263 int err, board_config;
7265 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7271 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7275 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7276 /* Pick up systems that don't supply PCI SSID */
7277 switch (codec->subsystem_id) {
7278 case 0x106b0c00: /* Mac Pro */
7279 board_config = ALC885_MACPRO;
7281 case 0x106b1000: /* iMac 24 */
7282 case 0x106b2800: /* AppleTV */
7283 case 0x106b3e00: /* iMac 24 Aluminium */
7284 board_config = ALC885_IMAC24;
7286 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7287 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7288 case 0x106b00a4: /* MacbookPro4,1 */
7289 case 0x106b2c00: /* Macbook Pro rev3 */
7290 case 0x106b3600: /* Macbook 3.1 */
7291 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7292 board_config = ALC885_MBP3;
7294 case 0x106b3f00: /* Macbook 5,1 */
7295 board_config = ALC885_MB5;
7298 /* ALC889A is handled better as ALC888-compatible */
7299 if (codec->revision_id == 0x100101 ||
7300 codec->revision_id == 0x100103) {
7302 return patch_alc883(codec);
7304 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7305 "trying auto-probe from BIOS...\n");
7306 board_config = ALC882_AUTO;
7310 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7312 if (board_config == ALC882_AUTO) {
7313 /* automatic parse from the BIOS config */
7314 err = alc882_parse_auto_config(codec);
7320 "hda_codec: Cannot set up configuration "
7321 "from BIOS. Using base mode...\n");
7322 board_config = ALC882_3ST_DIG;
7326 err = snd_hda_attach_beep_device(codec, 0x1);
7332 if (board_config != ALC882_AUTO)
7333 setup_preset(spec, &alc882_presets[board_config]);
7335 if (codec->vendor_id == 0x10ec0885) {
7336 spec->stream_name_analog = "ALC885 Analog";
7337 spec->stream_name_digital = "ALC885 Digital";
7339 spec->stream_name_analog = "ALC882 Analog";
7340 spec->stream_name_digital = "ALC882 Digital";
7343 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7344 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7345 /* FIXME: setup DAC5 */
7346 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7347 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7349 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7350 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7352 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7353 if (!spec->adc_nids && spec->input_mux) {
7354 /* check whether NID 0x07 is valid */
7355 unsigned int wcap = get_wcaps(codec, 0x07);
7357 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7358 if (wcap != AC_WID_AUD_IN) {
7359 spec->adc_nids = alc882_adc_nids_alt;
7360 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7361 spec->capsrc_nids = alc882_capsrc_nids_alt;
7363 spec->adc_nids = alc882_adc_nids;
7364 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7365 spec->capsrc_nids = alc882_capsrc_nids;
7368 set_capture_mixer(spec);
7369 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7371 spec->vmaster_nid = 0x0c;
7373 codec->patch_ops = alc_patch_ops;
7374 if (board_config == ALC882_AUTO)
7375 spec->init_hook = alc882_auto_init;
7376 #ifdef CONFIG_SND_HDA_POWER_SAVE
7377 if (!spec->loopback.amplist)
7378 spec->loopback.amplist = alc882_loopbacks;
7380 codec->proc_widget_hook = print_realtek_coef;
7388 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7389 * configuration. Each pin widget can choose any input DACs and a mixer.
7390 * Each ADC is connected from a mixer of all inputs. This makes possible
7391 * 6-channel independent captures.
7393 * In addition, an independent DAC for the multi-playback (not used in this
7396 #define ALC883_DIGOUT_NID 0x06
7397 #define ALC883_DIGIN_NID 0x0a
7399 #define ALC1200_DIGOUT_NID 0x10
7401 static hda_nid_t alc883_dac_nids[4] = {
7402 /* front, rear, clfe, rear_surr */
7403 0x02, 0x03, 0x04, 0x05
7406 static hda_nid_t alc883_adc_nids[2] = {
7411 static hda_nid_t alc883_adc_nids_alt[1] = {
7416 static hda_nid_t alc883_adc_nids_rev[2] = {
7421 #define alc889_adc_nids alc880_adc_nids
7423 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7425 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7427 #define alc889_capsrc_nids alc882_capsrc_nids
7430 /* FIXME: should be a matrix-type input source selection */
7432 static struct hda_input_mux alc883_capture_source = {
7436 { "Front Mic", 0x1 },
7442 static struct hda_input_mux alc883_3stack_6ch_intel = {
7446 { "Front Mic", 0x0 },
7452 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7460 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7470 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7478 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7482 { "Front Mic", 0x1 },
7487 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7498 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7505 static struct hda_verb alc883_3ST_ch2_init[] = {
7506 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7507 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7508 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7509 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7516 static struct hda_verb alc883_3ST_ch4_init[] = {
7517 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7518 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7519 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7520 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7521 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7528 static struct hda_verb alc883_3ST_ch6_init[] = {
7529 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7530 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7531 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7532 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7533 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7534 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7538 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7539 { 2, alc883_3ST_ch2_init },
7540 { 4, alc883_3ST_ch4_init },
7541 { 6, alc883_3ST_ch6_init },
7547 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7548 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7549 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7550 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7551 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7558 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7559 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7560 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7561 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7562 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7563 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7570 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7571 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7572 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7573 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7574 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7575 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7576 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7580 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7581 { 2, alc883_3ST_ch2_intel_init },
7582 { 4, alc883_3ST_ch4_intel_init },
7583 { 6, alc883_3ST_ch6_intel_init },
7589 static struct hda_verb alc883_sixstack_ch6_init[] = {
7590 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7591 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7592 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7593 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7600 static struct hda_verb alc883_sixstack_ch8_init[] = {
7601 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7602 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7603 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7604 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7608 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7609 { 6, alc883_sixstack_ch6_init },
7610 { 8, alc883_sixstack_ch8_init },
7613 static struct hda_verb alc883_medion_eapd_verbs[] = {
7614 /* eanable EAPD on medion laptop */
7615 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7616 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7620 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7621 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7624 static struct snd_kcontrol_new alc883_base_mixer[] = {
7625 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7626 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7628 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7631 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7632 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7633 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7634 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7638 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7639 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7641 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7642 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7643 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7644 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7645 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7649 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7650 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7651 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7652 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7653 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7654 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7655 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7656 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7658 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7660 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7661 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7662 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7666 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7667 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7668 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7669 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7670 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7673 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7674 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7675 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7676 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7680 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7681 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7682 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7683 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7684 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7688 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7689 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7690 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7694 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7697 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7698 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7699 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7700 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7701 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7703 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7705 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7706 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7707 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7711 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7712 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7713 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7714 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7715 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7716 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7717 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7718 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7719 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7720 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7721 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7722 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7723 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7724 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7726 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7727 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7728 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7729 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7730 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7734 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7735 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7736 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
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,
7741 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7742 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7743 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7744 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7745 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7746 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7747 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7748 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7749 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7750 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7751 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7752 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7753 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7754 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7758 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7759 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7760 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7761 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7762 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7763 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7764 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7765 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7766 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7768 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7769 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7770 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7771 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7773 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7774 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7776 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7777 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7781 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7782 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7783 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7784 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7785 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7786 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7787 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7788 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7789 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7790 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7791 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7792 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7794 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7796 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7797 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7801 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7802 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7804 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7805 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7806 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7807 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7808 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7809 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7810 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7811 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7812 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7816 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7817 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7818 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7819 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7820 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7821 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7822 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7823 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7824 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7828 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7829 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7830 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7835 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7836 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7837 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7841 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7842 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7844 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7845 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7846 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7848 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7849 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7850 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7854 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7855 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7856 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7857 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7858 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7859 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7866 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7867 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7868 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7869 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7870 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7871 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7872 0x0d, 1, 0x0, HDA_OUTPUT),
7873 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7874 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7875 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7876 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7877 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7878 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7879 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7880 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7881 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7882 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7883 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7885 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7886 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7887 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7891 static struct hda_bind_ctls alc883_bind_cap_vol = {
7892 .ops = &snd_hda_bind_vol,
7894 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7895 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7900 static struct hda_bind_ctls alc883_bind_cap_switch = {
7901 .ops = &snd_hda_bind_sw,
7903 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7904 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7909 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7911 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7912 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7913 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7914 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7915 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7916 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7917 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7921 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7922 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7923 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7926 /* .name = "Capture Source", */
7927 .name = "Input Source",
7929 .info = alc_mux_enum_info,
7930 .get = alc_mux_enum_get,
7931 .put = alc_mux_enum_put,
7936 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7938 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7939 .name = "Channel Mode",
7940 .info = alc_ch_mode_info,
7941 .get = alc_ch_mode_get,
7942 .put = alc_ch_mode_put,
7947 static struct hda_verb alc883_init_verbs[] = {
7948 /* ADC1: mute amp left and right */
7949 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7950 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7951 /* ADC2: mute amp left and right */
7952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7953 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7954 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7955 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7956 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7957 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7959 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7965 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7967 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7968 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7969 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7971 /* mute analog input loopbacks */
7972 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7973 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7974 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7975 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7976 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7978 /* Front Pin: output 0 (0x0c) */
7979 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7980 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7981 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7982 /* Rear Pin: output 1 (0x0d) */
7983 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7984 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7986 /* CLFE Pin: output 2 (0x0e) */
7987 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7988 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7989 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7990 /* Side Pin: output 3 (0x0f) */
7991 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7992 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7993 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7994 /* Mic (rear) pin: input vref at 80% */
7995 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7997 /* Front Mic pin: input vref at 80% */
7998 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7999 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8000 /* Line In pin: input */
8001 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8003 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8004 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8005 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8006 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8007 /* CD pin widget for input */
8008 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8010 /* FIXME: use matrix-type input source selection */
8011 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8013 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8014 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8020 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8021 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8025 /* toggle speaker-output according to the hp-jack state */
8026 static void alc883_mitac_init_hook(struct hda_codec *codec)
8028 struct alc_spec *spec = codec->spec;
8030 spec->autocfg.hp_pins[0] = 0x15;
8031 spec->autocfg.speaker_pins[0] = 0x14;
8032 spec->autocfg.speaker_pins[1] = 0x17;
8033 alc_automute_amp(codec);
8036 /* auto-toggle front mic */
8038 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8040 unsigned int present;
8043 present = snd_hda_codec_read(codec, 0x18, 0,
8044 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8045 bits = present ? HDA_AMP_MUTE : 0;
8046 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8050 static struct hda_verb alc883_mitac_verbs[] = {
8052 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8055 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8056 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8058 /* enable unsolicited event */
8059 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8060 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8065 static struct hda_verb alc883_clevo_m720_verbs[] = {
8067 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8068 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8070 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8073 /* enable unsolicited event */
8074 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8075 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8080 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8082 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8085 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8086 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8088 /* enable unsolicited event */
8089 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8094 static struct hda_verb alc883_tagra_verbs[] = {
8095 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8096 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8098 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8099 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8101 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8102 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8103 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8105 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8106 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8107 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8108 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8113 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8114 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8115 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8116 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8120 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8121 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8122 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8123 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8124 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8128 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8129 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8130 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8131 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8132 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8133 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8137 static struct hda_verb alc883_haier_w66_verbs[] = {
8138 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8141 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8143 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8144 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8145 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8146 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8150 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8151 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8152 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8153 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8154 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8155 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8156 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8157 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8162 static struct hda_verb alc888_6st_dell_verbs[] = {
8163 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8167 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8169 struct alc_spec *spec = codec->spec;
8171 spec->autocfg.hp_pins[0] = 0x1b;
8172 spec->autocfg.speaker_pins[0] = 0x14;
8173 spec->autocfg.speaker_pins[1] = 0x16;
8174 spec->autocfg.speaker_pins[2] = 0x18;
8175 alc_automute_amp(codec);
8178 static struct hda_verb alc888_3st_hp_verbs[] = {
8179 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8180 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8181 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8182 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8189 static struct hda_verb alc888_3st_hp_2ch_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_IN },
8193 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8200 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8201 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8202 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8203 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8204 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8205 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8212 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8213 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8214 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8215 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8216 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8217 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8218 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8222 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8223 { 2, alc888_3st_hp_2ch_init },
8224 { 4, alc888_3st_hp_4ch_init },
8225 { 6, alc888_3st_hp_6ch_init },
8228 /* toggle front-jack and RCA according to the hp-jack state */
8229 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8231 unsigned int present;
8233 present = snd_hda_codec_read(codec, 0x1b, 0,
8234 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8235 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8236 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8237 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8238 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8241 /* toggle RCA according to the front-jack state */
8242 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8244 unsigned int present;
8246 present = snd_hda_codec_read(codec, 0x14, 0,
8247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8248 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8249 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8252 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8255 if ((res >> 26) == ALC880_HP_EVENT)
8256 alc888_lenovo_ms7195_front_automute(codec);
8257 if ((res >> 26) == ALC880_FRONT_EVENT)
8258 alc888_lenovo_ms7195_rca_automute(codec);
8261 static struct hda_verb alc883_medion_md2_verbs[] = {
8262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8265 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8267 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8271 /* toggle speaker-output according to the hp-jack state */
8272 static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8274 struct alc_spec *spec = codec->spec;
8276 spec->autocfg.hp_pins[0] = 0x14;
8277 spec->autocfg.speaker_pins[0] = 0x15;
8278 alc_automute_amp(codec);
8281 /* toggle speaker-output according to the hp-jack state */
8282 #define alc883_tagra_init_hook alc882_targa_init_hook
8283 #define alc883_tagra_unsol_event alc882_targa_unsol_event
8285 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8287 unsigned int present;
8289 present = snd_hda_codec_read(codec, 0x18, 0,
8290 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8291 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8292 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8295 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8297 struct alc_spec *spec = codec->spec;
8299 spec->autocfg.hp_pins[0] = 0x15;
8300 spec->autocfg.speaker_pins[0] = 0x14;
8301 alc_automute_amp(codec);
8302 alc883_clevo_m720_mic_automute(codec);
8305 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8308 switch (res >> 26) {
8309 case ALC880_MIC_EVENT:
8310 alc883_clevo_m720_mic_automute(codec);
8313 alc_automute_amp_unsol_event(codec, res);
8318 /* toggle speaker-output according to the hp-jack state */
8319 static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8321 struct alc_spec *spec = codec->spec;
8323 spec->autocfg.hp_pins[0] = 0x14;
8324 spec->autocfg.speaker_pins[0] = 0x15;
8325 alc_automute_amp(codec);
8328 static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8330 struct alc_spec *spec = codec->spec;
8332 spec->autocfg.hp_pins[0] = 0x1b;
8333 spec->autocfg.speaker_pins[0] = 0x14;
8334 alc_automute_amp(codec);
8337 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8339 unsigned int present;
8342 present = snd_hda_codec_read(codec, 0x14, 0,
8343 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8344 bits = present ? HDA_AMP_MUTE : 0;
8345 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8346 HDA_AMP_MUTE, bits);
8349 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8351 unsigned int present;
8354 present = snd_hda_codec_read(codec, 0x1b, 0,
8355 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8356 bits = present ? HDA_AMP_MUTE : 0;
8357 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8358 HDA_AMP_MUTE, bits);
8359 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8360 HDA_AMP_MUTE, bits);
8363 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8366 if ((res >> 26) == ALC880_HP_EVENT)
8367 alc883_lenovo_101e_all_automute(codec);
8368 if ((res >> 26) == ALC880_FRONT_EVENT)
8369 alc883_lenovo_101e_ispeaker_automute(codec);
8372 /* toggle speaker-output according to the hp-jack state */
8373 static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8375 struct alc_spec *spec = codec->spec;
8377 spec->autocfg.hp_pins[0] = 0x14;
8378 spec->autocfg.speaker_pins[0] = 0x15;
8379 spec->autocfg.speaker_pins[1] = 0x16;
8380 alc_automute_amp(codec);
8383 static struct hda_verb alc883_acer_eapd_verbs[] = {
8384 /* HP Pin: output 0 (0x0c) */
8385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8386 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8387 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8388 /* Front Pin: output 0 (0x0c) */
8389 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8390 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8391 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8392 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8393 /* eanable EAPD on medion laptop */
8394 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8395 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8396 /* enable unsolicited event */
8397 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8401 static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8403 struct alc_spec *spec = codec->spec;
8405 spec->autocfg.hp_pins[0] = 0x1b;
8406 spec->autocfg.speaker_pins[0] = 0x14;
8407 spec->autocfg.speaker_pins[1] = 0x15;
8408 spec->autocfg.speaker_pins[2] = 0x16;
8409 spec->autocfg.speaker_pins[3] = 0x17;
8410 alc_automute_amp(codec);
8413 static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8415 struct alc_spec *spec = codec->spec;
8417 spec->autocfg.hp_pins[0] = 0x1b;
8418 spec->autocfg.speaker_pins[0] = 0x14;
8419 spec->autocfg.speaker_pins[1] = 0x15;
8420 spec->autocfg.speaker_pins[2] = 0x16;
8421 spec->autocfg.speaker_pins[3] = 0x17;
8422 spec->autocfg.speaker_pins[4] = 0x1a;
8423 alc_automute_amp(codec);
8427 * generic initialization of ADC, input mixers and output mixers
8429 static struct hda_verb alc883_auto_init_verbs[] = {
8431 * Unmute ADC0-2 and set the default input to mic-in
8433 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8436 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8438 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8440 * Note: PASD motherboards uses the Line In 2 as the input for
8441 * front panel mic (mic 2)
8443 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8445 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8446 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8447 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8448 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8451 * Set up output mixers (0x0c - 0x0f)
8453 /* set vol=0 to output mixers */
8454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8455 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8457 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8458 /* set up input amps for analog loopback */
8459 /* Amp Indices: DAC = 0, mixer = 1 */
8460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8462 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8464 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8466 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8467 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8468 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8469 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8471 /* FIXME: use matrix-type input source selection */
8472 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8477 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8478 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8483 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8484 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8489 static struct hda_verb alc888_asus_m90v_verbs[] = {
8490 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8491 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8493 /* enable unsolicited event */
8494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8495 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8499 static void alc883_nb_mic_automute(struct hda_codec *codec)
8501 unsigned int present;
8503 present = snd_hda_codec_read(codec, 0x18, 0,
8504 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8505 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8506 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8507 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8508 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8511 static void alc883_M90V_init_hook(struct hda_codec *codec)
8513 struct alc_spec *spec = codec->spec;
8515 spec->autocfg.hp_pins[0] = 0x1b;
8516 spec->autocfg.speaker_pins[0] = 0x14;
8517 spec->autocfg.speaker_pins[1] = 0x15;
8518 spec->autocfg.speaker_pins[2] = 0x16;
8519 alc_automute_pin(codec);
8522 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8525 switch (res >> 26) {
8526 case ALC880_MIC_EVENT:
8527 alc883_nb_mic_automute(codec);
8530 alc_sku_unsol_event(codec, res);
8535 static void alc883_mode2_inithook(struct hda_codec *codec)
8537 alc883_M90V_init_hook(codec);
8538 alc883_nb_mic_automute(codec);
8541 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8542 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8543 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8544 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8545 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8547 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8548 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8549 /* enable unsolicited event */
8550 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8554 static void alc883_eee1601_inithook(struct hda_codec *codec)
8556 struct alc_spec *spec = codec->spec;
8558 spec->autocfg.hp_pins[0] = 0x14;
8559 spec->autocfg.speaker_pins[0] = 0x1b;
8560 alc_automute_pin(codec);
8563 #ifdef CONFIG_SND_HDA_POWER_SAVE
8564 #define alc883_loopbacks alc880_loopbacks
8567 /* pcm configuration: identiacal with ALC880 */
8568 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8569 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8570 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8571 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8572 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8575 * configuration and preset
8577 static const char *alc883_models[ALC883_MODEL_LAST] = {
8578 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8579 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8580 [ALC883_3ST_6ch] = "3stack-6ch",
8581 [ALC883_6ST_DIG] = "6stack-dig",
8582 [ALC883_TARGA_DIG] = "targa-dig",
8583 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8584 [ALC883_ACER] = "acer",
8585 [ALC883_ACER_ASPIRE] = "acer-aspire",
8586 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8587 [ALC883_MEDION] = "medion",
8588 [ALC883_MEDION_MD2] = "medion-md2",
8589 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8590 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8591 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8592 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8593 [ALC888_LENOVO_SKY] = "lenovo-sky",
8594 [ALC883_HAIER_W66] = "haier-w66",
8595 [ALC888_3ST_HP] = "3stack-hp",
8596 [ALC888_6ST_DELL] = "6stack-dell",
8597 [ALC883_MITAC] = "mitac",
8598 [ALC883_CLEVO_M720] = "clevo-m720",
8599 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8600 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8601 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8602 [ALC1200_ASUS_P5Q] = "asus-p5q",
8603 [ALC883_AUTO] = "auto",
8606 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8607 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8608 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8609 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8610 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8611 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8612 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8613 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8614 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8615 ALC888_ACER_ASPIRE_4930G),
8616 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8617 ALC888_ACER_ASPIRE_4930G),
8618 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8619 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8620 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8621 ALC888_ACER_ASPIRE_4930G),
8622 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8623 ALC888_ACER_ASPIRE_4930G),
8625 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
8626 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8627 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8628 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8629 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8630 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8631 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8632 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8633 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8634 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8635 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8636 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8637 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8638 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8639 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8640 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8641 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8642 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8643 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8644 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8645 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8646 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8647 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8648 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8649 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8650 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8651 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8652 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8653 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8654 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8655 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8656 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8657 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8658 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8659 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8660 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8661 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8662 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8663 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8664 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8665 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8666 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8667 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8668 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8669 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8670 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8671 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8672 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8673 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8674 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8675 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8676 ALC883_FUJITSU_PI2515),
8677 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8678 ALC888_FUJITSU_XA3530),
8679 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8680 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8681 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8682 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8683 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8684 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8685 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8686 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8687 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8688 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8689 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8690 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8691 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8692 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8696 static hda_nid_t alc883_slave_dig_outs[] = {
8697 ALC1200_DIGOUT_NID, 0,
8700 static hda_nid_t alc1200_slave_dig_outs[] = {
8701 ALC883_DIGOUT_NID, 0,
8704 static struct alc_config_preset alc883_presets[] = {
8705 [ALC883_3ST_2ch_DIG] = {
8706 .mixers = { alc883_3ST_2ch_mixer },
8707 .init_verbs = { alc883_init_verbs },
8708 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8709 .dac_nids = alc883_dac_nids,
8710 .dig_out_nid = ALC883_DIGOUT_NID,
8711 .dig_in_nid = ALC883_DIGIN_NID,
8712 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8713 .channel_mode = alc883_3ST_2ch_modes,
8714 .input_mux = &alc883_capture_source,
8716 [ALC883_3ST_6ch_DIG] = {
8717 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8718 .init_verbs = { alc883_init_verbs },
8719 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8720 .dac_nids = alc883_dac_nids,
8721 .dig_out_nid = ALC883_DIGOUT_NID,
8722 .dig_in_nid = ALC883_DIGIN_NID,
8723 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8724 .channel_mode = alc883_3ST_6ch_modes,
8726 .input_mux = &alc883_capture_source,
8728 [ALC883_3ST_6ch] = {
8729 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8730 .init_verbs = { alc883_init_verbs },
8731 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8732 .dac_nids = alc883_dac_nids,
8733 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8734 .channel_mode = alc883_3ST_6ch_modes,
8736 .input_mux = &alc883_capture_source,
8738 [ALC883_3ST_6ch_INTEL] = {
8739 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8740 .init_verbs = { alc883_init_verbs },
8741 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8742 .dac_nids = alc883_dac_nids,
8743 .dig_out_nid = ALC883_DIGOUT_NID,
8744 .dig_in_nid = ALC883_DIGIN_NID,
8745 .slave_dig_outs = alc883_slave_dig_outs,
8746 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8747 .channel_mode = alc883_3ST_6ch_intel_modes,
8749 .input_mux = &alc883_3stack_6ch_intel,
8751 [ALC883_6ST_DIG] = {
8752 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8753 .init_verbs = { alc883_init_verbs },
8754 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8755 .dac_nids = alc883_dac_nids,
8756 .dig_out_nid = ALC883_DIGOUT_NID,
8757 .dig_in_nid = ALC883_DIGIN_NID,
8758 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8759 .channel_mode = alc883_sixstack_modes,
8760 .input_mux = &alc883_capture_source,
8762 [ALC883_TARGA_DIG] = {
8763 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8764 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8765 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8766 .dac_nids = alc883_dac_nids,
8767 .dig_out_nid = ALC883_DIGOUT_NID,
8768 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8769 .channel_mode = alc883_3ST_6ch_modes,
8771 .input_mux = &alc883_capture_source,
8772 .unsol_event = alc883_tagra_unsol_event,
8773 .init_hook = alc883_tagra_init_hook,
8775 [ALC883_TARGA_2ch_DIG] = {
8776 .mixers = { alc883_tagra_2ch_mixer},
8777 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8778 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8779 .dac_nids = alc883_dac_nids,
8780 .adc_nids = alc883_adc_nids_alt,
8781 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8782 .dig_out_nid = ALC883_DIGOUT_NID,
8783 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8784 .channel_mode = alc883_3ST_2ch_modes,
8785 .input_mux = &alc883_capture_source,
8786 .unsol_event = alc883_tagra_unsol_event,
8787 .init_hook = alc883_tagra_init_hook,
8790 .mixers = { alc883_base_mixer },
8791 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8792 * and the headphone jack. Turn this on and rely on the
8793 * standard mute methods whenever the user wants to turn
8794 * these outputs off.
8796 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8797 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8798 .dac_nids = alc883_dac_nids,
8799 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8800 .channel_mode = alc883_3ST_2ch_modes,
8801 .input_mux = &alc883_capture_source,
8803 [ALC883_ACER_ASPIRE] = {
8804 .mixers = { alc883_acer_aspire_mixer },
8805 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8806 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8807 .dac_nids = alc883_dac_nids,
8808 .dig_out_nid = ALC883_DIGOUT_NID,
8809 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8810 .channel_mode = alc883_3ST_2ch_modes,
8811 .input_mux = &alc883_capture_source,
8812 .unsol_event = alc_automute_amp_unsol_event,
8813 .init_hook = alc883_acer_aspire_init_hook,
8815 [ALC888_ACER_ASPIRE_4930G] = {
8816 .mixers = { alc888_base_mixer,
8817 alc883_chmode_mixer },
8818 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8819 alc888_acer_aspire_4930g_verbs },
8820 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8821 .dac_nids = alc883_dac_nids,
8822 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8823 .adc_nids = alc883_adc_nids_rev,
8824 .capsrc_nids = alc883_capsrc_nids_rev,
8825 .dig_out_nid = ALC883_DIGOUT_NID,
8826 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8827 .channel_mode = alc883_3ST_6ch_modes,
8830 ARRAY_SIZE(alc888_2_capture_sources),
8831 .input_mux = alc888_2_capture_sources,
8832 .unsol_event = alc_automute_amp_unsol_event,
8833 .init_hook = alc888_acer_aspire_4930g_init_hook,
8836 .mixers = { alc883_fivestack_mixer,
8837 alc883_chmode_mixer },
8838 .init_verbs = { alc883_init_verbs,
8839 alc883_medion_eapd_verbs },
8840 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8841 .dac_nids = alc883_dac_nids,
8842 .adc_nids = alc883_adc_nids_alt,
8843 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8844 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8845 .channel_mode = alc883_sixstack_modes,
8846 .input_mux = &alc883_capture_source,
8848 [ALC883_MEDION_MD2] = {
8849 .mixers = { alc883_medion_md2_mixer},
8850 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8851 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8852 .dac_nids = alc883_dac_nids,
8853 .dig_out_nid = ALC883_DIGOUT_NID,
8854 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8855 .channel_mode = alc883_3ST_2ch_modes,
8856 .input_mux = &alc883_capture_source,
8857 .unsol_event = alc_automute_amp_unsol_event,
8858 .init_hook = alc883_medion_md2_init_hook,
8860 [ALC883_LAPTOP_EAPD] = {
8861 .mixers = { alc883_base_mixer },
8862 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8863 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8864 .dac_nids = alc883_dac_nids,
8865 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8866 .channel_mode = alc883_3ST_2ch_modes,
8867 .input_mux = &alc883_capture_source,
8869 [ALC883_CLEVO_M720] = {
8870 .mixers = { alc883_clevo_m720_mixer },
8871 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8872 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8873 .dac_nids = alc883_dac_nids,
8874 .dig_out_nid = ALC883_DIGOUT_NID,
8875 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8876 .channel_mode = alc883_3ST_2ch_modes,
8877 .input_mux = &alc883_capture_source,
8878 .unsol_event = alc883_clevo_m720_unsol_event,
8879 .init_hook = alc883_clevo_m720_init_hook,
8881 [ALC883_LENOVO_101E_2ch] = {
8882 .mixers = { alc883_lenovo_101e_2ch_mixer},
8883 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8884 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8885 .dac_nids = alc883_dac_nids,
8886 .adc_nids = alc883_adc_nids_alt,
8887 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8888 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8889 .channel_mode = alc883_3ST_2ch_modes,
8890 .input_mux = &alc883_lenovo_101e_capture_source,
8891 .unsol_event = alc883_lenovo_101e_unsol_event,
8892 .init_hook = alc883_lenovo_101e_all_automute,
8894 [ALC883_LENOVO_NB0763] = {
8895 .mixers = { alc883_lenovo_nb0763_mixer },
8896 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8897 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8898 .dac_nids = alc883_dac_nids,
8899 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8900 .channel_mode = alc883_3ST_2ch_modes,
8902 .input_mux = &alc883_lenovo_nb0763_capture_source,
8903 .unsol_event = alc_automute_amp_unsol_event,
8904 .init_hook = alc883_medion_md2_init_hook,
8906 [ALC888_LENOVO_MS7195_DIG] = {
8907 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8908 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8909 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8910 .dac_nids = alc883_dac_nids,
8911 .dig_out_nid = ALC883_DIGOUT_NID,
8912 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8913 .channel_mode = alc883_3ST_6ch_modes,
8915 .input_mux = &alc883_capture_source,
8916 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8917 .init_hook = alc888_lenovo_ms7195_front_automute,
8919 [ALC883_HAIER_W66] = {
8920 .mixers = { alc883_tagra_2ch_mixer},
8921 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8922 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8923 .dac_nids = alc883_dac_nids,
8924 .dig_out_nid = ALC883_DIGOUT_NID,
8925 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8926 .channel_mode = alc883_3ST_2ch_modes,
8927 .input_mux = &alc883_capture_source,
8928 .unsol_event = alc_automute_amp_unsol_event,
8929 .init_hook = alc883_haier_w66_init_hook,
8932 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8933 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8934 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8935 .dac_nids = alc883_dac_nids,
8936 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8937 .channel_mode = alc888_3st_hp_modes,
8939 .input_mux = &alc883_capture_source,
8940 .unsol_event = alc_automute_amp_unsol_event,
8941 .init_hook = alc888_3st_hp_init_hook,
8943 [ALC888_6ST_DELL] = {
8944 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8945 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8946 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8947 .dac_nids = alc883_dac_nids,
8948 .dig_out_nid = ALC883_DIGOUT_NID,
8949 .dig_in_nid = ALC883_DIGIN_NID,
8950 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8951 .channel_mode = alc883_sixstack_modes,
8952 .input_mux = &alc883_capture_source,
8953 .unsol_event = alc_automute_amp_unsol_event,
8954 .init_hook = alc888_6st_dell_init_hook,
8957 .mixers = { alc883_mitac_mixer },
8958 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8959 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8960 .dac_nids = alc883_dac_nids,
8961 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8962 .channel_mode = alc883_3ST_2ch_modes,
8963 .input_mux = &alc883_capture_source,
8964 .unsol_event = alc_automute_amp_unsol_event,
8965 .init_hook = alc883_mitac_init_hook,
8967 [ALC883_FUJITSU_PI2515] = {
8968 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8969 .init_verbs = { alc883_init_verbs,
8970 alc883_2ch_fujitsu_pi2515_verbs},
8971 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8972 .dac_nids = alc883_dac_nids,
8973 .dig_out_nid = ALC883_DIGOUT_NID,
8974 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8975 .channel_mode = alc883_3ST_2ch_modes,
8976 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8977 .unsol_event = alc_automute_amp_unsol_event,
8978 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
8980 [ALC888_FUJITSU_XA3530] = {
8981 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8982 .init_verbs = { alc883_init_verbs,
8983 alc888_fujitsu_xa3530_verbs },
8984 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8985 .dac_nids = alc883_dac_nids,
8986 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8987 .adc_nids = alc883_adc_nids_rev,
8988 .capsrc_nids = alc883_capsrc_nids_rev,
8989 .dig_out_nid = ALC883_DIGOUT_NID,
8990 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8991 .channel_mode = alc888_4ST_8ch_intel_modes,
8993 ARRAY_SIZE(alc888_2_capture_sources),
8994 .input_mux = alc888_2_capture_sources,
8995 .unsol_event = alc_automute_amp_unsol_event,
8996 .init_hook = alc888_fujitsu_xa3530_init_hook,
8998 [ALC888_LENOVO_SKY] = {
8999 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9000 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9001 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9002 .dac_nids = alc883_dac_nids,
9003 .dig_out_nid = ALC883_DIGOUT_NID,
9004 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9005 .channel_mode = alc883_sixstack_modes,
9007 .input_mux = &alc883_lenovo_sky_capture_source,
9008 .unsol_event = alc_automute_amp_unsol_event,
9009 .init_hook = alc888_lenovo_sky_init_hook,
9011 [ALC888_ASUS_M90V] = {
9012 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9013 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9014 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9015 .dac_nids = alc883_dac_nids,
9016 .dig_out_nid = ALC883_DIGOUT_NID,
9017 .dig_in_nid = ALC883_DIGIN_NID,
9018 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9019 .channel_mode = alc883_3ST_6ch_modes,
9021 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9022 .unsol_event = alc883_mode2_unsol_event,
9023 .init_hook = alc883_mode2_inithook,
9025 [ALC888_ASUS_EEE1601] = {
9026 .mixers = { alc883_asus_eee1601_mixer },
9027 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9028 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9029 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9030 .dac_nids = alc883_dac_nids,
9031 .dig_out_nid = ALC883_DIGOUT_NID,
9032 .dig_in_nid = ALC883_DIGIN_NID,
9033 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9034 .channel_mode = alc883_3ST_2ch_modes,
9036 .input_mux = &alc883_asus_eee1601_capture_source,
9037 .unsol_event = alc_sku_unsol_event,
9038 .init_hook = alc883_eee1601_inithook,
9040 [ALC1200_ASUS_P5Q] = {
9041 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9042 .init_verbs = { alc883_init_verbs },
9043 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9044 .dac_nids = alc883_dac_nids,
9045 .dig_out_nid = ALC1200_DIGOUT_NID,
9046 .dig_in_nid = ALC883_DIGIN_NID,
9047 .slave_dig_outs = alc1200_slave_dig_outs,
9048 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9049 .channel_mode = alc883_sixstack_modes,
9050 .input_mux = &alc883_capture_source,
9056 * BIOS auto configuration
9058 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9059 hda_nid_t nid, int pin_type,
9063 struct alc_spec *spec = codec->spec;
9066 alc_set_pin_output(codec, nid, pin_type);
9067 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9070 idx = spec->multiout.dac_nids[dac_idx] - 2;
9071 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9075 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9077 struct alc_spec *spec = codec->spec;
9080 for (i = 0; i <= HDA_SIDE; i++) {
9081 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9082 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9084 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9089 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9091 struct alc_spec *spec = codec->spec;
9094 pin = spec->autocfg.hp_pins[0];
9095 if (pin) /* connect to front */
9097 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9098 pin = spec->autocfg.speaker_pins[0];
9100 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9103 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9104 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9106 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9108 struct alc_spec *spec = codec->spec;
9111 for (i = 0; i < AUTO_PIN_LAST; i++) {
9112 hda_nid_t nid = spec->autocfg.input_pins[i];
9113 if (alc883_is_input_pin(nid)) {
9114 alc_set_input_pin(codec, nid, i);
9115 if (nid != ALC883_PIN_CD_NID &&
9116 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9117 snd_hda_codec_write(codec, nid, 0,
9118 AC_VERB_SET_AMP_GAIN_MUTE,
9124 #define alc883_auto_init_input_src alc882_auto_init_input_src
9126 /* almost identical with ALC880 parser... */
9127 static int alc883_parse_auto_config(struct hda_codec *codec)
9129 struct alc_spec *spec = codec->spec;
9130 int err = alc880_parse_auto_config(codec);
9131 struct auto_pin_cfg *cfg = &spec->autocfg;
9137 return 0; /* no config found */
9139 err = alc_auto_add_mic_boost(codec);
9143 /* hack - override the init verbs */
9144 spec->init_verbs[0] = alc883_auto_init_verbs;
9146 /* setup input_mux for ALC889 */
9147 if (codec->vendor_id == 0x10ec0889) {
9148 /* digital-mic input pin is excluded in alc880_auto_create..()
9149 * because it's under 0x18
9151 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9152 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9153 struct hda_input_mux *imux = &spec->private_imux[0];
9154 for (i = 1; i < 3; i++)
9155 memcpy(&spec->private_imux[i],
9156 &spec->private_imux[0],
9157 sizeof(spec->private_imux[0]));
9158 imux->items[imux->num_items].label = "Int DMic";
9159 imux->items[imux->num_items].index = 0x0b;
9161 spec->num_mux_defs = 3;
9162 spec->input_mux = spec->private_imux;
9166 return 1; /* config found */
9169 /* additional initialization for auto-configuration model */
9170 static void alc883_auto_init(struct hda_codec *codec)
9172 struct alc_spec *spec = codec->spec;
9173 alc883_auto_init_multi_out(codec);
9174 alc883_auto_init_hp_out(codec);
9175 alc883_auto_init_analog_input(codec);
9176 alc883_auto_init_input_src(codec);
9177 if (spec->unsol_event)
9178 alc_inithook(codec);
9181 static int patch_alc883(struct hda_codec *codec)
9183 struct alc_spec *spec;
9184 int err, board_config;
9186 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9192 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9194 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9197 if (board_config < 0) {
9198 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9199 "trying auto-probe from BIOS...\n");
9200 board_config = ALC883_AUTO;
9203 if (board_config == ALC883_AUTO) {
9204 /* automatic parse from the BIOS config */
9205 err = alc883_parse_auto_config(codec);
9211 "hda_codec: Cannot set up configuration "
9212 "from BIOS. Using base mode...\n");
9213 board_config = ALC883_3ST_2ch_DIG;
9217 err = snd_hda_attach_beep_device(codec, 0x1);
9223 if (board_config != ALC883_AUTO)
9224 setup_preset(spec, &alc883_presets[board_config]);
9226 switch (codec->vendor_id) {
9228 if (codec->revision_id == 0x100101) {
9229 spec->stream_name_analog = "ALC1200 Analog";
9230 spec->stream_name_digital = "ALC1200 Digital";
9232 spec->stream_name_analog = "ALC888 Analog";
9233 spec->stream_name_digital = "ALC888 Digital";
9235 if (!spec->num_adc_nids) {
9236 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9237 spec->adc_nids = alc883_adc_nids;
9239 if (!spec->capsrc_nids)
9240 spec->capsrc_nids = alc883_capsrc_nids;
9241 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9242 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9245 spec->stream_name_analog = "ALC889 Analog";
9246 spec->stream_name_digital = "ALC889 Digital";
9247 if (!spec->num_adc_nids) {
9248 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9249 spec->adc_nids = alc889_adc_nids;
9251 if (!spec->capsrc_nids)
9252 spec->capsrc_nids = alc889_capsrc_nids;
9253 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9257 spec->stream_name_analog = "ALC883 Analog";
9258 spec->stream_name_digital = "ALC883 Digital";
9259 if (!spec->num_adc_nids) {
9260 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9261 spec->adc_nids = alc883_adc_nids;
9263 if (!spec->capsrc_nids)
9264 spec->capsrc_nids = alc883_capsrc_nids;
9265 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9269 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9270 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9271 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9273 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9274 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9276 if (!spec->cap_mixer)
9277 set_capture_mixer(spec);
9278 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9280 spec->vmaster_nid = 0x0c;
9282 codec->patch_ops = alc_patch_ops;
9283 if (board_config == ALC883_AUTO)
9284 spec->init_hook = alc883_auto_init;
9286 #ifdef CONFIG_SND_HDA_POWER_SAVE
9287 if (!spec->loopback.amplist)
9288 spec->loopback.amplist = alc883_loopbacks;
9290 codec->proc_widget_hook = print_realtek_coef;
9299 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9300 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9302 #define alc262_dac_nids alc260_dac_nids
9303 #define alc262_adc_nids alc882_adc_nids
9304 #define alc262_adc_nids_alt alc882_adc_nids_alt
9305 #define alc262_capsrc_nids alc882_capsrc_nids
9306 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9308 #define alc262_modes alc260_modes
9309 #define alc262_capture_source alc882_capture_source
9311 static hda_nid_t alc262_dmic_adc_nids[1] = {
9316 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9318 static struct snd_kcontrol_new alc262_base_mixer[] = {
9319 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9320 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9321 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9322 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9323 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9324 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9327 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9328 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9329 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9330 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9331 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9333 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9334 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9338 /* update HP, line and mono-out pins according to the master switch */
9339 static void alc262_hp_master_update(struct hda_codec *codec)
9341 struct alc_spec *spec = codec->spec;
9342 int val = spec->master_sw;
9345 snd_hda_codec_write_cache(codec, 0x1b, 0,
9346 AC_VERB_SET_PIN_WIDGET_CONTROL,
9348 snd_hda_codec_write_cache(codec, 0x15, 0,
9349 AC_VERB_SET_PIN_WIDGET_CONTROL,
9351 /* mono (speaker) depending on the HP jack sense */
9352 val = val && !spec->jack_present;
9353 snd_hda_codec_write_cache(codec, 0x16, 0,
9354 AC_VERB_SET_PIN_WIDGET_CONTROL,
9358 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9360 struct alc_spec *spec = codec->spec;
9361 unsigned int presence;
9362 presence = snd_hda_codec_read(codec, 0x1b, 0,
9363 AC_VERB_GET_PIN_SENSE, 0);
9364 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9365 alc262_hp_master_update(codec);
9368 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9370 if ((res >> 26) != ALC880_HP_EVENT)
9372 alc262_hp_bpc_automute(codec);
9375 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9377 struct alc_spec *spec = codec->spec;
9378 unsigned int presence;
9379 presence = snd_hda_codec_read(codec, 0x15, 0,
9380 AC_VERB_GET_PIN_SENSE, 0);
9381 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9382 alc262_hp_master_update(codec);
9385 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9388 if ((res >> 26) != ALC880_HP_EVENT)
9390 alc262_hp_wildwest_automute(codec);
9393 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
9395 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9396 struct snd_ctl_elem_value *ucontrol)
9398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9399 struct alc_spec *spec = codec->spec;
9400 int val = !!*ucontrol->value.integer.value;
9402 if (val == spec->master_sw)
9404 spec->master_sw = val;
9405 alc262_hp_master_update(codec);
9409 #define ALC262_HP_MASTER_SWITCH \
9411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9412 .name = "Master Playback Switch", \
9413 .info = snd_ctl_boolean_mono_info, \
9414 .get = alc262_hp_master_sw_get, \
9415 .put = alc262_hp_master_sw_put, \
9418 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9419 ALC262_HP_MASTER_SWITCH,
9420 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9421 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9422 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9423 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9425 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9429 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9430 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9431 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9432 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9433 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9434 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9437 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9438 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9442 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9443 ALC262_HP_MASTER_SWITCH,
9444 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9445 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9446 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9447 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9448 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9450 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9452 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9453 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9454 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9455 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9456 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9457 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9458 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9462 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9463 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9464 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9465 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9469 /* mute/unmute internal speaker according to the hp jack and mute state */
9470 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9472 struct alc_spec *spec = codec->spec;
9474 spec->autocfg.hp_pins[0] = 0x15;
9475 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9476 alc_automute_amp(codec);
9479 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9480 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9481 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9482 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9485 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9486 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9490 static struct hda_verb alc262_hp_t5735_verbs[] = {
9491 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9494 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9498 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9499 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9500 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9501 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9502 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9503 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9504 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9508 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9510 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9511 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9512 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9513 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9514 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9522 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9529 /* bind hp and internal speaker mute (with plug check) as master switch */
9530 static void alc262_hippo_master_update(struct hda_codec *codec)
9532 struct alc_spec *spec = codec->spec;
9533 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9534 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9535 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9539 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9540 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9541 HDA_AMP_MUTE, mute);
9542 /* mute internal speaker per jack sense */
9543 if (spec->jack_present)
9544 mute = HDA_AMP_MUTE;
9546 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9547 HDA_AMP_MUTE, mute);
9548 if (speaker_nid && speaker_nid != line_nid)
9549 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9550 HDA_AMP_MUTE, mute);
9553 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9555 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9556 struct snd_ctl_elem_value *ucontrol)
9558 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9559 struct alc_spec *spec = codec->spec;
9560 int val = !!*ucontrol->value.integer.value;
9562 if (val == spec->master_sw)
9564 spec->master_sw = val;
9565 alc262_hippo_master_update(codec);
9569 #define ALC262_HIPPO_MASTER_SWITCH \
9571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9572 .name = "Master Playback Switch", \
9573 .info = snd_ctl_boolean_mono_info, \
9574 .get = alc262_hippo_master_sw_get, \
9575 .put = alc262_hippo_master_sw_put, \
9578 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9579 ALC262_HIPPO_MASTER_SWITCH,
9580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9581 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9582 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9583 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9584 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9587 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9588 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9589 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9590 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9591 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9595 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9596 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9597 ALC262_HIPPO_MASTER_SWITCH,
9598 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9599 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9600 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9601 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9602 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9604 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9607 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9611 /* mute/unmute internal speaker according to the hp jack and mute state */
9612 static void alc262_hippo_automute(struct hda_codec *codec)
9614 struct alc_spec *spec = codec->spec;
9615 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9616 unsigned int present;
9618 /* need to execute and sync at first */
9619 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9620 present = snd_hda_codec_read(codec, hp_nid, 0,
9621 AC_VERB_GET_PIN_SENSE, 0);
9622 spec->jack_present = (present & 0x80000000) != 0;
9623 alc262_hippo_master_update(codec);
9626 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9628 if ((res >> 26) != ALC880_HP_EVENT)
9630 alc262_hippo_automute(codec);
9633 static void alc262_hippo_init_hook(struct hda_codec *codec)
9635 struct alc_spec *spec = codec->spec;
9637 spec->autocfg.hp_pins[0] = 0x15;
9638 spec->autocfg.speaker_pins[0] = 0x14;
9639 alc262_hippo_automute(codec);
9642 static void alc262_hippo1_init_hook(struct hda_codec *codec)
9644 struct alc_spec *spec = codec->spec;
9646 spec->autocfg.hp_pins[0] = 0x1b;
9647 spec->autocfg.speaker_pins[0] = 0x14;
9648 alc262_hippo_automute(codec);
9652 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9653 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9654 ALC262_HIPPO_MASTER_SWITCH,
9655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9657 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9658 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9662 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9663 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9664 ALC262_HIPPO_MASTER_SWITCH,
9665 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9668 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9669 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9673 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9674 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9675 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9676 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9677 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9678 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9679 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9682 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9683 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9684 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9685 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9689 static struct hda_verb alc262_tyan_verbs[] = {
9690 /* Headphone automute */
9691 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9693 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9695 /* P11 AUX_IN, white 4-pin connector */
9696 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9697 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9698 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9699 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9704 /* unsolicited event for HP jack sensing */
9705 static void alc262_tyan_init_hook(struct hda_codec *codec)
9707 struct alc_spec *spec = codec->spec;
9709 spec->autocfg.hp_pins[0] = 0x1b;
9710 spec->autocfg.speaker_pins[0] = 0x15;
9711 alc_automute_amp(codec);
9715 #define alc262_capture_mixer alc882_capture_mixer
9716 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9719 * generic initialization of ADC, input mixers and output mixers
9721 static struct hda_verb alc262_init_verbs[] = {
9723 * Unmute ADC0-2 and set the default input to mic-in
9725 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9726 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9727 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9728 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9729 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9730 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9732 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9734 * Note: PASD motherboards uses the Line In 2 as the input for
9735 * front panel mic (mic 2)
9737 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9738 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9739 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9740 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9742 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9745 * Set up output mixers (0x0c - 0x0e)
9747 /* set vol=0 to output mixers */
9748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9750 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9751 /* set up input amps for analog loopback */
9752 /* Amp Indices: DAC = 0, mixer = 1 */
9753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9763 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9764 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9765 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9769 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9770 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9771 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9773 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9774 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9776 /* FIXME: use matrix-type input source selection */
9777 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9778 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9780 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9781 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9782 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9784 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9785 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9786 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9787 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9791 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9797 static struct hda_verb alc262_eapd_verbs[] = {
9798 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9799 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9803 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9804 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9805 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9809 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9810 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9811 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9812 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9814 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9815 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9819 static struct hda_verb alc262_sony_unsol_verbs[] = {
9820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9821 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9822 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9824 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9829 static struct hda_input_mux alc262_dmic_capture_source = {
9832 { "Int DMic", 0x9 },
9837 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9838 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9839 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9842 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9846 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9847 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9848 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9850 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9851 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9852 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9853 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9854 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9858 static void alc262_dmic_automute(struct hda_codec *codec)
9860 unsigned int present;
9862 present = snd_hda_codec_read(codec, 0x18, 0,
9863 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9864 snd_hda_codec_write(codec, 0x22, 0,
9865 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9869 /* unsolicited event for HP jack sensing */
9870 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9873 if ((res >> 26) == ALC880_MIC_EVENT)
9874 alc262_dmic_automute(codec);
9876 alc_sku_unsol_event(codec, res);
9879 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9881 struct alc_spec *spec = codec->spec;
9883 spec->autocfg.hp_pins[0] = 0x15;
9884 spec->autocfg.speaker_pins[0] = 0x14;
9885 alc_automute_pin(codec);
9886 alc262_dmic_automute(codec);
9892 * 0x16 = internal speaker
9893 * 0x18 = external mic
9896 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9897 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9898 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9901 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9902 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9904 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9909 static struct hda_verb alc262_nec_verbs[] = {
9910 /* Unmute Speaker */
9911 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9914 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9915 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9917 /* External mic to headphone */
9918 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9919 /* External mic to speaker */
9920 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9926 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9927 * 0x1b = port replicator headphone out
9930 #define ALC_HP_EVENT 0x37
9932 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9933 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9934 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9935 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9936 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9940 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9946 static struct hda_input_mux alc262_fujitsu_capture_source = {
9955 static struct hda_input_mux alc262_HP_capture_source = {
9959 { "Front Mic", 0x1 },
9966 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9970 { "Front Mic", 0x2 },
9976 /* mute/unmute internal speaker according to the hp jacks and mute state */
9977 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9979 struct alc_spec *spec = codec->spec;
9982 if (force || !spec->sense_updated) {
9983 unsigned int present;
9984 /* need to execute and sync at first */
9985 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9986 /* check laptop HP jack */
9987 present = snd_hda_codec_read(codec, 0x14, 0,
9988 AC_VERB_GET_PIN_SENSE, 0);
9989 /* need to execute and sync at first */
9990 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9991 /* check docking HP jack */
9992 present |= snd_hda_codec_read(codec, 0x1b, 0,
9993 AC_VERB_GET_PIN_SENSE, 0);
9994 if (present & AC_PINSENSE_PRESENCE)
9995 spec->jack_present = 1;
9997 spec->jack_present = 0;
9998 spec->sense_updated = 1;
10000 /* unmute internal speaker only if both HPs are unplugged and
10001 * master switch is on
10003 if (spec->jack_present)
10004 mute = HDA_AMP_MUTE;
10006 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10007 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10008 HDA_AMP_MUTE, mute);
10011 /* unsolicited event for HP jack sensing */
10012 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10015 if ((res >> 26) != ALC_HP_EVENT)
10017 alc262_fujitsu_automute(codec, 1);
10020 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10022 alc262_fujitsu_automute(codec, 1);
10025 /* bind volumes of both NID 0x0c and 0x0d */
10026 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10027 .ops = &snd_hda_bind_vol,
10029 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10030 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10035 /* mute/unmute internal speaker according to the hp jack and mute state */
10036 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10038 struct alc_spec *spec = codec->spec;
10041 if (force || !spec->sense_updated) {
10042 unsigned int present_int_hp;
10043 /* need to execute and sync at first */
10044 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10045 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10046 AC_VERB_GET_PIN_SENSE, 0);
10047 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10048 spec->sense_updated = 1;
10050 if (spec->jack_present) {
10051 /* mute internal speaker */
10052 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10053 HDA_AMP_MUTE, HDA_AMP_MUTE);
10054 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10055 HDA_AMP_MUTE, HDA_AMP_MUTE);
10057 /* unmute internal speaker if necessary */
10058 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10059 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10060 HDA_AMP_MUTE, mute);
10061 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10062 HDA_AMP_MUTE, mute);
10066 /* unsolicited event for HP jack sensing */
10067 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10070 if ((res >> 26) != ALC_HP_EVENT)
10072 alc262_lenovo_3000_automute(codec, 1);
10075 /* bind hp and internal speaker mute (with plug check) */
10076 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10077 struct snd_ctl_elem_value *ucontrol)
10079 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10080 long *valp = ucontrol->value.integer.value;
10083 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10085 valp ? 0 : HDA_AMP_MUTE);
10086 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10088 valp ? 0 : HDA_AMP_MUTE);
10091 alc262_fujitsu_automute(codec, 0);
10095 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10096 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10099 .name = "Master Playback Switch",
10100 .info = snd_hda_mixer_amp_switch_info,
10101 .get = snd_hda_mixer_amp_switch_get,
10102 .put = alc262_fujitsu_master_sw_put,
10103 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10105 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10106 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10107 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10110 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10111 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10112 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10116 /* bind hp and internal speaker mute (with plug check) */
10117 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10118 struct snd_ctl_elem_value *ucontrol)
10120 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10121 long *valp = ucontrol->value.integer.value;
10124 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10126 valp ? 0 : HDA_AMP_MUTE);
10129 alc262_lenovo_3000_automute(codec, 0);
10133 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10134 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10136 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10137 .name = "Master Playback Switch",
10138 .info = snd_hda_mixer_amp_switch_info,
10139 .get = snd_hda_mixer_amp_switch_get,
10140 .put = alc262_lenovo_3000_master_sw_put,
10141 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10143 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10144 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10145 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10148 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10149 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10150 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10154 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10155 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10156 ALC262_HIPPO_MASTER_SWITCH,
10157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10159 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10160 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10161 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10162 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10166 /* additional init verbs for Benq laptops */
10167 static struct hda_verb alc262_EAPD_verbs[] = {
10168 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10169 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10173 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10174 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10175 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10177 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10178 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10182 /* Samsung Q1 Ultra Vista model setup */
10183 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10184 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10185 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10187 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10188 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10189 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10193 static struct hda_verb alc262_ultra_verbs[] = {
10195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10197 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10200 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10201 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10202 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10206 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10207 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10208 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10210 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10212 /* ADC, choose mic */
10213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10214 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10215 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10216 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10218 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10219 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10220 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10222 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10226 /* mute/unmute internal speaker according to the hp jack and mute state */
10227 static void alc262_ultra_automute(struct hda_codec *codec)
10229 struct alc_spec *spec = codec->spec;
10233 /* auto-mute only when HP is used as HP */
10234 if (!spec->cur_mux[0]) {
10235 unsigned int present;
10236 /* need to execute and sync at first */
10237 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10238 present = snd_hda_codec_read(codec, 0x15, 0,
10239 AC_VERB_GET_PIN_SENSE, 0);
10240 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10241 if (spec->jack_present)
10242 mute = HDA_AMP_MUTE;
10244 /* mute/unmute internal speaker */
10245 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10246 HDA_AMP_MUTE, mute);
10247 /* mute/unmute HP */
10248 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10249 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10252 /* unsolicited event for HP jack sensing */
10253 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10256 if ((res >> 26) != ALC880_HP_EVENT)
10258 alc262_ultra_automute(codec);
10261 static struct hda_input_mux alc262_ultra_capture_source = {
10265 { "Headphone", 0x7 },
10269 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10270 struct snd_ctl_elem_value *ucontrol)
10272 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10273 struct alc_spec *spec = codec->spec;
10276 ret = alc_mux_enum_put(kcontrol, ucontrol);
10279 /* reprogram the HP pin as mic or HP according to the input source */
10280 snd_hda_codec_write_cache(codec, 0x15, 0,
10281 AC_VERB_SET_PIN_WIDGET_CONTROL,
10282 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10283 alc262_ultra_automute(codec); /* mute/unmute HP */
10287 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10288 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10289 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10292 .name = "Capture Source",
10293 .info = alc_mux_enum_info,
10294 .get = alc_mux_enum_get,
10295 .put = alc262_ultra_mux_enum_put,
10300 /* add playback controls from the parsed DAC table */
10301 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10302 const struct auto_pin_cfg *cfg)
10307 spec->multiout.num_dacs = 1; /* only use one dac */
10308 spec->multiout.dac_nids = spec->private_dac_nids;
10309 spec->multiout.dac_nids[0] = 2;
10311 nid = cfg->line_out_pins[0];
10313 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10314 "Front Playback Volume",
10315 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10318 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10319 "Front Playback Switch",
10320 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10325 nid = cfg->speaker_pins[0];
10328 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10329 "Speaker Playback Volume",
10330 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10334 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10335 "Speaker Playback Switch",
10336 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10341 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10342 "Speaker Playback Switch",
10343 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10349 nid = cfg->hp_pins[0];
10351 /* spec->multiout.hp_nid = 2; */
10353 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10354 "Headphone Playback Volume",
10355 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10359 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10360 "Headphone Playback Switch",
10361 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10366 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10367 "Headphone Playback Switch",
10368 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10377 /* identical with ALC880 */
10378 #define alc262_auto_create_analog_input_ctls \
10379 alc880_auto_create_analog_input_ctls
10382 * generic initialization of ADC, input mixers and output mixers
10384 static struct hda_verb alc262_volume_init_verbs[] = {
10386 * Unmute ADC0-2 and set the default input to mic-in
10388 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10390 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10391 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10392 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10395 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10397 * Note: PASD motherboards uses the Line In 2 as the input for
10398 * front panel mic (mic 2)
10400 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10408 * Set up output mixers (0x0c - 0x0f)
10410 /* set vol=0 to output mixers */
10411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10415 /* set up input amps for analog loopback */
10416 /* Amp Indices: DAC = 0, mixer = 1 */
10417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10418 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10421 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10422 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10424 /* FIXME: use matrix-type input source selection */
10425 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10426 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10428 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10429 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10430 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10433 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10434 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10435 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10440 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10445 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10447 * Unmute ADC0-2 and set the default input to mic-in
10449 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10451 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10452 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10453 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10454 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10456 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10458 * Note: PASD motherboards uses the Line In 2 as the input for
10459 * front panel mic (mic 2)
10461 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10462 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10463 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10464 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10465 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10466 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10467 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10468 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10471 * Set up output mixers (0x0c - 0x0e)
10473 /* set vol=0 to output mixers */
10474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10475 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10476 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10478 /* set up input amps for analog loopback */
10479 /* Amp Indices: DAC = 0, mixer = 1 */
10480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10485 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10489 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10491 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10494 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10495 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10497 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10499 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10500 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10501 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10503 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10504 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10506 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10507 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10508 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10511 /* FIXME: use matrix-type input source selection */
10512 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10513 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10514 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10529 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10534 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10536 * Unmute ADC0-2 and set the default input to mic-in
10538 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10540 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10541 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10542 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10543 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10545 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10547 * Note: PASD motherboards uses the Line In 2 as the input for front
10548 * panel mic (mic 2)
10550 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10555 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10560 * Set up output mixers (0x0c - 0x0e)
10562 /* set vol=0 to output mixers */
10563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10567 /* set up input amps for analog loopback */
10568 /* Amp Indices: DAC = 0, mixer = 1 */
10569 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10570 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10571 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10573 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10574 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10577 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10578 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10579 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10580 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10581 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10583 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10588 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10589 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10591 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10592 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10593 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10594 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10595 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10596 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10598 /* FIXME: use matrix-type input source selection */
10599 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10600 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10603 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10604 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10605 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10606 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10609 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10610 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10611 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10614 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10622 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10625 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10630 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10632 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10633 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10634 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10636 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10638 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10639 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10641 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10642 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10643 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10648 #ifdef CONFIG_SND_HDA_POWER_SAVE
10649 #define alc262_loopbacks alc880_loopbacks
10652 /* pcm configuration: identiacal with ALC880 */
10653 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10654 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10655 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10656 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10659 * BIOS auto configuration
10661 static int alc262_parse_auto_config(struct hda_codec *codec)
10663 struct alc_spec *spec = codec->spec;
10665 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10667 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10671 if (!spec->autocfg.line_outs) {
10672 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10673 spec->multiout.max_channels = 2;
10674 spec->no_analog = 1;
10677 return 0; /* can't find valid BIOS pin config */
10679 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10682 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10686 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10689 if (spec->autocfg.dig_outs) {
10690 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10691 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10693 if (spec->autocfg.dig_in_pin)
10694 spec->dig_in_nid = ALC262_DIGIN_NID;
10696 if (spec->kctls.list)
10697 add_mixer(spec, spec->kctls.list);
10699 add_verb(spec, alc262_volume_init_verbs);
10700 spec->num_mux_defs = 1;
10701 spec->input_mux = &spec->private_imux[0];
10703 err = alc_auto_add_mic_boost(codec);
10707 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10712 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10713 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10714 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10715 #define alc262_auto_init_input_src alc882_auto_init_input_src
10718 /* init callback for auto-configuration model -- overriding the default init */
10719 static void alc262_auto_init(struct hda_codec *codec)
10721 struct alc_spec *spec = codec->spec;
10722 alc262_auto_init_multi_out(codec);
10723 alc262_auto_init_hp_out(codec);
10724 alc262_auto_init_analog_input(codec);
10725 alc262_auto_init_input_src(codec);
10726 if (spec->unsol_event)
10727 alc_inithook(codec);
10731 * configuration and preset
10733 static const char *alc262_models[ALC262_MODEL_LAST] = {
10734 [ALC262_BASIC] = "basic",
10735 [ALC262_HIPPO] = "hippo",
10736 [ALC262_HIPPO_1] = "hippo_1",
10737 [ALC262_FUJITSU] = "fujitsu",
10738 [ALC262_HP_BPC] = "hp-bpc",
10739 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10740 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10741 [ALC262_HP_RP5700] = "hp-rp5700",
10742 [ALC262_BENQ_ED8] = "benq",
10743 [ALC262_BENQ_T31] = "benq-t31",
10744 [ALC262_SONY_ASSAMD] = "sony-assamd",
10745 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10746 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10747 [ALC262_ULTRA] = "ultra",
10748 [ALC262_LENOVO_3000] = "lenovo-3000",
10749 [ALC262_NEC] = "nec",
10750 [ALC262_TYAN] = "tyan",
10751 [ALC262_AUTO] = "auto",
10754 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10755 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10756 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10757 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10759 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10761 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10763 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10764 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10765 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10766 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10767 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10768 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10769 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10770 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10771 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10772 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10773 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10774 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10775 ALC262_HP_TC_T5735),
10776 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10777 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10778 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10779 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10780 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10781 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10782 ALC262_SONY_ASSAMD),
10783 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10784 ALC262_TOSHIBA_RX1),
10785 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10786 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10787 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10788 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10789 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10791 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10792 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10793 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10794 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10795 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10799 static struct alc_config_preset alc262_presets[] = {
10801 .mixers = { alc262_base_mixer },
10802 .init_verbs = { alc262_init_verbs },
10803 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10804 .dac_nids = alc262_dac_nids,
10806 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10807 .channel_mode = alc262_modes,
10808 .input_mux = &alc262_capture_source,
10811 .mixers = { alc262_hippo_mixer },
10812 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10813 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10814 .dac_nids = alc262_dac_nids,
10816 .dig_out_nid = ALC262_DIGOUT_NID,
10817 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10818 .channel_mode = alc262_modes,
10819 .input_mux = &alc262_capture_source,
10820 .unsol_event = alc262_hippo_unsol_event,
10821 .init_hook = alc262_hippo_init_hook,
10823 [ALC262_HIPPO_1] = {
10824 .mixers = { alc262_hippo1_mixer },
10825 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10826 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10827 .dac_nids = alc262_dac_nids,
10829 .dig_out_nid = ALC262_DIGOUT_NID,
10830 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10831 .channel_mode = alc262_modes,
10832 .input_mux = &alc262_capture_source,
10833 .unsol_event = alc262_hippo_unsol_event,
10834 .init_hook = alc262_hippo1_init_hook,
10836 [ALC262_FUJITSU] = {
10837 .mixers = { alc262_fujitsu_mixer },
10838 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10839 alc262_fujitsu_unsol_verbs },
10840 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10841 .dac_nids = alc262_dac_nids,
10843 .dig_out_nid = ALC262_DIGOUT_NID,
10844 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10845 .channel_mode = alc262_modes,
10846 .input_mux = &alc262_fujitsu_capture_source,
10847 .unsol_event = alc262_fujitsu_unsol_event,
10848 .init_hook = alc262_fujitsu_init_hook,
10850 [ALC262_HP_BPC] = {
10851 .mixers = { alc262_HP_BPC_mixer },
10852 .init_verbs = { alc262_HP_BPC_init_verbs },
10853 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10854 .dac_nids = alc262_dac_nids,
10856 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10857 .channel_mode = alc262_modes,
10858 .input_mux = &alc262_HP_capture_source,
10859 .unsol_event = alc262_hp_bpc_unsol_event,
10860 .init_hook = alc262_hp_bpc_automute,
10862 [ALC262_HP_BPC_D7000_WF] = {
10863 .mixers = { alc262_HP_BPC_WildWest_mixer },
10864 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10865 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10866 .dac_nids = alc262_dac_nids,
10868 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10869 .channel_mode = alc262_modes,
10870 .input_mux = &alc262_HP_D7000_capture_source,
10871 .unsol_event = alc262_hp_wildwest_unsol_event,
10872 .init_hook = alc262_hp_wildwest_automute,
10874 [ALC262_HP_BPC_D7000_WL] = {
10875 .mixers = { alc262_HP_BPC_WildWest_mixer,
10876 alc262_HP_BPC_WildWest_option_mixer },
10877 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10878 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10879 .dac_nids = alc262_dac_nids,
10881 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10882 .channel_mode = alc262_modes,
10883 .input_mux = &alc262_HP_D7000_capture_source,
10884 .unsol_event = alc262_hp_wildwest_unsol_event,
10885 .init_hook = alc262_hp_wildwest_automute,
10887 [ALC262_HP_TC_T5735] = {
10888 .mixers = { alc262_hp_t5735_mixer },
10889 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10890 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10891 .dac_nids = alc262_dac_nids,
10893 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10894 .channel_mode = alc262_modes,
10895 .input_mux = &alc262_capture_source,
10896 .unsol_event = alc_automute_amp_unsol_event,
10897 .init_hook = alc262_hp_t5735_init_hook,
10899 [ALC262_HP_RP5700] = {
10900 .mixers = { alc262_hp_rp5700_mixer },
10901 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10902 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10903 .dac_nids = alc262_dac_nids,
10904 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10905 .channel_mode = alc262_modes,
10906 .input_mux = &alc262_hp_rp5700_capture_source,
10908 [ALC262_BENQ_ED8] = {
10909 .mixers = { alc262_base_mixer },
10910 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10911 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10912 .dac_nids = alc262_dac_nids,
10914 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10915 .channel_mode = alc262_modes,
10916 .input_mux = &alc262_capture_source,
10918 [ALC262_SONY_ASSAMD] = {
10919 .mixers = { alc262_sony_mixer },
10920 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10921 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10922 .dac_nids = alc262_dac_nids,
10924 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10925 .channel_mode = alc262_modes,
10926 .input_mux = &alc262_capture_source,
10927 .unsol_event = alc262_hippo_unsol_event,
10928 .init_hook = alc262_hippo_init_hook,
10930 [ALC262_BENQ_T31] = {
10931 .mixers = { alc262_benq_t31_mixer },
10932 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10933 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10934 .dac_nids = alc262_dac_nids,
10936 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10937 .channel_mode = alc262_modes,
10938 .input_mux = &alc262_capture_source,
10939 .unsol_event = alc262_hippo_unsol_event,
10940 .init_hook = alc262_hippo_init_hook,
10943 .mixers = { alc262_ultra_mixer },
10944 .cap_mixer = alc262_ultra_capture_mixer,
10945 .init_verbs = { alc262_ultra_verbs },
10946 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10947 .dac_nids = alc262_dac_nids,
10948 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10949 .channel_mode = alc262_modes,
10950 .input_mux = &alc262_ultra_capture_source,
10951 .adc_nids = alc262_adc_nids, /* ADC0 */
10952 .capsrc_nids = alc262_capsrc_nids,
10953 .num_adc_nids = 1, /* single ADC */
10954 .unsol_event = alc262_ultra_unsol_event,
10955 .init_hook = alc262_ultra_automute,
10957 [ALC262_LENOVO_3000] = {
10958 .mixers = { alc262_lenovo_3000_mixer },
10959 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10960 alc262_lenovo_3000_unsol_verbs },
10961 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10962 .dac_nids = alc262_dac_nids,
10964 .dig_out_nid = ALC262_DIGOUT_NID,
10965 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10966 .channel_mode = alc262_modes,
10967 .input_mux = &alc262_fujitsu_capture_source,
10968 .unsol_event = alc262_lenovo_3000_unsol_event,
10971 .mixers = { alc262_nec_mixer },
10972 .init_verbs = { alc262_nec_verbs },
10973 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10974 .dac_nids = alc262_dac_nids,
10976 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10977 .channel_mode = alc262_modes,
10978 .input_mux = &alc262_capture_source,
10980 [ALC262_TOSHIBA_S06] = {
10981 .mixers = { alc262_toshiba_s06_mixer },
10982 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10983 alc262_eapd_verbs },
10984 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10985 .capsrc_nids = alc262_dmic_capsrc_nids,
10986 .dac_nids = alc262_dac_nids,
10987 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10988 .dig_out_nid = ALC262_DIGOUT_NID,
10989 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10990 .channel_mode = alc262_modes,
10991 .input_mux = &alc262_dmic_capture_source,
10992 .unsol_event = alc262_toshiba_s06_unsol_event,
10993 .init_hook = alc262_toshiba_s06_init_hook,
10995 [ALC262_TOSHIBA_RX1] = {
10996 .mixers = { alc262_toshiba_rx1_mixer },
10997 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10998 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10999 .dac_nids = alc262_dac_nids,
11001 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11002 .channel_mode = alc262_modes,
11003 .input_mux = &alc262_capture_source,
11004 .unsol_event = alc262_hippo_unsol_event,
11005 .init_hook = alc262_hippo_init_hook,
11008 .mixers = { alc262_tyan_mixer },
11009 .init_verbs = { alc262_init_verbs, alc262_tyan_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 = alc_automute_amp_unsol_event,
11018 .init_hook = alc262_tyan_init_hook,
11022 static int patch_alc262(struct hda_codec *codec)
11024 struct alc_spec *spec;
11028 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11032 codec->spec = spec;
11034 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11039 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11040 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11041 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11042 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11046 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11048 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11052 if (board_config < 0) {
11053 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11054 "trying auto-probe from BIOS...\n");
11055 board_config = ALC262_AUTO;
11058 if (board_config == ALC262_AUTO) {
11059 /* automatic parse from the BIOS config */
11060 err = alc262_parse_auto_config(codec);
11066 "hda_codec: Cannot set up configuration "
11067 "from BIOS. Using base mode...\n");
11068 board_config = ALC262_BASIC;
11072 if (!spec->no_analog) {
11073 err = snd_hda_attach_beep_device(codec, 0x1);
11080 if (board_config != ALC262_AUTO)
11081 setup_preset(spec, &alc262_presets[board_config]);
11083 spec->stream_name_analog = "ALC262 Analog";
11084 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11085 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11087 spec->stream_name_digital = "ALC262 Digital";
11088 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11089 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11091 spec->capture_style = CAPT_MIX;
11092 if (!spec->adc_nids && spec->input_mux) {
11093 /* check whether NID 0x07 is valid */
11094 unsigned int wcap = get_wcaps(codec, 0x07);
11097 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11098 if (wcap != AC_WID_AUD_IN) {
11099 spec->adc_nids = alc262_adc_nids_alt;
11100 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11101 spec->capsrc_nids = alc262_capsrc_nids_alt;
11103 spec->adc_nids = alc262_adc_nids;
11104 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11105 spec->capsrc_nids = alc262_capsrc_nids;
11108 if (!spec->cap_mixer && !spec->no_analog)
11109 set_capture_mixer(spec);
11110 if (!spec->no_analog)
11111 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11113 spec->vmaster_nid = 0x0c;
11115 codec->patch_ops = alc_patch_ops;
11116 if (board_config == ALC262_AUTO)
11117 spec->init_hook = alc262_auto_init;
11118 #ifdef CONFIG_SND_HDA_POWER_SAVE
11119 if (!spec->loopback.amplist)
11120 spec->loopback.amplist = alc262_loopbacks;
11122 codec->proc_widget_hook = print_realtek_coef;
11128 * ALC268 channel source setting (2 channel)
11130 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11131 #define alc268_modes alc260_modes
11133 static hda_nid_t alc268_dac_nids[2] = {
11138 static hda_nid_t alc268_adc_nids[2] = {
11143 static hda_nid_t alc268_adc_nids_alt[1] = {
11148 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11150 static struct snd_kcontrol_new alc268_base_mixer[] = {
11151 /* output mixer control */
11152 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11153 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11154 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11155 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11156 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11157 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11158 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11162 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11163 /* output mixer control */
11164 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11166 ALC262_HIPPO_MASTER_SWITCH,
11167 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11168 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11169 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11173 /* bind Beep switches of both NID 0x0f and 0x10 */
11174 static struct hda_bind_ctls alc268_bind_beep_sw = {
11175 .ops = &snd_hda_bind_sw,
11177 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11178 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11183 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11184 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11185 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11189 static struct hda_verb alc268_eapd_verbs[] = {
11190 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11191 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11195 /* Toshiba specific */
11196 static struct hda_verb alc268_toshiba_verbs[] = {
11197 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11201 static struct hda_input_mux alc268_acer_lc_capture_source = {
11209 /* Acer specific */
11210 /* bind volumes of both NID 0x02 and 0x03 */
11211 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11212 .ops = &snd_hda_bind_vol,
11214 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11215 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11220 /* mute/unmute internal speaker according to the hp jack and mute state */
11221 static void alc268_acer_automute(struct hda_codec *codec, int force)
11223 struct alc_spec *spec = codec->spec;
11226 if (force || !spec->sense_updated) {
11227 unsigned int present;
11228 present = snd_hda_codec_read(codec, 0x14, 0,
11229 AC_VERB_GET_PIN_SENSE, 0);
11230 spec->jack_present = (present & 0x80000000) != 0;
11231 spec->sense_updated = 1;
11233 if (spec->jack_present)
11234 mute = HDA_AMP_MUTE; /* mute internal speaker */
11235 else /* unmute internal speaker if necessary */
11236 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11237 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11238 HDA_AMP_MUTE, mute);
11242 /* bind hp and internal speaker mute (with plug check) */
11243 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11244 struct snd_ctl_elem_value *ucontrol)
11246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11247 long *valp = ucontrol->value.integer.value;
11250 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11252 valp[0] ? 0 : HDA_AMP_MUTE);
11253 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11255 valp[1] ? 0 : HDA_AMP_MUTE);
11257 alc268_acer_automute(codec, 0);
11261 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11262 /* output mixer control */
11263 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11266 .name = "Master Playback Switch",
11267 .info = snd_hda_mixer_amp_switch_info,
11268 .get = snd_hda_mixer_amp_switch_get,
11269 .put = alc268_acer_master_sw_put,
11270 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11272 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11276 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11277 /* output mixer control */
11278 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11280 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11281 .name = "Master Playback Switch",
11282 .info = snd_hda_mixer_amp_switch_info,
11283 .get = snd_hda_mixer_amp_switch_get,
11284 .put = alc268_acer_master_sw_put,
11285 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11287 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11288 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11289 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11293 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11294 /* output mixer control */
11295 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11298 .name = "Master Playback Switch",
11299 .info = snd_hda_mixer_amp_switch_info,
11300 .get = snd_hda_mixer_amp_switch_get,
11301 .put = alc268_acer_master_sw_put,
11302 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11304 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11305 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11309 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11310 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11312 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11313 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11314 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11319 static struct hda_verb alc268_acer_verbs[] = {
11320 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11321 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11322 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11324 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11326 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11330 /* unsolicited event for HP jack sensing */
11331 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11332 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11334 static void alc268_acer_unsol_event(struct hda_codec *codec,
11337 if ((res >> 26) != ALC880_HP_EVENT)
11339 alc268_acer_automute(codec, 1);
11342 static void alc268_acer_init_hook(struct hda_codec *codec)
11344 alc268_acer_automute(codec, 1);
11347 /* toggle speaker-output according to the hp-jack state */
11348 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11350 unsigned int present;
11351 unsigned char bits;
11353 present = snd_hda_codec_read(codec, 0x15, 0,
11354 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11355 bits = present ? AMP_IN_MUTE(0) : 0;
11356 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11357 AMP_IN_MUTE(0), bits);
11358 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11359 AMP_IN_MUTE(0), bits);
11363 static void alc268_acer_mic_automute(struct hda_codec *codec)
11365 unsigned int present;
11367 present = snd_hda_codec_read(codec, 0x18, 0,
11368 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11369 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11370 present ? 0x0 : 0x6);
11373 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11376 if ((res >> 26) == ALC880_HP_EVENT)
11377 alc268_aspire_one_speaker_automute(codec);
11378 if ((res >> 26) == ALC880_MIC_EVENT)
11379 alc268_acer_mic_automute(codec);
11382 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11384 alc268_aspire_one_speaker_automute(codec);
11385 alc268_acer_mic_automute(codec);
11388 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11389 /* output mixer control */
11390 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11391 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11392 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11393 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11394 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11395 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11399 static struct hda_verb alc268_dell_verbs[] = {
11400 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11401 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11402 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11406 /* mute/unmute internal speaker according to the hp jack and mute state */
11407 static void alc268_dell_init_hook(struct hda_codec *codec)
11409 struct alc_spec *spec = codec->spec;
11411 spec->autocfg.hp_pins[0] = 0x15;
11412 spec->autocfg.speaker_pins[0] = 0x14;
11413 alc_automute_pin(codec);
11416 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11417 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11418 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11419 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11421 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11422 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11423 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11424 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11428 static struct hda_verb alc267_quanta_il1_verbs[] = {
11429 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11430 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11434 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11436 unsigned int present;
11438 present = snd_hda_codec_read(codec, 0x18, 0,
11439 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11440 snd_hda_codec_write(codec, 0x23, 0,
11441 AC_VERB_SET_CONNECT_SEL,
11442 present ? 0x00 : 0x01);
11445 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11447 struct alc_spec *spec = codec->spec;
11449 spec->autocfg.hp_pins[0] = 0x15;
11450 spec->autocfg.speaker_pins[0] = 0x14;
11451 alc_automute_pin(codec);
11452 alc267_quanta_il1_mic_automute(codec);
11455 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11458 switch (res >> 26) {
11459 case ALC880_MIC_EVENT:
11460 alc267_quanta_il1_mic_automute(codec);
11463 alc_sku_unsol_event(codec, res);
11469 * generic initialization of ADC, input mixers and output mixers
11471 static struct hda_verb alc268_base_init_verbs[] = {
11472 /* Unmute DAC0-1 and set vol = 0 */
11473 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11474 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11477 * Set up output mixers (0x0c - 0x0e)
11479 /* set vol=0 to output mixers */
11480 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11481 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11483 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11484 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11486 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11488 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11490 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11491 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11492 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11493 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11495 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11497 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11498 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11499 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11501 /* set PCBEEP vol = 0, mute connections */
11502 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11503 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11504 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11506 /* Unmute Selector 23h,24h and set the default input to mic-in */
11508 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11509 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11510 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11511 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11517 * generic initialization of ADC, input mixers and output mixers
11519 static struct hda_verb alc268_volume_init_verbs[] = {
11520 /* set output DAC */
11521 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11522 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11526 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11527 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11528 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11530 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11531 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11532 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11535 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11537 /* set PCBEEP vol = 0, mute connections */
11538 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11540 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11545 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11546 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11547 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11549 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11550 /* The multiple "Capture Source" controls confuse alsamixer
11551 * So call somewhat different..
11553 /* .name = "Capture Source", */
11554 .name = "Input Source",
11556 .info = alc_mux_enum_info,
11557 .get = alc_mux_enum_get,
11558 .put = alc_mux_enum_put,
11563 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11564 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11565 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11566 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11567 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11570 /* The multiple "Capture Source" controls confuse alsamixer
11571 * So call somewhat different..
11573 /* .name = "Capture Source", */
11574 .name = "Input Source",
11576 .info = alc_mux_enum_info,
11577 .get = alc_mux_enum_get,
11578 .put = alc_mux_enum_put,
11583 static struct hda_input_mux alc268_capture_source = {
11587 { "Front Mic", 0x1 },
11593 static struct hda_input_mux alc268_acer_capture_source = {
11597 { "Internal Mic", 0x1 },
11602 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11606 { "Internal Mic", 0x6 },
11611 #ifdef CONFIG_SND_DEBUG
11612 static struct snd_kcontrol_new alc268_test_mixer[] = {
11613 /* Volume widgets */
11614 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11615 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11616 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11617 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11618 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11619 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11620 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11621 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11622 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11623 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11624 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11625 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11626 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11627 /* The below appears problematic on some hardwares */
11628 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11629 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11630 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11631 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11632 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11634 /* Modes for retasking pin widgets */
11635 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11636 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11637 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11638 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11640 /* Controls for GPIO pins, assuming they are configured as outputs */
11641 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11642 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11643 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11644 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11646 /* Switches to allow the digital SPDIF output pin to be enabled.
11647 * The ALC268 does not have an SPDIF input.
11649 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11651 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11652 * this output to turn on an external amplifier.
11654 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11655 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11661 /* create input playback/capture controls for the given pin */
11662 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11663 const char *ctlname, int idx)
11668 sprintf(name, "%s Playback Volume", ctlname);
11670 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11671 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11675 } else if (nid == 0x15) {
11676 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11677 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11683 sprintf(name, "%s Playback Switch", ctlname);
11684 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11685 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11691 /* add playback controls from the parsed DAC table */
11692 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11693 const struct auto_pin_cfg *cfg)
11698 spec->multiout.num_dacs = 2; /* only use one dac */
11699 spec->multiout.dac_nids = spec->private_dac_nids;
11700 spec->multiout.dac_nids[0] = 2;
11701 spec->multiout.dac_nids[1] = 3;
11703 nid = cfg->line_out_pins[0];
11705 alc268_new_analog_output(spec, nid, "Front", 0);
11707 nid = cfg->speaker_pins[0];
11709 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11710 "Speaker Playback Volume",
11711 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11715 nid = cfg->hp_pins[0];
11717 alc268_new_analog_output(spec, nid, "Headphone", 0);
11719 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11721 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11722 "Mono Playback Switch",
11723 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11730 /* create playback/capture controls for input pins */
11731 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11732 const struct auto_pin_cfg *cfg)
11734 struct hda_input_mux *imux = &spec->private_imux[0];
11737 for (i = 0; i < AUTO_PIN_LAST; i++) {
11738 switch(cfg->input_pins[i]) {
11740 idx1 = 0; /* Mic 1 */
11743 idx1 = 1; /* Mic 2 */
11746 idx1 = 2; /* Line In */
11753 idx1 = 6; /* digital mics */
11758 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11759 imux->items[imux->num_items].index = idx1;
11765 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11767 struct alc_spec *spec = codec->spec;
11768 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11769 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11770 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11771 unsigned int dac_vol1, dac_vol2;
11774 snd_hda_codec_write(codec, speaker_nid, 0,
11775 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11776 snd_hda_codec_write(codec, 0x0f, 0,
11777 AC_VERB_SET_AMP_GAIN_MUTE,
11779 snd_hda_codec_write(codec, 0x10, 0,
11780 AC_VERB_SET_AMP_GAIN_MUTE,
11783 snd_hda_codec_write(codec, 0x0f, 0,
11784 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11785 snd_hda_codec_write(codec, 0x10, 0,
11786 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11789 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11790 if (line_nid == 0x14)
11791 dac_vol2 = AMP_OUT_ZERO;
11792 else if (line_nid == 0x15)
11793 dac_vol1 = AMP_OUT_ZERO;
11794 if (hp_nid == 0x14)
11795 dac_vol2 = AMP_OUT_ZERO;
11796 else if (hp_nid == 0x15)
11797 dac_vol1 = AMP_OUT_ZERO;
11798 if (line_nid != 0x16 || hp_nid != 0x16 ||
11799 spec->autocfg.line_out_pins[1] != 0x16 ||
11800 spec->autocfg.line_out_pins[2] != 0x16)
11801 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11803 snd_hda_codec_write(codec, 0x02, 0,
11804 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11805 snd_hda_codec_write(codec, 0x03, 0,
11806 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11809 /* pcm configuration: identiacal with ALC880 */
11810 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11811 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11812 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11813 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11816 * BIOS auto configuration
11818 static int alc268_parse_auto_config(struct hda_codec *codec)
11820 struct alc_spec *spec = codec->spec;
11822 static hda_nid_t alc268_ignore[] = { 0 };
11824 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11828 if (!spec->autocfg.line_outs) {
11829 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11830 spec->multiout.max_channels = 2;
11831 spec->no_analog = 1;
11834 return 0; /* can't find valid BIOS pin config */
11836 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11839 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11843 spec->multiout.max_channels = 2;
11846 /* digital only support output */
11847 if (spec->autocfg.dig_outs) {
11848 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11849 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11851 if (spec->kctls.list)
11852 add_mixer(spec, spec->kctls.list);
11854 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
11855 add_mixer(spec, alc268_beep_mixer);
11857 add_verb(spec, alc268_volume_init_verbs);
11858 spec->num_mux_defs = 1;
11859 spec->input_mux = &spec->private_imux[0];
11861 err = alc_auto_add_mic_boost(codec);
11868 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11869 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11870 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11872 /* init callback for auto-configuration model -- overriding the default init */
11873 static void alc268_auto_init(struct hda_codec *codec)
11875 struct alc_spec *spec = codec->spec;
11876 alc268_auto_init_multi_out(codec);
11877 alc268_auto_init_hp_out(codec);
11878 alc268_auto_init_mono_speaker_out(codec);
11879 alc268_auto_init_analog_input(codec);
11880 if (spec->unsol_event)
11881 alc_inithook(codec);
11885 * configuration and preset
11887 static const char *alc268_models[ALC268_MODEL_LAST] = {
11888 [ALC267_QUANTA_IL1] = "quanta-il1",
11889 [ALC268_3ST] = "3stack",
11890 [ALC268_TOSHIBA] = "toshiba",
11891 [ALC268_ACER] = "acer",
11892 [ALC268_ACER_DMIC] = "acer-dmic",
11893 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11894 [ALC268_DELL] = "dell",
11895 [ALC268_ZEPTO] = "zepto",
11896 #ifdef CONFIG_SND_DEBUG
11897 [ALC268_TEST] = "test",
11899 [ALC268_AUTO] = "auto",
11902 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11903 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11904 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11905 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11906 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11907 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11908 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11909 ALC268_ACER_ASPIRE_ONE),
11910 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11911 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
11912 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11913 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11914 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11915 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11916 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11917 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11918 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11919 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11920 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11924 static struct alc_config_preset alc268_presets[] = {
11925 [ALC267_QUANTA_IL1] = {
11926 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
11927 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11928 alc267_quanta_il1_verbs },
11929 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11930 .dac_nids = alc268_dac_nids,
11931 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11932 .adc_nids = alc268_adc_nids_alt,
11934 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11935 .channel_mode = alc268_modes,
11936 .input_mux = &alc268_capture_source,
11937 .unsol_event = alc267_quanta_il1_unsol_event,
11938 .init_hook = alc267_quanta_il1_init_hook,
11941 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11942 alc268_beep_mixer },
11943 .init_verbs = { alc268_base_init_verbs },
11944 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11945 .dac_nids = alc268_dac_nids,
11946 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11947 .adc_nids = alc268_adc_nids_alt,
11948 .capsrc_nids = alc268_capsrc_nids,
11950 .dig_out_nid = ALC268_DIGOUT_NID,
11951 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11952 .channel_mode = alc268_modes,
11953 .input_mux = &alc268_capture_source,
11955 [ALC268_TOSHIBA] = {
11956 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
11957 alc268_beep_mixer },
11958 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11959 alc268_toshiba_verbs },
11960 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11961 .dac_nids = alc268_dac_nids,
11962 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11963 .adc_nids = alc268_adc_nids_alt,
11964 .capsrc_nids = alc268_capsrc_nids,
11966 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11967 .channel_mode = alc268_modes,
11968 .input_mux = &alc268_capture_source,
11969 .unsol_event = alc268_toshiba_unsol_event,
11970 .init_hook = alc268_toshiba_init_hook,
11973 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11974 alc268_beep_mixer },
11975 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11976 alc268_acer_verbs },
11977 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11978 .dac_nids = alc268_dac_nids,
11979 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11980 .adc_nids = alc268_adc_nids_alt,
11981 .capsrc_nids = alc268_capsrc_nids,
11983 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11984 .channel_mode = alc268_modes,
11985 .input_mux = &alc268_acer_capture_source,
11986 .unsol_event = alc268_acer_unsol_event,
11987 .init_hook = alc268_acer_init_hook,
11989 [ALC268_ACER_DMIC] = {
11990 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11991 alc268_beep_mixer },
11992 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11993 alc268_acer_verbs },
11994 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11995 .dac_nids = alc268_dac_nids,
11996 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11997 .adc_nids = alc268_adc_nids_alt,
11998 .capsrc_nids = alc268_capsrc_nids,
12000 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12001 .channel_mode = alc268_modes,
12002 .input_mux = &alc268_acer_dmic_capture_source,
12003 .unsol_event = alc268_acer_unsol_event,
12004 .init_hook = alc268_acer_init_hook,
12006 [ALC268_ACER_ASPIRE_ONE] = {
12007 .mixers = { alc268_acer_aspire_one_mixer,
12009 alc268_capture_alt_mixer },
12010 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12011 alc268_acer_aspire_one_verbs },
12012 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12013 .dac_nids = alc268_dac_nids,
12014 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12015 .adc_nids = alc268_adc_nids_alt,
12016 .capsrc_nids = alc268_capsrc_nids,
12018 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12019 .channel_mode = alc268_modes,
12020 .input_mux = &alc268_acer_lc_capture_source,
12021 .unsol_event = alc268_acer_lc_unsol_event,
12022 .init_hook = alc268_acer_lc_init_hook,
12025 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12026 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12027 alc268_dell_verbs },
12028 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12029 .dac_nids = alc268_dac_nids,
12031 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12032 .channel_mode = alc268_modes,
12033 .unsol_event = alc_sku_unsol_event,
12034 .init_hook = alc268_dell_init_hook,
12035 .input_mux = &alc268_capture_source,
12038 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12039 alc268_beep_mixer },
12040 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12041 alc268_toshiba_verbs },
12042 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12043 .dac_nids = alc268_dac_nids,
12044 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12045 .adc_nids = alc268_adc_nids_alt,
12046 .capsrc_nids = alc268_capsrc_nids,
12048 .dig_out_nid = ALC268_DIGOUT_NID,
12049 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12050 .channel_mode = alc268_modes,
12051 .input_mux = &alc268_capture_source,
12052 .unsol_event = alc268_toshiba_unsol_event,
12053 .init_hook = alc268_toshiba_init_hook
12055 #ifdef CONFIG_SND_DEBUG
12057 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12058 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12059 alc268_volume_init_verbs },
12060 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12061 .dac_nids = alc268_dac_nids,
12062 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12063 .adc_nids = alc268_adc_nids_alt,
12064 .capsrc_nids = alc268_capsrc_nids,
12066 .dig_out_nid = ALC268_DIGOUT_NID,
12067 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12068 .channel_mode = alc268_modes,
12069 .input_mux = &alc268_capture_source,
12074 static int patch_alc268(struct hda_codec *codec)
12076 struct alc_spec *spec;
12078 int i, has_beep, err;
12080 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12084 codec->spec = spec;
12086 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12090 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12091 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12092 "trying auto-probe from BIOS...\n");
12093 board_config = ALC268_AUTO;
12096 if (board_config == ALC268_AUTO) {
12097 /* automatic parse from the BIOS config */
12098 err = alc268_parse_auto_config(codec);
12104 "hda_codec: Cannot set up configuration "
12105 "from BIOS. Using base mode...\n");
12106 board_config = ALC268_3ST;
12110 if (board_config != ALC268_AUTO)
12111 setup_preset(spec, &alc268_presets[board_config]);
12113 if (codec->vendor_id == 0x10ec0267) {
12114 spec->stream_name_analog = "ALC267 Analog";
12115 spec->stream_name_digital = "ALC267 Digital";
12117 spec->stream_name_analog = "ALC268 Analog";
12118 spec->stream_name_digital = "ALC268 Digital";
12121 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12122 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12123 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12125 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12128 for (i = 0; i < spec->num_mixers; i++) {
12129 if (spec->mixers[i] == alc268_beep_mixer) {
12136 err = snd_hda_attach_beep_device(codec, 0x1);
12141 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12142 /* override the amp caps for beep generator */
12143 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12144 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12145 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12146 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12147 (0 << AC_AMPCAP_MUTE_SHIFT));
12150 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12151 /* check whether NID 0x07 is valid */
12152 unsigned int wcap = get_wcaps(codec, 0x07);
12156 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12157 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12158 spec->adc_nids = alc268_adc_nids_alt;
12159 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12160 add_mixer(spec, alc268_capture_alt_mixer);
12162 spec->adc_nids = alc268_adc_nids;
12163 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12164 add_mixer(spec, alc268_capture_mixer);
12166 spec->capsrc_nids = alc268_capsrc_nids;
12167 /* set default input source */
12168 for (i = 0; i < spec->num_adc_nids; i++)
12169 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12170 0, AC_VERB_SET_CONNECT_SEL,
12171 spec->input_mux->items[0].index);
12174 spec->vmaster_nid = 0x02;
12176 codec->patch_ops = alc_patch_ops;
12177 if (board_config == ALC268_AUTO)
12178 spec->init_hook = alc268_auto_init;
12180 codec->proc_widget_hook = print_realtek_coef;
12186 * ALC269 channel source setting (2 channel)
12188 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12190 #define alc269_dac_nids alc260_dac_nids
12192 static hda_nid_t alc269_adc_nids[1] = {
12197 static hda_nid_t alc269_capsrc_nids[1] = {
12201 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12205 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12213 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12221 #define alc269_modes alc260_modes
12222 #define alc269_capture_source alc880_lg_lw_capture_source
12224 static struct snd_kcontrol_new alc269_base_mixer[] = {
12225 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12226 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12227 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12228 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12229 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12231 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12232 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12233 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12234 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12235 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12236 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12240 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12241 /* output mixer control */
12242 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12245 .name = "Master Playback Switch",
12246 .info = snd_hda_mixer_amp_switch_info,
12247 .get = snd_hda_mixer_amp_switch_get,
12248 .put = alc268_acer_master_sw_put,
12249 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12252 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12253 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12254 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12255 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12256 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12260 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12261 /* output mixer control */
12262 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12264 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12265 .name = "Master Playback Switch",
12266 .info = snd_hda_mixer_amp_switch_info,
12267 .get = snd_hda_mixer_amp_switch_get,
12268 .put = alc268_acer_master_sw_put,
12269 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12273 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12274 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12275 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12276 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12277 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12278 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12279 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12283 /* bind volumes of both NID 0x0c and 0x0d */
12284 static struct hda_bind_ctls alc269_epc_bind_vol = {
12285 .ops = &snd_hda_bind_vol,
12287 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12288 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12293 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12294 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12295 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12296 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12300 /* capture mixer elements */
12301 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12302 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12303 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12304 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12309 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12310 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12312 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12316 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12318 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12319 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12321 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12322 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12326 static struct hda_verb alc269_lifebook_verbs[] = {
12327 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12328 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12331 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12332 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12333 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12334 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12335 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12336 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12340 /* toggle speaker-output according to the hp-jack state */
12341 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12343 unsigned int present;
12344 unsigned char bits;
12346 present = snd_hda_codec_read(codec, 0x15, 0,
12347 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12348 bits = present ? AMP_IN_MUTE(0) : 0;
12349 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12350 AMP_IN_MUTE(0), bits);
12351 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12352 AMP_IN_MUTE(0), bits);
12354 snd_hda_codec_write(codec, 0x20, 0,
12355 AC_VERB_SET_COEF_INDEX, 0x0c);
12356 snd_hda_codec_write(codec, 0x20, 0,
12357 AC_VERB_SET_PROC_COEF, 0x680);
12359 snd_hda_codec_write(codec, 0x20, 0,
12360 AC_VERB_SET_COEF_INDEX, 0x0c);
12361 snd_hda_codec_write(codec, 0x20, 0,
12362 AC_VERB_SET_PROC_COEF, 0x480);
12365 /* toggle speaker-output according to the hp-jacks state */
12366 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12368 unsigned int present;
12369 unsigned char bits;
12371 /* Check laptop headphone socket */
12372 present = snd_hda_codec_read(codec, 0x15, 0,
12373 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12375 /* Check port replicator headphone socket */
12376 present |= snd_hda_codec_read(codec, 0x1a, 0,
12377 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12379 bits = present ? AMP_IN_MUTE(0) : 0;
12380 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12381 AMP_IN_MUTE(0), bits);
12382 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12383 AMP_IN_MUTE(0), bits);
12385 snd_hda_codec_write(codec, 0x20, 0,
12386 AC_VERB_SET_COEF_INDEX, 0x0c);
12387 snd_hda_codec_write(codec, 0x20, 0,
12388 AC_VERB_SET_PROC_COEF, 0x680);
12390 snd_hda_codec_write(codec, 0x20, 0,
12391 AC_VERB_SET_COEF_INDEX, 0x0c);
12392 snd_hda_codec_write(codec, 0x20, 0,
12393 AC_VERB_SET_PROC_COEF, 0x480);
12396 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12398 unsigned int present;
12400 present = snd_hda_codec_read(codec, 0x18, 0,
12401 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12402 snd_hda_codec_write(codec, 0x23, 0,
12403 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12406 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12408 unsigned int present_laptop;
12409 unsigned int present_dock;
12411 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12414 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12415 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12417 /* Laptop mic port overrides dock mic port, design decision */
12419 snd_hda_codec_write(codec, 0x23, 0,
12420 AC_VERB_SET_CONNECT_SEL, 0x3);
12421 if (present_laptop)
12422 snd_hda_codec_write(codec, 0x23, 0,
12423 AC_VERB_SET_CONNECT_SEL, 0x0);
12424 if (!present_dock && !present_laptop)
12425 snd_hda_codec_write(codec, 0x23, 0,
12426 AC_VERB_SET_CONNECT_SEL, 0x1);
12429 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12432 if ((res >> 26) == ALC880_HP_EVENT)
12433 alc269_quanta_fl1_speaker_automute(codec);
12434 if ((res >> 26) == ALC880_MIC_EVENT)
12435 alc269_quanta_fl1_mic_automute(codec);
12438 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12441 if ((res >> 26) == ALC880_HP_EVENT)
12442 alc269_lifebook_speaker_automute(codec);
12443 if ((res >> 26) == ALC880_MIC_EVENT)
12444 alc269_lifebook_mic_autoswitch(codec);
12447 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12449 alc269_quanta_fl1_speaker_automute(codec);
12450 alc269_quanta_fl1_mic_automute(codec);
12453 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12455 alc269_lifebook_speaker_automute(codec);
12456 alc269_lifebook_mic_autoswitch(codec);
12459 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12460 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12461 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12462 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12463 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12465 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12466 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12470 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12471 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12472 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12473 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12474 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12475 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12476 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12480 /* toggle speaker-output according to the hp-jack state */
12481 static void alc269_speaker_automute(struct hda_codec *codec)
12483 unsigned int present;
12484 unsigned char bits;
12486 present = snd_hda_codec_read(codec, 0x15, 0,
12487 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12488 bits = present ? AMP_IN_MUTE(0) : 0;
12489 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12490 AMP_IN_MUTE(0), bits);
12491 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12492 AMP_IN_MUTE(0), bits);
12495 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12497 unsigned int present;
12499 present = snd_hda_codec_read(codec, 0x18, 0,
12500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12501 snd_hda_codec_write(codec, 0x23, 0,
12502 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12505 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12507 unsigned int present;
12509 present = snd_hda_codec_read(codec, 0x18, 0,
12510 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12511 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12512 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12513 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12514 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12517 /* unsolicited event for HP jack sensing */
12518 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12521 if ((res >> 26) == ALC880_HP_EVENT)
12522 alc269_speaker_automute(codec);
12524 if ((res >> 26) == ALC880_MIC_EVENT)
12525 alc269_eeepc_dmic_automute(codec);
12528 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12530 alc269_speaker_automute(codec);
12531 alc269_eeepc_dmic_automute(codec);
12534 /* unsolicited event for HP jack sensing */
12535 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12538 if ((res >> 26) == ALC880_HP_EVENT)
12539 alc269_speaker_automute(codec);
12541 if ((res >> 26) == ALC880_MIC_EVENT)
12542 alc269_eeepc_amic_automute(codec);
12545 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12547 alc269_speaker_automute(codec);
12548 alc269_eeepc_amic_automute(codec);
12552 * generic initialization of ADC, input mixers and output mixers
12554 static struct hda_verb alc269_init_verbs[] = {
12556 * Unmute ADC0 and set the default input to mic-in
12558 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12560 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12561 * analog-loopback mixer widget
12562 * Note: PASD motherboards uses the Line In 2 as the input for
12563 * front panel mic (mic 2)
12565 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12566 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12568 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12569 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12570 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12573 * Set up output mixers (0x0c - 0x0e)
12575 /* set vol=0 to output mixers */
12576 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12577 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12579 /* set up input amps for analog loopback */
12580 /* Amp Indices: DAC = 0, mixer = 1 */
12581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12585 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12590 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12591 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12592 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12593 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12594 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12597 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12600 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12602 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12604 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12605 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12607 /* FIXME: use matrix-type input source selection */
12608 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12609 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12612 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12613 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12616 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12617 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12621 /* add playback controls from the parsed DAC table */
12622 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12623 const struct auto_pin_cfg *cfg)
12628 spec->multiout.num_dacs = 1; /* only use one dac */
12629 spec->multiout.dac_nids = spec->private_dac_nids;
12630 spec->multiout.dac_nids[0] = 2;
12632 nid = cfg->line_out_pins[0];
12634 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12635 "Front Playback Volume",
12636 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12639 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12640 "Front Playback Switch",
12641 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12646 nid = cfg->speaker_pins[0];
12648 if (!cfg->line_out_pins[0]) {
12649 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12650 "Speaker Playback Volume",
12651 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12657 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12658 "Speaker Playback Switch",
12659 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12664 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12665 "Speaker Playback Switch",
12666 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12672 nid = cfg->hp_pins[0];
12674 /* spec->multiout.hp_nid = 2; */
12675 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12676 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12677 "Headphone Playback Volume",
12678 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12684 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12685 "Headphone Playback Switch",
12686 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12691 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12692 "Headphone Playback Switch",
12693 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12702 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12703 const struct auto_pin_cfg *cfg)
12707 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12710 /* digital-mic input pin is excluded in alc880_auto_create..()
12711 * because it's under 0x18
12713 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12714 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12715 struct hda_input_mux *imux = &spec->private_imux[0];
12716 imux->items[imux->num_items].label = "Int Mic";
12717 imux->items[imux->num_items].index = 0x05;
12723 #ifdef CONFIG_SND_HDA_POWER_SAVE
12724 #define alc269_loopbacks alc880_loopbacks
12727 /* pcm configuration: identiacal with ALC880 */
12728 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12729 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12730 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12731 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12733 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12737 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12738 /* NID is set in alc_build_pcms */
12740 .open = alc880_playback_pcm_open,
12741 .prepare = alc880_playback_pcm_prepare,
12742 .cleanup = alc880_playback_pcm_cleanup
12746 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12750 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12751 /* NID is set in alc_build_pcms */
12755 * BIOS auto configuration
12757 static int alc269_parse_auto_config(struct hda_codec *codec)
12759 struct alc_spec *spec = codec->spec;
12761 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12763 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12768 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12771 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12775 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12777 if (spec->autocfg.dig_outs)
12778 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12780 if (spec->kctls.list)
12781 add_mixer(spec, spec->kctls.list);
12783 add_verb(spec, alc269_init_verbs);
12784 spec->num_mux_defs = 1;
12785 spec->input_mux = &spec->private_imux[0];
12786 /* set default input source */
12787 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12788 0, AC_VERB_SET_CONNECT_SEL,
12789 spec->input_mux->items[0].index);
12791 err = alc_auto_add_mic_boost(codec);
12795 if (!spec->cap_mixer && !spec->no_analog)
12796 set_capture_mixer(spec);
12801 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12802 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12803 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12806 /* init callback for auto-configuration model -- overriding the default init */
12807 static void alc269_auto_init(struct hda_codec *codec)
12809 struct alc_spec *spec = codec->spec;
12810 alc269_auto_init_multi_out(codec);
12811 alc269_auto_init_hp_out(codec);
12812 alc269_auto_init_analog_input(codec);
12813 if (spec->unsol_event)
12814 alc_inithook(codec);
12818 * configuration and preset
12820 static const char *alc269_models[ALC269_MODEL_LAST] = {
12821 [ALC269_BASIC] = "basic",
12822 [ALC269_QUANTA_FL1] = "quanta",
12823 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12824 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12825 [ALC269_FUJITSU] = "fujitsu",
12826 [ALC269_LIFEBOOK] = "lifebook"
12829 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12830 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12831 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12832 ALC269_ASUS_EEEPC_P703),
12833 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12834 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12835 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12836 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12837 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12838 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12839 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12840 ALC269_ASUS_EEEPC_P901),
12841 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12842 ALC269_ASUS_EEEPC_P901),
12843 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12844 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12845 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12849 static struct alc_config_preset alc269_presets[] = {
12851 .mixers = { alc269_base_mixer },
12852 .init_verbs = { alc269_init_verbs },
12853 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12854 .dac_nids = alc269_dac_nids,
12856 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12857 .channel_mode = alc269_modes,
12858 .input_mux = &alc269_capture_source,
12860 [ALC269_QUANTA_FL1] = {
12861 .mixers = { alc269_quanta_fl1_mixer },
12862 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12863 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12864 .dac_nids = alc269_dac_nids,
12866 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12867 .channel_mode = alc269_modes,
12868 .input_mux = &alc269_capture_source,
12869 .unsol_event = alc269_quanta_fl1_unsol_event,
12870 .init_hook = alc269_quanta_fl1_init_hook,
12872 [ALC269_ASUS_EEEPC_P703] = {
12873 .mixers = { alc269_eeepc_mixer },
12874 .cap_mixer = alc269_epc_capture_mixer,
12875 .init_verbs = { alc269_init_verbs,
12876 alc269_eeepc_amic_init_verbs },
12877 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12878 .dac_nids = alc269_dac_nids,
12880 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12881 .channel_mode = alc269_modes,
12882 .input_mux = &alc269_eeepc_amic_capture_source,
12883 .unsol_event = alc269_eeepc_amic_unsol_event,
12884 .init_hook = alc269_eeepc_amic_inithook,
12886 [ALC269_ASUS_EEEPC_P901] = {
12887 .mixers = { alc269_eeepc_mixer },
12888 .cap_mixer = alc269_epc_capture_mixer,
12889 .init_verbs = { alc269_init_verbs,
12890 alc269_eeepc_dmic_init_verbs },
12891 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12892 .dac_nids = alc269_dac_nids,
12894 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12895 .channel_mode = alc269_modes,
12896 .input_mux = &alc269_eeepc_dmic_capture_source,
12897 .unsol_event = alc269_eeepc_dmic_unsol_event,
12898 .init_hook = alc269_eeepc_dmic_inithook,
12900 [ALC269_FUJITSU] = {
12901 .mixers = { alc269_fujitsu_mixer },
12902 .cap_mixer = alc269_epc_capture_mixer,
12903 .init_verbs = { alc269_init_verbs,
12904 alc269_eeepc_dmic_init_verbs },
12905 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12906 .dac_nids = alc269_dac_nids,
12908 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12909 .channel_mode = alc269_modes,
12910 .input_mux = &alc269_eeepc_dmic_capture_source,
12911 .unsol_event = alc269_eeepc_dmic_unsol_event,
12912 .init_hook = alc269_eeepc_dmic_inithook,
12914 [ALC269_LIFEBOOK] = {
12915 .mixers = { alc269_lifebook_mixer },
12916 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12917 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12918 .dac_nids = alc269_dac_nids,
12920 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12921 .channel_mode = alc269_modes,
12922 .input_mux = &alc269_capture_source,
12923 .unsol_event = alc269_lifebook_unsol_event,
12924 .init_hook = alc269_lifebook_init_hook,
12928 static int patch_alc269(struct hda_codec *codec)
12930 struct alc_spec *spec;
12934 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12938 codec->spec = spec;
12940 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12942 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12946 if (board_config < 0) {
12947 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12948 "trying auto-probe from BIOS...\n");
12949 board_config = ALC269_AUTO;
12952 if (board_config == ALC269_AUTO) {
12953 /* automatic parse from the BIOS config */
12954 err = alc269_parse_auto_config(codec);
12960 "hda_codec: Cannot set up configuration "
12961 "from BIOS. Using base mode...\n");
12962 board_config = ALC269_BASIC;
12966 err = snd_hda_attach_beep_device(codec, 0x1);
12972 if (board_config != ALC269_AUTO)
12973 setup_preset(spec, &alc269_presets[board_config]);
12975 spec->stream_name_analog = "ALC269 Analog";
12976 if (codec->subsystem_id == 0x17aa3bf8) {
12977 /* Due to a hardware problem on Lenovo Ideadpad, we need to
12978 * fix the sample rate of analog I/O to 44.1kHz
12980 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
12981 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
12983 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12984 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12986 spec->stream_name_digital = "ALC269 Digital";
12987 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12988 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12990 spec->adc_nids = alc269_adc_nids;
12991 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12992 spec->capsrc_nids = alc269_capsrc_nids;
12993 if (!spec->cap_mixer)
12994 set_capture_mixer(spec);
12995 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
12997 codec->patch_ops = alc_patch_ops;
12998 if (board_config == ALC269_AUTO)
12999 spec->init_hook = alc269_auto_init;
13000 #ifdef CONFIG_SND_HDA_POWER_SAVE
13001 if (!spec->loopback.amplist)
13002 spec->loopback.amplist = alc269_loopbacks;
13004 codec->proc_widget_hook = print_realtek_coef;
13010 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13014 * set the path ways for 2 channel output
13015 * need to set the codec line out and mic 1 pin widgets to inputs
13017 static struct hda_verb alc861_threestack_ch2_init[] = {
13018 /* set pin widget 1Ah (line in) for input */
13019 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13020 /* set pin widget 18h (mic1/2) for input, for mic also enable
13023 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13025 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13027 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13028 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13034 * need to set the codec line out and mic 1 pin widgets to outputs
13036 static struct hda_verb alc861_threestack_ch6_init[] = {
13037 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13038 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13039 /* set pin widget 18h (mic1) for output (CLFE)*/
13040 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13042 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13043 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13045 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13047 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13048 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13053 static struct hda_channel_mode alc861_threestack_modes[2] = {
13054 { 2, alc861_threestack_ch2_init },
13055 { 6, alc861_threestack_ch6_init },
13057 /* Set mic1 as input and unmute the mixer */
13058 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13059 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13060 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13063 /* Set mic1 as output and mute mixer */
13064 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13065 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13066 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13070 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13071 { 2, alc861_uniwill_m31_ch2_init },
13072 { 4, alc861_uniwill_m31_ch4_init },
13075 /* Set mic1 and line-in as input and unmute the mixer */
13076 static struct hda_verb alc861_asus_ch2_init[] = {
13077 /* set pin widget 1Ah (line in) for input */
13078 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13079 /* set pin widget 18h (mic1/2) for input, for mic also enable
13082 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13084 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13086 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13087 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13091 /* Set mic1 nad line-in as output and mute mixer */
13092 static struct hda_verb alc861_asus_ch6_init[] = {
13093 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13094 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13095 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13096 /* set pin widget 18h (mic1) for output (CLFE)*/
13097 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13098 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13099 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13100 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13102 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13104 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13105 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13110 static struct hda_channel_mode alc861_asus_modes[2] = {
13111 { 2, alc861_asus_ch2_init },
13112 { 6, alc861_asus_ch6_init },
13117 static struct snd_kcontrol_new alc861_base_mixer[] = {
13118 /* output mixer control */
13119 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13120 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13121 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13122 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13123 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13125 /*Input mixer control */
13126 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13127 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13128 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13129 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13130 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13131 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13132 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13133 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13140 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13141 /* output mixer control */
13142 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13143 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13144 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13145 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13146 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13148 /* Input mixer control */
13149 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13150 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13151 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13152 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13153 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13154 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13156 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13157 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13158 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13161 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13162 .name = "Channel Mode",
13163 .info = alc_ch_mode_info,
13164 .get = alc_ch_mode_get,
13165 .put = alc_ch_mode_put,
13166 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13171 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13172 /* output mixer control */
13173 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13175 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13180 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13181 /* output mixer control */
13182 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13183 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13184 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13185 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13186 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13188 /* Input mixer control */
13189 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13190 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13191 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13192 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13193 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13194 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13196 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13202 .name = "Channel Mode",
13203 .info = alc_ch_mode_info,
13204 .get = alc_ch_mode_get,
13205 .put = alc_ch_mode_put,
13206 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13211 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13212 /* output mixer control */
13213 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13214 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13215 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13216 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13217 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13219 /* Input mixer control */
13220 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13221 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13222 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13223 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13224 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13225 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13226 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13227 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13229 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13232 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13233 .name = "Channel Mode",
13234 .info = alc_ch_mode_info,
13235 .get = alc_ch_mode_get,
13236 .put = alc_ch_mode_put,
13237 .private_value = ARRAY_SIZE(alc861_asus_modes),
13242 /* additional mixer */
13243 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13244 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13245 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13250 * generic initialization of ADC, input mixers and output mixers
13252 static struct hda_verb alc861_base_init_verbs[] = {
13254 * Unmute ADC0 and set the default input to mic-in
13256 /* port-A for surround (rear panel) */
13257 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13258 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13259 /* port-B for mic-in (rear panel) with vref */
13260 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13261 /* port-C for line-in (rear panel) */
13262 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13263 /* port-D for Front */
13264 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13265 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13266 /* port-E for HP out (front panel) */
13267 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13268 /* route front PCM to HP */
13269 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13270 /* port-F for mic-in (front panel) with vref */
13271 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13272 /* port-G for CLFE (rear panel) */
13273 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13274 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13275 /* port-H for side (rear panel) */
13276 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13277 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13279 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13280 /* route front mic to ADC1*/
13281 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13282 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13284 /* Unmute DAC0~3 & spdif out*/
13285 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13286 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13287 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13288 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13289 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13291 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13292 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13293 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13294 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13295 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13297 /* Unmute Stereo Mixer 15 */
13298 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13299 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13300 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13301 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13304 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13305 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13306 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13308 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13309 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13311 /* hp used DAC 3 (Front) */
13312 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13318 static struct hda_verb alc861_threestack_init_verbs[] = {
13320 * Unmute ADC0 and set the default input to mic-in
13322 /* port-A for surround (rear panel) */
13323 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13324 /* port-B for mic-in (rear panel) with vref */
13325 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13326 /* port-C for line-in (rear panel) */
13327 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13328 /* port-D for Front */
13329 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13330 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13331 /* port-E for HP out (front panel) */
13332 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13333 /* route front PCM to HP */
13334 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13335 /* port-F for mic-in (front panel) with vref */
13336 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13337 /* port-G for CLFE (rear panel) */
13338 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13339 /* port-H for side (rear panel) */
13340 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13342 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13343 /* route front mic to ADC1*/
13344 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13345 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13346 /* Unmute DAC0~3 & spdif out*/
13347 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13348 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13349 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13350 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13351 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13353 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13354 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13355 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13356 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13357 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13359 /* Unmute Stereo Mixer 15 */
13360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13362 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13363 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13365 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13367 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13368 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13369 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13370 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13371 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13372 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13373 /* hp used DAC 3 (Front) */
13374 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13375 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13379 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13381 * Unmute ADC0 and set the default input to mic-in
13383 /* port-A for surround (rear panel) */
13384 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13385 /* port-B for mic-in (rear panel) with vref */
13386 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13387 /* port-C for line-in (rear panel) */
13388 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13389 /* port-D for Front */
13390 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13391 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13392 /* port-E for HP out (front panel) */
13393 /* this has to be set to VREF80 */
13394 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13395 /* route front PCM to HP */
13396 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13397 /* port-F for mic-in (front panel) with vref */
13398 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13399 /* port-G for CLFE (rear panel) */
13400 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13401 /* port-H for side (rear panel) */
13402 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13404 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13405 /* route front mic to ADC1*/
13406 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13407 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13408 /* Unmute DAC0~3 & spdif out*/
13409 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13410 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13411 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13412 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13415 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13416 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13417 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13418 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13419 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13421 /* Unmute Stereo Mixer 15 */
13422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13425 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13427 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13428 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13429 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13430 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13434 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13435 /* hp used DAC 3 (Front) */
13436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13441 static struct hda_verb alc861_asus_init_verbs[] = {
13443 * Unmute ADC0 and set the default input to mic-in
13445 /* port-A for surround (rear panel)
13446 * according to codec#0 this is the HP jack
13448 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13449 /* route front PCM to HP */
13450 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13451 /* port-B for mic-in (rear panel) with vref */
13452 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13453 /* port-C for line-in (rear panel) */
13454 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13455 /* port-D for Front */
13456 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13457 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13458 /* port-E for HP out (front panel) */
13459 /* this has to be set to VREF80 */
13460 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13461 /* route front PCM to HP */
13462 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13463 /* port-F for mic-in (front panel) with vref */
13464 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13465 /* port-G for CLFE (rear panel) */
13466 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13467 /* port-H for side (rear panel) */
13468 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13470 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13471 /* route front mic to ADC1*/
13472 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13473 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13474 /* Unmute DAC0~3 & spdif out*/
13475 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13476 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13477 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13478 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13480 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13481 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13482 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13483 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13484 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13486 /* Unmute Stereo Mixer 15 */
13487 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13488 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13490 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13492 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13493 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13494 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13495 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13496 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13497 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13498 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13499 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13500 /* hp used DAC 3 (Front) */
13501 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13506 /* additional init verbs for ASUS laptops */
13507 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13508 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13509 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13514 * generic initialization of ADC, input mixers and output mixers
13516 static struct hda_verb alc861_auto_init_verbs[] = {
13518 * Unmute ADC0 and set the default input to mic-in
13520 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13521 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13523 /* Unmute DAC0~3 & spdif out*/
13524 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13525 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13526 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13527 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13530 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13531 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13532 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13533 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13534 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13536 /* Unmute Stereo Mixer 15 */
13537 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13543 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13544 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13545 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13546 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13548 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13549 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13551 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13552 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13556 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13557 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13558 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13560 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13565 static struct hda_verb alc861_toshiba_init_verbs[] = {
13566 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13571 /* toggle speaker-output according to the hp-jack state */
13572 static void alc861_toshiba_automute(struct hda_codec *codec)
13574 unsigned int present;
13576 present = snd_hda_codec_read(codec, 0x0f, 0,
13577 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13578 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13579 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13580 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13581 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13584 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13587 if ((res >> 26) == ALC880_HP_EVENT)
13588 alc861_toshiba_automute(codec);
13591 /* pcm configuration: identiacal with ALC880 */
13592 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13593 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13594 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13595 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13598 #define ALC861_DIGOUT_NID 0x07
13600 static struct hda_channel_mode alc861_8ch_modes[1] = {
13604 static hda_nid_t alc861_dac_nids[4] = {
13605 /* front, surround, clfe, side */
13606 0x03, 0x06, 0x05, 0x04
13609 static hda_nid_t alc660_dac_nids[3] = {
13610 /* front, clfe, surround */
13614 static hda_nid_t alc861_adc_nids[1] = {
13619 static struct hda_input_mux alc861_capture_source = {
13623 { "Front Mic", 0x3 },
13630 /* fill in the dac_nids table from the parsed pin configuration */
13631 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13632 const struct auto_pin_cfg *cfg)
13637 spec->multiout.dac_nids = spec->private_dac_nids;
13638 for (i = 0; i < cfg->line_outs; i++) {
13639 nid = cfg->line_out_pins[i];
13641 if (i >= ARRAY_SIZE(alc861_dac_nids))
13643 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13646 spec->multiout.num_dacs = cfg->line_outs;
13650 /* add playback controls from the parsed DAC table */
13651 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13652 const struct auto_pin_cfg *cfg)
13655 static const char *chname[4] = {
13656 "Front", "Surround", NULL /*CLFE*/, "Side"
13661 for (i = 0; i < cfg->line_outs; i++) {
13662 nid = spec->multiout.dac_nids[i];
13667 err = add_control(spec, ALC_CTL_BIND_MUTE,
13668 "Center Playback Switch",
13669 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13673 err = add_control(spec, ALC_CTL_BIND_MUTE,
13674 "LFE Playback Switch",
13675 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13680 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13682 if (nid == alc861_dac_nids[idx])
13684 sprintf(name, "%s Playback Switch", chname[idx]);
13685 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13686 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13695 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13703 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13705 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13706 "Headphone Playback Switch",
13707 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13710 spec->multiout.hp_nid = nid;
13715 /* create playback/capture controls for input pins */
13716 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13717 const struct auto_pin_cfg *cfg)
13719 struct hda_input_mux *imux = &spec->private_imux[0];
13720 int i, err, idx, idx1;
13722 for (i = 0; i < AUTO_PIN_LAST; i++) {
13723 switch (cfg->input_pins[i]) {
13726 idx = 2; /* Line In */
13730 idx = 2; /* Line In */
13734 idx = 1; /* Mic In */
13738 idx = 1; /* Mic In */
13748 err = new_analog_input(spec, cfg->input_pins[i],
13749 auto_pin_cfg_labels[i], idx, 0x15);
13753 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13754 imux->items[imux->num_items].index = idx1;
13760 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13762 int pin_type, int dac_idx)
13764 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13766 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13770 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13772 struct alc_spec *spec = codec->spec;
13775 for (i = 0; i < spec->autocfg.line_outs; i++) {
13776 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13777 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13779 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13780 spec->multiout.dac_nids[i]);
13784 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13786 struct alc_spec *spec = codec->spec;
13789 pin = spec->autocfg.hp_pins[0];
13790 if (pin) /* connect to front */
13791 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13792 spec->multiout.dac_nids[0]);
13793 pin = spec->autocfg.speaker_pins[0];
13795 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13798 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13800 struct alc_spec *spec = codec->spec;
13803 for (i = 0; i < AUTO_PIN_LAST; i++) {
13804 hda_nid_t nid = spec->autocfg.input_pins[i];
13805 if (nid >= 0x0c && nid <= 0x11)
13806 alc_set_input_pin(codec, nid, i);
13810 /* parse the BIOS configuration and set up the alc_spec */
13811 /* return 1 if successful, 0 if the proper config is not found,
13812 * or a negative error code
13814 static int alc861_parse_auto_config(struct hda_codec *codec)
13816 struct alc_spec *spec = codec->spec;
13818 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13820 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13824 if (!spec->autocfg.line_outs)
13825 return 0; /* can't find valid BIOS pin config */
13827 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13830 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13833 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13836 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13840 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13842 if (spec->autocfg.dig_outs)
13843 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13845 if (spec->kctls.list)
13846 add_mixer(spec, spec->kctls.list);
13848 add_verb(spec, alc861_auto_init_verbs);
13850 spec->num_mux_defs = 1;
13851 spec->input_mux = &spec->private_imux[0];
13853 spec->adc_nids = alc861_adc_nids;
13854 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13855 set_capture_mixer(spec);
13857 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
13862 /* additional initialization for auto-configuration model */
13863 static void alc861_auto_init(struct hda_codec *codec)
13865 struct alc_spec *spec = codec->spec;
13866 alc861_auto_init_multi_out(codec);
13867 alc861_auto_init_hp_out(codec);
13868 alc861_auto_init_analog_input(codec);
13869 if (spec->unsol_event)
13870 alc_inithook(codec);
13873 #ifdef CONFIG_SND_HDA_POWER_SAVE
13874 static struct hda_amp_list alc861_loopbacks[] = {
13875 { 0x15, HDA_INPUT, 0 },
13876 { 0x15, HDA_INPUT, 1 },
13877 { 0x15, HDA_INPUT, 2 },
13878 { 0x15, HDA_INPUT, 3 },
13885 * configuration and preset
13887 static const char *alc861_models[ALC861_MODEL_LAST] = {
13888 [ALC861_3ST] = "3stack",
13889 [ALC660_3ST] = "3stack-660",
13890 [ALC861_3ST_DIG] = "3stack-dig",
13891 [ALC861_6ST_DIG] = "6stack-dig",
13892 [ALC861_UNIWILL_M31] = "uniwill-m31",
13893 [ALC861_TOSHIBA] = "toshiba",
13894 [ALC861_ASUS] = "asus",
13895 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13896 [ALC861_AUTO] = "auto",
13899 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13900 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13901 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13902 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13903 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13904 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13905 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13906 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13907 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13908 * Any other models that need this preset?
13910 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13911 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13912 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13913 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13914 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13915 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13916 /* FIXME: the below seems conflict */
13917 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13918 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13919 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13923 static struct alc_config_preset alc861_presets[] = {
13925 .mixers = { alc861_3ST_mixer },
13926 .init_verbs = { alc861_threestack_init_verbs },
13927 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13928 .dac_nids = alc861_dac_nids,
13929 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13930 .channel_mode = alc861_threestack_modes,
13932 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13933 .adc_nids = alc861_adc_nids,
13934 .input_mux = &alc861_capture_source,
13936 [ALC861_3ST_DIG] = {
13937 .mixers = { alc861_base_mixer },
13938 .init_verbs = { alc861_threestack_init_verbs },
13939 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13940 .dac_nids = alc861_dac_nids,
13941 .dig_out_nid = ALC861_DIGOUT_NID,
13942 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13943 .channel_mode = alc861_threestack_modes,
13945 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13946 .adc_nids = alc861_adc_nids,
13947 .input_mux = &alc861_capture_source,
13949 [ALC861_6ST_DIG] = {
13950 .mixers = { alc861_base_mixer },
13951 .init_verbs = { alc861_base_init_verbs },
13952 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13953 .dac_nids = alc861_dac_nids,
13954 .dig_out_nid = ALC861_DIGOUT_NID,
13955 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13956 .channel_mode = alc861_8ch_modes,
13957 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13958 .adc_nids = alc861_adc_nids,
13959 .input_mux = &alc861_capture_source,
13962 .mixers = { alc861_3ST_mixer },
13963 .init_verbs = { alc861_threestack_init_verbs },
13964 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13965 .dac_nids = alc660_dac_nids,
13966 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13967 .channel_mode = alc861_threestack_modes,
13969 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13970 .adc_nids = alc861_adc_nids,
13971 .input_mux = &alc861_capture_source,
13973 [ALC861_UNIWILL_M31] = {
13974 .mixers = { alc861_uniwill_m31_mixer },
13975 .init_verbs = { alc861_uniwill_m31_init_verbs },
13976 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13977 .dac_nids = alc861_dac_nids,
13978 .dig_out_nid = ALC861_DIGOUT_NID,
13979 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13980 .channel_mode = alc861_uniwill_m31_modes,
13982 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13983 .adc_nids = alc861_adc_nids,
13984 .input_mux = &alc861_capture_source,
13986 [ALC861_TOSHIBA] = {
13987 .mixers = { alc861_toshiba_mixer },
13988 .init_verbs = { alc861_base_init_verbs,
13989 alc861_toshiba_init_verbs },
13990 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13991 .dac_nids = alc861_dac_nids,
13992 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13993 .channel_mode = alc883_3ST_2ch_modes,
13994 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13995 .adc_nids = alc861_adc_nids,
13996 .input_mux = &alc861_capture_source,
13997 .unsol_event = alc861_toshiba_unsol_event,
13998 .init_hook = alc861_toshiba_automute,
14001 .mixers = { alc861_asus_mixer },
14002 .init_verbs = { alc861_asus_init_verbs },
14003 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14004 .dac_nids = alc861_dac_nids,
14005 .dig_out_nid = ALC861_DIGOUT_NID,
14006 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14007 .channel_mode = alc861_asus_modes,
14010 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14011 .adc_nids = alc861_adc_nids,
14012 .input_mux = &alc861_capture_source,
14014 [ALC861_ASUS_LAPTOP] = {
14015 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14016 .init_verbs = { alc861_asus_init_verbs,
14017 alc861_asus_laptop_init_verbs },
14018 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14019 .dac_nids = alc861_dac_nids,
14020 .dig_out_nid = ALC861_DIGOUT_NID,
14021 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14022 .channel_mode = alc883_3ST_2ch_modes,
14024 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14025 .adc_nids = alc861_adc_nids,
14026 .input_mux = &alc861_capture_source,
14031 static int patch_alc861(struct hda_codec *codec)
14033 struct alc_spec *spec;
14037 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14041 codec->spec = spec;
14043 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14047 if (board_config < 0) {
14048 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14049 "trying auto-probe from BIOS...\n");
14050 board_config = ALC861_AUTO;
14053 if (board_config == ALC861_AUTO) {
14054 /* automatic parse from the BIOS config */
14055 err = alc861_parse_auto_config(codec);
14061 "hda_codec: Cannot set up configuration "
14062 "from BIOS. Using base mode...\n");
14063 board_config = ALC861_3ST_DIG;
14067 err = snd_hda_attach_beep_device(codec, 0x23);
14073 if (board_config != ALC861_AUTO)
14074 setup_preset(spec, &alc861_presets[board_config]);
14076 spec->stream_name_analog = "ALC861 Analog";
14077 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14078 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14080 spec->stream_name_digital = "ALC861 Digital";
14081 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14082 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14084 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14086 spec->vmaster_nid = 0x03;
14088 codec->patch_ops = alc_patch_ops;
14089 if (board_config == ALC861_AUTO)
14090 spec->init_hook = alc861_auto_init;
14091 #ifdef CONFIG_SND_HDA_POWER_SAVE
14092 if (!spec->loopback.amplist)
14093 spec->loopback.amplist = alc861_loopbacks;
14095 codec->proc_widget_hook = print_realtek_coef;
14101 * ALC861-VD support
14105 * In addition, an independent DAC
14107 #define ALC861VD_DIGOUT_NID 0x06
14109 static hda_nid_t alc861vd_dac_nids[4] = {
14110 /* front, surr, clfe, side surr */
14111 0x02, 0x03, 0x04, 0x05
14114 /* dac_nids for ALC660vd are in a different order - according to
14115 * Realtek's driver.
14116 * This should probably tesult in a different mixer for 6stack models
14117 * of ALC660vd codecs, but for now there is only 3stack mixer
14118 * - and it is the same as in 861vd.
14119 * adc_nids in ALC660vd are (is) the same as in 861vd
14121 static hda_nid_t alc660vd_dac_nids[3] = {
14122 /* front, rear, clfe, rear_surr */
14126 static hda_nid_t alc861vd_adc_nids[1] = {
14131 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14134 /* FIXME: should be a matrix-type input source selection */
14135 static struct hda_input_mux alc861vd_capture_source = {
14139 { "Front Mic", 0x1 },
14145 static struct hda_input_mux alc861vd_dallas_capture_source = {
14148 { "Ext Mic", 0x0 },
14149 { "Int Mic", 0x1 },
14153 static struct hda_input_mux alc861vd_hp_capture_source = {
14156 { "Front Mic", 0x0 },
14157 { "ATAPI Mic", 0x1 },
14164 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14171 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14172 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14173 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14174 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14175 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14182 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14183 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14184 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14185 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14186 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14190 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14191 { 6, alc861vd_6stack_ch6_init },
14192 { 8, alc861vd_6stack_ch8_init },
14195 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14198 .name = "Channel Mode",
14199 .info = alc_ch_mode_info,
14200 .get = alc_ch_mode_get,
14201 .put = alc_ch_mode_put,
14206 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14207 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14209 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14210 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14213 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14214 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14216 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14218 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14220 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14221 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14223 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14224 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14226 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14228 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14229 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14232 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14233 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14234 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14236 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14237 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14239 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14240 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14245 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14246 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14247 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14249 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14251 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14252 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14253 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14255 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14256 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14257 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14259 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14260 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14268 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14269 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14270 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14271 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14275 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14279 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14280 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14281 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14283 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14284 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14289 /* Pin assignment: Speaker=0x14, HP = 0x15,
14290 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14292 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14293 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14294 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14295 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14296 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14297 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14298 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14299 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14300 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14301 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14302 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14306 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14307 * Front Mic=0x18, ATAPI Mic = 0x19,
14309 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14310 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14311 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14312 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14313 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14314 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14315 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14316 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14317 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14323 * generic initialization of ADC, input mixers and output mixers
14325 static struct hda_verb alc861vd_volume_init_verbs[] = {
14327 * Unmute ADC0 and set the default input to mic-in
14329 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14330 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14332 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14333 * the analog-loopback mixer widget
14335 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14342 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14344 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14345 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14349 * Set up output mixers (0x02 - 0x05)
14351 /* set vol=0 to output mixers */
14352 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14353 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14354 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14355 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14357 /* set up input amps for analog loopback */
14358 /* Amp Indices: DAC = 0, mixer = 1 */
14359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14362 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14363 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14364 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14365 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14366 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14372 * 3-stack pin configuration:
14373 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14375 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14377 * Set pin mode and muting
14379 /* set front pin widgets 0x14 for output */
14380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14381 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14382 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14384 /* Mic (rear) pin: input vref at 80% */
14385 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14386 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14387 /* Front Mic pin: input vref at 80% */
14388 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14389 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14390 /* Line In pin: input */
14391 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14392 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14393 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14394 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14395 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14396 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14397 /* CD pin widget for input */
14398 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14404 * 6-stack pin configuration:
14406 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14408 * Set pin mode and muting
14410 /* set front pin widgets 0x14 for output */
14411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14412 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14413 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14415 /* Rear Pin: output 1 (0x0d) */
14416 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14417 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14418 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14419 /* CLFE Pin: output 2 (0x0e) */
14420 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14421 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14422 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14423 /* Side Pin: output 3 (0x0f) */
14424 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14425 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14426 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14428 /* Mic (rear) pin: input vref at 80% */
14429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14431 /* Front Mic pin: input vref at 80% */
14432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14434 /* Line In pin: input */
14435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14437 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14438 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14439 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14440 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14441 /* CD pin widget for input */
14442 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14447 static struct hda_verb alc861vd_eapd_verbs[] = {
14448 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14452 static struct hda_verb alc660vd_eapd_verbs[] = {
14453 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14454 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14458 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14461 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14462 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14463 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14467 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14469 unsigned int present;
14470 unsigned char bits;
14472 present = snd_hda_codec_read(codec, 0x18, 0,
14473 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14474 bits = present ? HDA_AMP_MUTE : 0;
14475 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14476 HDA_AMP_MUTE, bits);
14479 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14481 struct alc_spec *spec = codec->spec;
14483 spec->autocfg.hp_pins[0] = 0x1b;
14484 spec->autocfg.speaker_pins[0] = 0x14;
14485 alc_automute_amp(codec);
14486 alc861vd_lenovo_mic_automute(codec);
14489 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14492 switch (res >> 26) {
14493 case ALC880_MIC_EVENT:
14494 alc861vd_lenovo_mic_automute(codec);
14497 alc_automute_amp_unsol_event(codec, res);
14502 static struct hda_verb alc861vd_dallas_verbs[] = {
14503 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14504 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14505 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14506 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14512 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14517 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14518 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14519 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14521 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14522 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14523 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14524 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14526 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14528 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14530 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14531 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14532 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14533 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14541 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14542 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14547 /* toggle speaker-output according to the hp-jack state */
14548 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14550 struct alc_spec *spec = codec->spec;
14552 spec->autocfg.hp_pins[0] = 0x15;
14553 spec->autocfg.speaker_pins[0] = 0x14;
14554 alc_automute_amp(codec);
14557 #ifdef CONFIG_SND_HDA_POWER_SAVE
14558 #define alc861vd_loopbacks alc880_loopbacks
14561 /* pcm configuration: identiacal with ALC880 */
14562 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14563 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14564 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14565 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14568 * configuration and preset
14570 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14571 [ALC660VD_3ST] = "3stack-660",
14572 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14573 [ALC660VD_ASUS_V1S] = "asus-v1s",
14574 [ALC861VD_3ST] = "3stack",
14575 [ALC861VD_3ST_DIG] = "3stack-digout",
14576 [ALC861VD_6ST_DIG] = "6stack-digout",
14577 [ALC861VD_LENOVO] = "lenovo",
14578 [ALC861VD_DALLAS] = "dallas",
14579 [ALC861VD_HP] = "hp",
14580 [ALC861VD_AUTO] = "auto",
14583 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14584 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14585 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14586 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14587 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14588 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14589 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14590 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14591 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14592 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14593 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14594 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14595 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14596 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14597 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14598 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14602 static struct alc_config_preset alc861vd_presets[] = {
14604 .mixers = { alc861vd_3st_mixer },
14605 .init_verbs = { alc861vd_volume_init_verbs,
14606 alc861vd_3stack_init_verbs },
14607 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14608 .dac_nids = alc660vd_dac_nids,
14609 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14610 .channel_mode = alc861vd_3stack_2ch_modes,
14611 .input_mux = &alc861vd_capture_source,
14613 [ALC660VD_3ST_DIG] = {
14614 .mixers = { alc861vd_3st_mixer },
14615 .init_verbs = { alc861vd_volume_init_verbs,
14616 alc861vd_3stack_init_verbs },
14617 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14618 .dac_nids = alc660vd_dac_nids,
14619 .dig_out_nid = ALC861VD_DIGOUT_NID,
14620 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14621 .channel_mode = alc861vd_3stack_2ch_modes,
14622 .input_mux = &alc861vd_capture_source,
14625 .mixers = { alc861vd_3st_mixer },
14626 .init_verbs = { alc861vd_volume_init_verbs,
14627 alc861vd_3stack_init_verbs },
14628 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14629 .dac_nids = alc861vd_dac_nids,
14630 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14631 .channel_mode = alc861vd_3stack_2ch_modes,
14632 .input_mux = &alc861vd_capture_source,
14634 [ALC861VD_3ST_DIG] = {
14635 .mixers = { alc861vd_3st_mixer },
14636 .init_verbs = { alc861vd_volume_init_verbs,
14637 alc861vd_3stack_init_verbs },
14638 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14639 .dac_nids = alc861vd_dac_nids,
14640 .dig_out_nid = ALC861VD_DIGOUT_NID,
14641 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14642 .channel_mode = alc861vd_3stack_2ch_modes,
14643 .input_mux = &alc861vd_capture_source,
14645 [ALC861VD_6ST_DIG] = {
14646 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14647 .init_verbs = { alc861vd_volume_init_verbs,
14648 alc861vd_6stack_init_verbs },
14649 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14650 .dac_nids = alc861vd_dac_nids,
14651 .dig_out_nid = ALC861VD_DIGOUT_NID,
14652 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14653 .channel_mode = alc861vd_6stack_modes,
14654 .input_mux = &alc861vd_capture_source,
14656 [ALC861VD_LENOVO] = {
14657 .mixers = { alc861vd_lenovo_mixer },
14658 .init_verbs = { alc861vd_volume_init_verbs,
14659 alc861vd_3stack_init_verbs,
14660 alc861vd_eapd_verbs,
14661 alc861vd_lenovo_unsol_verbs },
14662 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14663 .dac_nids = alc660vd_dac_nids,
14664 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14665 .channel_mode = alc861vd_3stack_2ch_modes,
14666 .input_mux = &alc861vd_capture_source,
14667 .unsol_event = alc861vd_lenovo_unsol_event,
14668 .init_hook = alc861vd_lenovo_init_hook,
14670 [ALC861VD_DALLAS] = {
14671 .mixers = { alc861vd_dallas_mixer },
14672 .init_verbs = { alc861vd_dallas_verbs },
14673 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14674 .dac_nids = alc861vd_dac_nids,
14675 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14676 .channel_mode = alc861vd_3stack_2ch_modes,
14677 .input_mux = &alc861vd_dallas_capture_source,
14678 .unsol_event = alc_automute_amp_unsol_event,
14679 .init_hook = alc861vd_dallas_init_hook,
14682 .mixers = { alc861vd_hp_mixer },
14683 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14684 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14685 .dac_nids = alc861vd_dac_nids,
14686 .dig_out_nid = ALC861VD_DIGOUT_NID,
14687 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14688 .channel_mode = alc861vd_3stack_2ch_modes,
14689 .input_mux = &alc861vd_hp_capture_source,
14690 .unsol_event = alc_automute_amp_unsol_event,
14691 .init_hook = alc861vd_dallas_init_hook,
14693 [ALC660VD_ASUS_V1S] = {
14694 .mixers = { alc861vd_lenovo_mixer },
14695 .init_verbs = { alc861vd_volume_init_verbs,
14696 alc861vd_3stack_init_verbs,
14697 alc861vd_eapd_verbs,
14698 alc861vd_lenovo_unsol_verbs },
14699 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14700 .dac_nids = alc660vd_dac_nids,
14701 .dig_out_nid = ALC861VD_DIGOUT_NID,
14702 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14703 .channel_mode = alc861vd_3stack_2ch_modes,
14704 .input_mux = &alc861vd_capture_source,
14705 .unsol_event = alc861vd_lenovo_unsol_event,
14706 .init_hook = alc861vd_lenovo_init_hook,
14711 * BIOS auto configuration
14713 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14714 hda_nid_t nid, int pin_type, int dac_idx)
14716 alc_set_pin_output(codec, nid, pin_type);
14719 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14721 struct alc_spec *spec = codec->spec;
14724 for (i = 0; i <= HDA_SIDE; i++) {
14725 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14726 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14728 alc861vd_auto_set_output_and_unmute(codec, nid,
14734 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14736 struct alc_spec *spec = codec->spec;
14739 pin = spec->autocfg.hp_pins[0];
14740 if (pin) /* connect to front and use dac 0 */
14741 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14742 pin = spec->autocfg.speaker_pins[0];
14744 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14747 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14748 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14750 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14752 struct alc_spec *spec = codec->spec;
14755 for (i = 0; i < AUTO_PIN_LAST; i++) {
14756 hda_nid_t nid = spec->autocfg.input_pins[i];
14757 if (alc861vd_is_input_pin(nid)) {
14758 alc_set_input_pin(codec, nid, i);
14759 if (nid != ALC861VD_PIN_CD_NID &&
14760 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14761 snd_hda_codec_write(codec, nid, 0,
14762 AC_VERB_SET_AMP_GAIN_MUTE,
14768 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14770 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14771 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14773 /* add playback controls from the parsed DAC table */
14774 /* Based on ALC880 version. But ALC861VD has separate,
14775 * different NIDs for mute/unmute switch and volume control */
14776 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14777 const struct auto_pin_cfg *cfg)
14780 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14781 hda_nid_t nid_v, nid_s;
14784 for (i = 0; i < cfg->line_outs; i++) {
14785 if (!spec->multiout.dac_nids[i])
14787 nid_v = alc861vd_idx_to_mixer_vol(
14789 spec->multiout.dac_nids[i]));
14790 nid_s = alc861vd_idx_to_mixer_switch(
14792 spec->multiout.dac_nids[i]));
14796 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14797 "Center Playback Volume",
14798 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14802 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14803 "LFE Playback Volume",
14804 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14808 err = add_control(spec, ALC_CTL_BIND_MUTE,
14809 "Center Playback Switch",
14810 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14814 err = add_control(spec, ALC_CTL_BIND_MUTE,
14815 "LFE Playback Switch",
14816 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14821 sprintf(name, "%s Playback Volume", chname[i]);
14822 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14823 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14827 sprintf(name, "%s Playback Switch", chname[i]);
14828 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14829 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14838 /* add playback controls for speaker and HP outputs */
14839 /* Based on ALC880 version. But ALC861VD has separate,
14840 * different NIDs for mute/unmute switch and volume control */
14841 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14842 hda_nid_t pin, const char *pfx)
14844 hda_nid_t nid_v, nid_s;
14851 if (alc880_is_fixed_pin(pin)) {
14852 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14853 /* specify the DAC as the extra output */
14854 if (!spec->multiout.hp_nid)
14855 spec->multiout.hp_nid = nid_v;
14857 spec->multiout.extra_out_nid[0] = nid_v;
14858 /* control HP volume/switch on the output mixer amp */
14859 nid_v = alc861vd_idx_to_mixer_vol(
14860 alc880_fixed_pin_idx(pin));
14861 nid_s = alc861vd_idx_to_mixer_switch(
14862 alc880_fixed_pin_idx(pin));
14864 sprintf(name, "%s Playback Volume", pfx);
14865 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14866 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14869 sprintf(name, "%s Playback Switch", pfx);
14870 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14871 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14874 } else if (alc880_is_multi_pin(pin)) {
14875 /* set manual connection */
14876 /* we have only a switch on HP-out PIN */
14877 sprintf(name, "%s Playback Switch", pfx);
14878 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14879 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14886 /* parse the BIOS configuration and set up the alc_spec
14887 * return 1 if successful, 0 if the proper config is not found,
14888 * or a negative error code
14889 * Based on ALC880 version - had to change it to override
14890 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14891 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14893 struct alc_spec *spec = codec->spec;
14895 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14897 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14901 if (!spec->autocfg.line_outs)
14902 return 0; /* can't find valid BIOS pin config */
14904 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14907 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14910 err = alc861vd_auto_create_extra_out(spec,
14911 spec->autocfg.speaker_pins[0],
14915 err = alc861vd_auto_create_extra_out(spec,
14916 spec->autocfg.hp_pins[0],
14920 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14924 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14926 if (spec->autocfg.dig_outs)
14927 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14929 if (spec->kctls.list)
14930 add_mixer(spec, spec->kctls.list);
14932 add_verb(spec, alc861vd_volume_init_verbs);
14934 spec->num_mux_defs = 1;
14935 spec->input_mux = &spec->private_imux[0];
14937 err = alc_auto_add_mic_boost(codec);
14941 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
14946 /* additional initialization for auto-configuration model */
14947 static void alc861vd_auto_init(struct hda_codec *codec)
14949 struct alc_spec *spec = codec->spec;
14950 alc861vd_auto_init_multi_out(codec);
14951 alc861vd_auto_init_hp_out(codec);
14952 alc861vd_auto_init_analog_input(codec);
14953 alc861vd_auto_init_input_src(codec);
14954 if (spec->unsol_event)
14955 alc_inithook(codec);
14958 static int patch_alc861vd(struct hda_codec *codec)
14960 struct alc_spec *spec;
14961 int err, board_config;
14963 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14967 codec->spec = spec;
14969 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14973 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14974 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14975 "ALC861VD, trying auto-probe from BIOS...\n");
14976 board_config = ALC861VD_AUTO;
14979 if (board_config == ALC861VD_AUTO) {
14980 /* automatic parse from the BIOS config */
14981 err = alc861vd_parse_auto_config(codec);
14987 "hda_codec: Cannot set up configuration "
14988 "from BIOS. Using base mode...\n");
14989 board_config = ALC861VD_3ST;
14993 err = snd_hda_attach_beep_device(codec, 0x23);
14999 if (board_config != ALC861VD_AUTO)
15000 setup_preset(spec, &alc861vd_presets[board_config]);
15002 if (codec->vendor_id == 0x10ec0660) {
15003 spec->stream_name_analog = "ALC660-VD Analog";
15004 spec->stream_name_digital = "ALC660-VD Digital";
15005 /* always turn on EAPD */
15006 add_verb(spec, alc660vd_eapd_verbs);
15008 spec->stream_name_analog = "ALC861VD Analog";
15009 spec->stream_name_digital = "ALC861VD Digital";
15012 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15013 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15015 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15016 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15018 spec->adc_nids = alc861vd_adc_nids;
15019 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15020 spec->capsrc_nids = alc861vd_capsrc_nids;
15021 spec->capture_style = CAPT_MIX;
15023 set_capture_mixer(spec);
15024 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15026 spec->vmaster_nid = 0x02;
15028 codec->patch_ops = alc_patch_ops;
15030 if (board_config == ALC861VD_AUTO)
15031 spec->init_hook = alc861vd_auto_init;
15032 #ifdef CONFIG_SND_HDA_POWER_SAVE
15033 if (!spec->loopback.amplist)
15034 spec->loopback.amplist = alc861vd_loopbacks;
15036 codec->proc_widget_hook = print_realtek_coef;
15044 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15045 * configuration. Each pin widget can choose any input DACs and a mixer.
15046 * Each ADC is connected from a mixer of all inputs. This makes possible
15047 * 6-channel independent captures.
15049 * In addition, an independent DAC for the multi-playback (not used in this
15052 #define ALC662_DIGOUT_NID 0x06
15053 #define ALC662_DIGIN_NID 0x0a
15055 static hda_nid_t alc662_dac_nids[4] = {
15056 /* front, rear, clfe, rear_surr */
15060 static hda_nid_t alc272_dac_nids[2] = {
15064 static hda_nid_t alc662_adc_nids[1] = {
15069 static hda_nid_t alc272_adc_nids[1] = {
15074 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15075 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15079 /* FIXME: should be a matrix-type input source selection */
15080 static struct hda_input_mux alc662_capture_source = {
15084 { "Front Mic", 0x1 },
15090 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15098 static struct hda_input_mux alc662_eeepc_capture_source = {
15106 static struct hda_input_mux alc663_capture_source = {
15110 { "Front Mic", 0x1 },
15115 static struct hda_input_mux alc663_m51va_capture_source = {
15118 { "Ext-Mic", 0x0 },
15126 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15133 static struct hda_verb alc662_3ST_ch2_init[] = {
15134 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15135 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15136 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15137 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15144 static struct hda_verb alc662_3ST_ch6_init[] = {
15145 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15146 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15147 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15150 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15154 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15155 { 2, alc662_3ST_ch2_init },
15156 { 6, alc662_3ST_ch6_init },
15162 static struct hda_verb alc662_sixstack_ch6_init[] = {
15163 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15164 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15165 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15172 static struct hda_verb alc662_sixstack_ch8_init[] = {
15173 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15174 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15175 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15179 static struct hda_channel_mode alc662_5stack_modes[2] = {
15180 { 2, alc662_sixstack_ch6_init },
15181 { 6, alc662_sixstack_ch8_init },
15184 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15185 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15188 static struct snd_kcontrol_new alc662_base_mixer[] = {
15189 /* output mixer control */
15190 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15191 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15192 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15193 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15194 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15195 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15196 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15197 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15200 /*Input mixer control */
15201 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15202 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15203 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15204 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15205 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15206 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15207 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15208 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15212 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15213 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15214 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15221 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15222 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15223 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15227 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15228 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15229 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15230 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15231 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15232 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15233 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15234 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15235 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15236 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15237 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15238 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15239 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15240 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15241 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15242 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15243 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15244 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15248 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15249 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15250 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15251 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15252 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15253 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15254 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15255 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15261 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15262 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15263 ALC262_HIPPO_MASTER_SWITCH,
15265 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15266 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15267 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15269 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15270 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15271 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15275 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15276 ALC262_HIPPO_MASTER_SWITCH,
15277 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15278 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15279 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15280 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15281 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15289 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15290 .ops = &snd_hda_bind_vol,
15292 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15293 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15298 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15299 .ops = &snd_hda_bind_sw,
15301 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15302 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15307 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15308 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15309 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15310 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15311 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15315 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15316 .ops = &snd_hda_bind_sw,
15318 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15319 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15320 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15325 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15326 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15327 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15328 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15329 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15330 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15331 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15336 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15337 .ops = &snd_hda_bind_sw,
15339 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15340 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15341 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15346 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15347 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15348 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15351 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15352 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15356 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15357 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15358 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15359 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15362 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15363 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15367 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15368 .ops = &snd_hda_bind_vol,
15370 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15371 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15376 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15377 .ops = &snd_hda_bind_sw,
15379 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15380 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15385 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15386 HDA_BIND_VOL("Master Playback Volume",
15387 &alc663_asus_two_bind_master_vol),
15388 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15389 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15391 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15392 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15396 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15397 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15398 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15399 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15400 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15401 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15402 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15406 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15407 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15408 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15409 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15410 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15413 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15414 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15415 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15416 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15420 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15421 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15422 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15423 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15427 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15428 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15434 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15437 .name = "Channel Mode",
15438 .info = alc_ch_mode_info,
15439 .get = alc_ch_mode_get,
15440 .put = alc_ch_mode_put,
15445 static struct hda_verb alc662_init_verbs[] = {
15446 /* ADC: mute amp left and right */
15447 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15448 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15449 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15462 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15464 /* Front Pin: output 0 (0x0c) */
15465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15466 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15468 /* Rear Pin: output 1 (0x0d) */
15469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15472 /* CLFE Pin: output 2 (0x0e) */
15473 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15474 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15476 /* Mic (rear) pin: input vref at 80% */
15477 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15478 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15479 /* Front Mic pin: input vref at 80% */
15480 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15481 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15482 /* Line In pin: input */
15483 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15484 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15485 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15486 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15487 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15488 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15489 /* CD pin widget for input */
15490 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15492 /* FIXME: use matrix-type input source selection */
15493 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15496 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15498 /* always trun on EAPD */
15499 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15500 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15505 static struct hda_verb alc662_sue_init_verbs[] = {
15506 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15507 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15511 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15512 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15513 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15517 /* Set Unsolicited Event*/
15518 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15519 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15520 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15525 * generic initialization of ADC, input mixers and output mixers
15527 static struct hda_verb alc662_auto_init_verbs[] = {
15529 * Unmute ADC and set the default input to mic-in
15531 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15534 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15536 * Note: PASD motherboards uses the Line In 2 as the input for front
15537 * panel mic (mic 2)
15539 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15547 * Set up output mixers (0x0c - 0x0f)
15549 /* set vol=0 to output mixers */
15550 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15551 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15552 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15554 /* set up input amps for analog loopback */
15555 /* Amp Indices: DAC = 0, mixer = 1 */
15556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15564 /* FIXME: use matrix-type input source selection */
15565 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15568 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15572 /* additional verbs for ALC663 */
15573 static struct hda_verb alc663_auto_init_verbs[] = {
15574 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15575 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15579 static struct hda_verb alc663_m51va_init_verbs[] = {
15580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15582 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15583 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15584 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15587 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15588 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15592 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15593 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15594 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15595 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15596 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15598 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15599 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15603 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15604 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15605 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15606 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15607 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15610 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15611 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15615 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15617 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15618 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15621 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15622 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15626 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15627 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15628 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15629 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15630 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15631 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15633 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15634 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15635 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15636 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15637 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15638 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15642 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15643 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15644 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15645 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15646 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15647 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15649 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15650 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15651 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15652 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15653 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15654 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15658 static struct hda_verb alc663_g71v_init_verbs[] = {
15659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15660 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15661 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15663 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15664 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15665 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15667 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15668 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15669 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15673 static struct hda_verb alc663_g50v_init_verbs[] = {
15674 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15675 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15676 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15678 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15679 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15683 static struct hda_verb alc662_ecs_init_verbs[] = {
15684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15685 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15686 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15687 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15691 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15692 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15693 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15694 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15695 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15696 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15697 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15698 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15700 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15701 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15702 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15706 static struct hda_verb alc272_dell_init_verbs[] = {
15707 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15708 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15709 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15710 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15711 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15712 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15713 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15714 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15715 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15716 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15717 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15721 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15722 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15723 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15727 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15728 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15729 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15733 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15735 unsigned int present;
15736 unsigned char bits;
15738 present = snd_hda_codec_read(codec, 0x14, 0,
15739 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15740 bits = present ? HDA_AMP_MUTE : 0;
15741 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15742 HDA_AMP_MUTE, bits);
15745 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15747 unsigned int present;
15748 unsigned char bits;
15750 present = snd_hda_codec_read(codec, 0x1b, 0,
15751 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15752 bits = present ? HDA_AMP_MUTE : 0;
15753 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15754 HDA_AMP_MUTE, bits);
15755 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15756 HDA_AMP_MUTE, bits);
15759 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15762 if ((res >> 26) == ALC880_HP_EVENT)
15763 alc662_lenovo_101e_all_automute(codec);
15764 if ((res >> 26) == ALC880_FRONT_EVENT)
15765 alc662_lenovo_101e_ispeaker_automute(codec);
15768 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15770 unsigned int present;
15772 present = snd_hda_codec_read(codec, 0x18, 0,
15773 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15774 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15775 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15776 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15777 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15778 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15779 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15780 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15781 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15784 /* unsolicited event for HP jack sensing */
15785 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15788 if ((res >> 26) == ALC880_MIC_EVENT)
15789 alc662_eeepc_mic_automute(codec);
15791 alc262_hippo_unsol_event(codec, res);
15794 static void alc662_eeepc_inithook(struct hda_codec *codec)
15796 alc262_hippo1_init_hook(codec);
15797 alc662_eeepc_mic_automute(codec);
15800 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15802 struct alc_spec *spec = codec->spec;
15804 spec->autocfg.hp_pins[0] = 0x14;
15805 spec->autocfg.speaker_pins[0] = 0x1b;
15806 alc262_hippo_master_update(codec);
15809 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15811 unsigned int present;
15812 unsigned char bits;
15814 present = snd_hda_codec_read(codec, 0x21, 0,
15815 AC_VERB_GET_PIN_SENSE, 0)
15816 & AC_PINSENSE_PRESENCE;
15817 bits = present ? HDA_AMP_MUTE : 0;
15818 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15819 AMP_IN_MUTE(0), bits);
15820 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15821 AMP_IN_MUTE(0), bits);
15824 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15826 unsigned int present;
15827 unsigned char bits;
15829 present = snd_hda_codec_read(codec, 0x21, 0,
15830 AC_VERB_GET_PIN_SENSE, 0)
15831 & AC_PINSENSE_PRESENCE;
15832 bits = present ? HDA_AMP_MUTE : 0;
15833 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15834 AMP_IN_MUTE(0), bits);
15835 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15836 AMP_IN_MUTE(0), bits);
15837 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15838 AMP_IN_MUTE(0), bits);
15839 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15840 AMP_IN_MUTE(0), bits);
15843 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15845 unsigned int present;
15846 unsigned char bits;
15848 present = snd_hda_codec_read(codec, 0x15, 0,
15849 AC_VERB_GET_PIN_SENSE, 0)
15850 & AC_PINSENSE_PRESENCE;
15851 bits = present ? HDA_AMP_MUTE : 0;
15852 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15853 AMP_IN_MUTE(0), bits);
15854 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15855 AMP_IN_MUTE(0), bits);
15856 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15857 AMP_IN_MUTE(0), bits);
15858 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15859 AMP_IN_MUTE(0), bits);
15862 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15864 unsigned int present;
15865 unsigned char bits;
15867 present = snd_hda_codec_read(codec, 0x1b, 0,
15868 AC_VERB_GET_PIN_SENSE, 0)
15869 & AC_PINSENSE_PRESENCE;
15870 bits = present ? 0 : PIN_OUT;
15871 snd_hda_codec_write(codec, 0x14, 0,
15872 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15875 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15877 unsigned int present1, present2;
15879 present1 = snd_hda_codec_read(codec, 0x21, 0,
15880 AC_VERB_GET_PIN_SENSE, 0)
15881 & AC_PINSENSE_PRESENCE;
15882 present2 = snd_hda_codec_read(codec, 0x15, 0,
15883 AC_VERB_GET_PIN_SENSE, 0)
15884 & AC_PINSENSE_PRESENCE;
15886 if (present1 || present2) {
15887 snd_hda_codec_write_cache(codec, 0x14, 0,
15888 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15890 snd_hda_codec_write_cache(codec, 0x14, 0,
15891 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15895 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15897 unsigned int present1, present2;
15899 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15900 AC_VERB_GET_PIN_SENSE, 0)
15901 & AC_PINSENSE_PRESENCE;
15902 present2 = snd_hda_codec_read(codec, 0x15, 0,
15903 AC_VERB_GET_PIN_SENSE, 0)
15904 & AC_PINSENSE_PRESENCE;
15906 if (present1 || present2) {
15907 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15908 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15909 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15910 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15912 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15913 AMP_IN_MUTE(0), 0);
15914 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15915 AMP_IN_MUTE(0), 0);
15919 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15921 unsigned int present;
15923 present = snd_hda_codec_read(codec, 0x18, 0,
15924 AC_VERB_GET_PIN_SENSE, 0)
15925 & AC_PINSENSE_PRESENCE;
15926 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15927 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15928 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15929 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15930 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15931 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15932 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15933 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15936 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15939 switch (res >> 26) {
15940 case ALC880_HP_EVENT:
15941 alc663_m51va_speaker_automute(codec);
15943 case ALC880_MIC_EVENT:
15944 alc663_m51va_mic_automute(codec);
15949 static void alc663_m51va_inithook(struct hda_codec *codec)
15951 alc663_m51va_speaker_automute(codec);
15952 alc663_m51va_mic_automute(codec);
15955 /* ***************** Mode1 ******************************/
15956 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15959 switch (res >> 26) {
15960 case ALC880_HP_EVENT:
15961 alc663_m51va_speaker_automute(codec);
15963 case ALC880_MIC_EVENT:
15964 alc662_eeepc_mic_automute(codec);
15969 static void alc663_mode1_inithook(struct hda_codec *codec)
15971 alc663_m51va_speaker_automute(codec);
15972 alc662_eeepc_mic_automute(codec);
15974 /* ***************** Mode2 ******************************/
15975 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15978 switch (res >> 26) {
15979 case ALC880_HP_EVENT:
15980 alc662_f5z_speaker_automute(codec);
15982 case ALC880_MIC_EVENT:
15983 alc662_eeepc_mic_automute(codec);
15988 static void alc662_mode2_inithook(struct hda_codec *codec)
15990 alc662_f5z_speaker_automute(codec);
15991 alc662_eeepc_mic_automute(codec);
15993 /* ***************** Mode3 ******************************/
15994 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15997 switch (res >> 26) {
15998 case ALC880_HP_EVENT:
15999 alc663_two_hp_m1_speaker_automute(codec);
16001 case ALC880_MIC_EVENT:
16002 alc662_eeepc_mic_automute(codec);
16007 static void alc663_mode3_inithook(struct hda_codec *codec)
16009 alc663_two_hp_m1_speaker_automute(codec);
16010 alc662_eeepc_mic_automute(codec);
16012 /* ***************** Mode4 ******************************/
16013 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16016 switch (res >> 26) {
16017 case ALC880_HP_EVENT:
16018 alc663_21jd_two_speaker_automute(codec);
16020 case ALC880_MIC_EVENT:
16021 alc662_eeepc_mic_automute(codec);
16026 static void alc663_mode4_inithook(struct hda_codec *codec)
16028 alc663_21jd_two_speaker_automute(codec);
16029 alc662_eeepc_mic_automute(codec);
16031 /* ***************** Mode5 ******************************/
16032 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16035 switch (res >> 26) {
16036 case ALC880_HP_EVENT:
16037 alc663_15jd_two_speaker_automute(codec);
16039 case ALC880_MIC_EVENT:
16040 alc662_eeepc_mic_automute(codec);
16045 static void alc663_mode5_inithook(struct hda_codec *codec)
16047 alc663_15jd_two_speaker_automute(codec);
16048 alc662_eeepc_mic_automute(codec);
16050 /* ***************** Mode6 ******************************/
16051 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16054 switch (res >> 26) {
16055 case ALC880_HP_EVENT:
16056 alc663_two_hp_m2_speaker_automute(codec);
16058 case ALC880_MIC_EVENT:
16059 alc662_eeepc_mic_automute(codec);
16064 static void alc663_mode6_inithook(struct hda_codec *codec)
16066 alc663_two_hp_m2_speaker_automute(codec);
16067 alc662_eeepc_mic_automute(codec);
16070 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16072 unsigned int present;
16073 unsigned char bits;
16075 present = snd_hda_codec_read(codec, 0x21, 0,
16076 AC_VERB_GET_PIN_SENSE, 0)
16077 & AC_PINSENSE_PRESENCE;
16078 bits = present ? HDA_AMP_MUTE : 0;
16079 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16080 HDA_AMP_MUTE, bits);
16081 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16082 HDA_AMP_MUTE, bits);
16085 static void alc663_g71v_front_automute(struct hda_codec *codec)
16087 unsigned int present;
16088 unsigned char bits;
16090 present = snd_hda_codec_read(codec, 0x15, 0,
16091 AC_VERB_GET_PIN_SENSE, 0)
16092 & AC_PINSENSE_PRESENCE;
16093 bits = present ? HDA_AMP_MUTE : 0;
16094 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16095 HDA_AMP_MUTE, bits);
16098 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16101 switch (res >> 26) {
16102 case ALC880_HP_EVENT:
16103 alc663_g71v_hp_automute(codec);
16105 case ALC880_FRONT_EVENT:
16106 alc663_g71v_front_automute(codec);
16108 case ALC880_MIC_EVENT:
16109 alc662_eeepc_mic_automute(codec);
16114 static void alc663_g71v_inithook(struct hda_codec *codec)
16116 alc663_g71v_front_automute(codec);
16117 alc663_g71v_hp_automute(codec);
16118 alc662_eeepc_mic_automute(codec);
16121 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16124 switch (res >> 26) {
16125 case ALC880_HP_EVENT:
16126 alc663_m51va_speaker_automute(codec);
16128 case ALC880_MIC_EVENT:
16129 alc662_eeepc_mic_automute(codec);
16134 static void alc663_g50v_inithook(struct hda_codec *codec)
16136 alc663_m51va_speaker_automute(codec);
16137 alc662_eeepc_mic_automute(codec);
16140 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16141 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16142 ALC262_HIPPO_MASTER_SWITCH,
16144 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16145 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16146 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16148 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16149 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16150 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16154 #ifdef CONFIG_SND_HDA_POWER_SAVE
16155 #define alc662_loopbacks alc880_loopbacks
16159 /* pcm configuration: identiacal with ALC880 */
16160 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16161 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16162 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16163 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16166 * configuration and preset
16168 static const char *alc662_models[ALC662_MODEL_LAST] = {
16169 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16170 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16171 [ALC662_3ST_6ch] = "3stack-6ch",
16172 [ALC662_5ST_DIG] = "6stack-dig",
16173 [ALC662_LENOVO_101E] = "lenovo-101e",
16174 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16175 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16176 [ALC662_ECS] = "ecs",
16177 [ALC663_ASUS_M51VA] = "m51va",
16178 [ALC663_ASUS_G71V] = "g71v",
16179 [ALC663_ASUS_H13] = "h13",
16180 [ALC663_ASUS_G50V] = "g50v",
16181 [ALC663_ASUS_MODE1] = "asus-mode1",
16182 [ALC662_ASUS_MODE2] = "asus-mode2",
16183 [ALC663_ASUS_MODE3] = "asus-mode3",
16184 [ALC663_ASUS_MODE4] = "asus-mode4",
16185 [ALC663_ASUS_MODE5] = "asus-mode5",
16186 [ALC663_ASUS_MODE6] = "asus-mode6",
16187 [ALC272_DELL] = "dell",
16188 [ALC272_DELL_ZM1] = "dell-zm1",
16189 [ALC662_AUTO] = "auto",
16192 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16193 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16194 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16195 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16196 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16197 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16198 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16199 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16200 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16201 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16202 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16203 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16204 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16205 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16206 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16207 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16208 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16209 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16210 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16211 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16212 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16213 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16214 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16215 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16216 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16217 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16218 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16219 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16220 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16221 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16222 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16223 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16224 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16225 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16226 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16227 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16228 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16229 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16230 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16231 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16232 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16233 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16234 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16235 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16236 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16237 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16238 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16239 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16240 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16241 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16242 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16243 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16244 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16245 ALC662_3ST_6ch_DIG),
16246 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16247 ALC662_3ST_6ch_DIG),
16248 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16249 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16250 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16251 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16252 ALC662_3ST_6ch_DIG),
16253 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16258 static struct alc_config_preset alc662_presets[] = {
16259 [ALC662_3ST_2ch_DIG] = {
16260 .mixers = { alc662_3ST_2ch_mixer },
16261 .init_verbs = { alc662_init_verbs },
16262 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16263 .dac_nids = alc662_dac_nids,
16264 .dig_out_nid = ALC662_DIGOUT_NID,
16265 .dig_in_nid = ALC662_DIGIN_NID,
16266 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16267 .channel_mode = alc662_3ST_2ch_modes,
16268 .input_mux = &alc662_capture_source,
16270 [ALC662_3ST_6ch_DIG] = {
16271 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16272 .init_verbs = { alc662_init_verbs },
16273 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16274 .dac_nids = alc662_dac_nids,
16275 .dig_out_nid = ALC662_DIGOUT_NID,
16276 .dig_in_nid = ALC662_DIGIN_NID,
16277 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16278 .channel_mode = alc662_3ST_6ch_modes,
16280 .input_mux = &alc662_capture_source,
16282 [ALC662_3ST_6ch] = {
16283 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16284 .init_verbs = { alc662_init_verbs },
16285 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16286 .dac_nids = alc662_dac_nids,
16287 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16288 .channel_mode = alc662_3ST_6ch_modes,
16290 .input_mux = &alc662_capture_source,
16292 [ALC662_5ST_DIG] = {
16293 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16294 .init_verbs = { alc662_init_verbs },
16295 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16296 .dac_nids = alc662_dac_nids,
16297 .dig_out_nid = ALC662_DIGOUT_NID,
16298 .dig_in_nid = ALC662_DIGIN_NID,
16299 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16300 .channel_mode = alc662_5stack_modes,
16301 .input_mux = &alc662_capture_source,
16303 [ALC662_LENOVO_101E] = {
16304 .mixers = { alc662_lenovo_101e_mixer },
16305 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16306 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16307 .dac_nids = alc662_dac_nids,
16308 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16309 .channel_mode = alc662_3ST_2ch_modes,
16310 .input_mux = &alc662_lenovo_101e_capture_source,
16311 .unsol_event = alc662_lenovo_101e_unsol_event,
16312 .init_hook = alc662_lenovo_101e_all_automute,
16314 [ALC662_ASUS_EEEPC_P701] = {
16315 .mixers = { alc662_eeepc_p701_mixer },
16316 .init_verbs = { alc662_init_verbs,
16317 alc662_eeepc_sue_init_verbs },
16318 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16319 .dac_nids = alc662_dac_nids,
16320 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16321 .channel_mode = alc662_3ST_2ch_modes,
16322 .input_mux = &alc662_eeepc_capture_source,
16323 .unsol_event = alc662_eeepc_unsol_event,
16324 .init_hook = alc662_eeepc_inithook,
16326 [ALC662_ASUS_EEEPC_EP20] = {
16327 .mixers = { alc662_eeepc_ep20_mixer,
16328 alc662_chmode_mixer },
16329 .init_verbs = { alc662_init_verbs,
16330 alc662_eeepc_ep20_sue_init_verbs },
16331 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16332 .dac_nids = alc662_dac_nids,
16333 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16334 .channel_mode = alc662_3ST_6ch_modes,
16335 .input_mux = &alc662_lenovo_101e_capture_source,
16336 .unsol_event = alc662_eeepc_unsol_event,
16337 .init_hook = alc662_eeepc_ep20_inithook,
16340 .mixers = { alc662_ecs_mixer },
16341 .init_verbs = { alc662_init_verbs,
16342 alc662_ecs_init_verbs },
16343 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16344 .dac_nids = alc662_dac_nids,
16345 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16346 .channel_mode = alc662_3ST_2ch_modes,
16347 .input_mux = &alc662_eeepc_capture_source,
16348 .unsol_event = alc662_eeepc_unsol_event,
16349 .init_hook = alc662_eeepc_inithook,
16351 [ALC663_ASUS_M51VA] = {
16352 .mixers = { alc663_m51va_mixer },
16353 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16354 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16355 .dac_nids = alc662_dac_nids,
16356 .dig_out_nid = ALC662_DIGOUT_NID,
16357 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16358 .channel_mode = alc662_3ST_2ch_modes,
16359 .input_mux = &alc663_m51va_capture_source,
16360 .unsol_event = alc663_m51va_unsol_event,
16361 .init_hook = alc663_m51va_inithook,
16363 [ALC663_ASUS_G71V] = {
16364 .mixers = { alc663_g71v_mixer },
16365 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16366 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16367 .dac_nids = alc662_dac_nids,
16368 .dig_out_nid = ALC662_DIGOUT_NID,
16369 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16370 .channel_mode = alc662_3ST_2ch_modes,
16371 .input_mux = &alc662_eeepc_capture_source,
16372 .unsol_event = alc663_g71v_unsol_event,
16373 .init_hook = alc663_g71v_inithook,
16375 [ALC663_ASUS_H13] = {
16376 .mixers = { alc663_m51va_mixer },
16377 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16378 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16379 .dac_nids = alc662_dac_nids,
16380 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16381 .channel_mode = alc662_3ST_2ch_modes,
16382 .input_mux = &alc663_m51va_capture_source,
16383 .unsol_event = alc663_m51va_unsol_event,
16384 .init_hook = alc663_m51va_inithook,
16386 [ALC663_ASUS_G50V] = {
16387 .mixers = { alc663_g50v_mixer },
16388 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16389 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16390 .dac_nids = alc662_dac_nids,
16391 .dig_out_nid = ALC662_DIGOUT_NID,
16392 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16393 .channel_mode = alc662_3ST_6ch_modes,
16394 .input_mux = &alc663_capture_source,
16395 .unsol_event = alc663_g50v_unsol_event,
16396 .init_hook = alc663_g50v_inithook,
16398 [ALC663_ASUS_MODE1] = {
16399 .mixers = { alc663_m51va_mixer },
16400 .cap_mixer = alc662_auto_capture_mixer,
16401 .init_verbs = { alc662_init_verbs,
16402 alc663_21jd_amic_init_verbs },
16403 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16405 .dac_nids = alc662_dac_nids,
16406 .dig_out_nid = ALC662_DIGOUT_NID,
16407 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16408 .channel_mode = alc662_3ST_2ch_modes,
16409 .input_mux = &alc662_eeepc_capture_source,
16410 .unsol_event = alc663_mode1_unsol_event,
16411 .init_hook = alc663_mode1_inithook,
16413 [ALC662_ASUS_MODE2] = {
16414 .mixers = { alc662_1bjd_mixer },
16415 .cap_mixer = alc662_auto_capture_mixer,
16416 .init_verbs = { alc662_init_verbs,
16417 alc662_1bjd_amic_init_verbs },
16418 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16419 .dac_nids = alc662_dac_nids,
16420 .dig_out_nid = ALC662_DIGOUT_NID,
16421 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16422 .channel_mode = alc662_3ST_2ch_modes,
16423 .input_mux = &alc662_eeepc_capture_source,
16424 .unsol_event = alc662_mode2_unsol_event,
16425 .init_hook = alc662_mode2_inithook,
16427 [ALC663_ASUS_MODE3] = {
16428 .mixers = { alc663_two_hp_m1_mixer },
16429 .cap_mixer = alc662_auto_capture_mixer,
16430 .init_verbs = { alc662_init_verbs,
16431 alc663_two_hp_amic_m1_init_verbs },
16432 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16434 .dac_nids = alc662_dac_nids,
16435 .dig_out_nid = ALC662_DIGOUT_NID,
16436 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16437 .channel_mode = alc662_3ST_2ch_modes,
16438 .input_mux = &alc662_eeepc_capture_source,
16439 .unsol_event = alc663_mode3_unsol_event,
16440 .init_hook = alc663_mode3_inithook,
16442 [ALC663_ASUS_MODE4] = {
16443 .mixers = { alc663_asus_21jd_clfe_mixer },
16444 .cap_mixer = alc662_auto_capture_mixer,
16445 .init_verbs = { alc662_init_verbs,
16446 alc663_21jd_amic_init_verbs},
16447 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16449 .dac_nids = alc662_dac_nids,
16450 .dig_out_nid = ALC662_DIGOUT_NID,
16451 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16452 .channel_mode = alc662_3ST_2ch_modes,
16453 .input_mux = &alc662_eeepc_capture_source,
16454 .unsol_event = alc663_mode4_unsol_event,
16455 .init_hook = alc663_mode4_inithook,
16457 [ALC663_ASUS_MODE5] = {
16458 .mixers = { alc663_asus_15jd_clfe_mixer },
16459 .cap_mixer = alc662_auto_capture_mixer,
16460 .init_verbs = { alc662_init_verbs,
16461 alc663_15jd_amic_init_verbs },
16462 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16464 .dac_nids = alc662_dac_nids,
16465 .dig_out_nid = ALC662_DIGOUT_NID,
16466 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16467 .channel_mode = alc662_3ST_2ch_modes,
16468 .input_mux = &alc662_eeepc_capture_source,
16469 .unsol_event = alc663_mode5_unsol_event,
16470 .init_hook = alc663_mode5_inithook,
16472 [ALC663_ASUS_MODE6] = {
16473 .mixers = { alc663_two_hp_m2_mixer },
16474 .cap_mixer = alc662_auto_capture_mixer,
16475 .init_verbs = { alc662_init_verbs,
16476 alc663_two_hp_amic_m2_init_verbs },
16477 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16479 .dac_nids = alc662_dac_nids,
16480 .dig_out_nid = ALC662_DIGOUT_NID,
16481 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16482 .channel_mode = alc662_3ST_2ch_modes,
16483 .input_mux = &alc662_eeepc_capture_source,
16484 .unsol_event = alc663_mode6_unsol_event,
16485 .init_hook = alc663_mode6_inithook,
16488 .mixers = { alc663_m51va_mixer },
16489 .cap_mixer = alc272_auto_capture_mixer,
16490 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16491 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16492 .dac_nids = alc662_dac_nids,
16493 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16494 .adc_nids = alc272_adc_nids,
16495 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16496 .capsrc_nids = alc272_capsrc_nids,
16497 .channel_mode = alc662_3ST_2ch_modes,
16498 .input_mux = &alc663_m51va_capture_source,
16499 .unsol_event = alc663_m51va_unsol_event,
16500 .init_hook = alc663_m51va_inithook,
16502 [ALC272_DELL_ZM1] = {
16503 .mixers = { alc663_m51va_mixer },
16504 .cap_mixer = alc662_auto_capture_mixer,
16505 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16506 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16507 .dac_nids = alc662_dac_nids,
16508 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16509 .adc_nids = alc662_adc_nids,
16510 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16511 .capsrc_nids = alc662_capsrc_nids,
16512 .channel_mode = alc662_3ST_2ch_modes,
16513 .input_mux = &alc663_m51va_capture_source,
16514 .unsol_event = alc663_m51va_unsol_event,
16515 .init_hook = alc663_m51va_inithook,
16521 * BIOS auto configuration
16524 /* add playback controls from the parsed DAC table */
16525 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16526 const struct auto_pin_cfg *cfg)
16529 static const char *chname[4] = {
16530 "Front", "Surround", NULL /*CLFE*/, "Side"
16535 for (i = 0; i < cfg->line_outs; i++) {
16536 if (!spec->multiout.dac_nids[i])
16538 nid = alc880_idx_to_dac(i);
16541 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16542 "Center Playback Volume",
16543 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16547 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16548 "LFE Playback Volume",
16549 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16553 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16554 "Center Playback Switch",
16555 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16559 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16560 "LFE Playback Switch",
16561 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16566 sprintf(name, "%s Playback Volume", chname[i]);
16567 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16568 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16572 sprintf(name, "%s Playback Switch", chname[i]);
16573 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16574 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16583 /* add playback controls for speaker and HP outputs */
16584 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16595 /* ALC663 has a mono output pin on 0x17 */
16596 sprintf(name, "%s Playback Switch", pfx);
16597 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16598 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16602 if (alc880_is_fixed_pin(pin)) {
16603 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16604 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16605 /* specify the DAC as the extra output */
16606 if (!spec->multiout.hp_nid)
16607 spec->multiout.hp_nid = nid;
16609 spec->multiout.extra_out_nid[0] = nid;
16610 /* control HP volume/switch on the output mixer amp */
16611 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16612 sprintf(name, "%s Playback Volume", pfx);
16613 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16614 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16617 sprintf(name, "%s Playback Switch", pfx);
16618 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16619 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16622 } else if (alc880_is_multi_pin(pin)) {
16623 /* set manual connection */
16624 /* we have only a switch on HP-out PIN */
16625 sprintf(name, "%s Playback Switch", pfx);
16626 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16627 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16634 /* return the index of the src widget from the connection list of the nid.
16635 * return -1 if not found
16637 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16640 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16643 conns = snd_hda_get_connections(codec, nid, conn_list,
16644 ARRAY_SIZE(conn_list));
16647 for (i = 0; i < conns; i++)
16648 if (conn_list[i] == src)
16653 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16655 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16656 return (pincap & AC_PINCAP_IN) != 0;
16659 /* create playback/capture controls for input pins */
16660 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16661 const struct auto_pin_cfg *cfg)
16663 struct alc_spec *spec = codec->spec;
16664 struct hda_input_mux *imux = &spec->private_imux[0];
16667 for (i = 0; i < AUTO_PIN_LAST; i++) {
16668 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16669 idx = alc662_input_pin_idx(codec, 0x0b,
16670 cfg->input_pins[i]);
16672 err = new_analog_input(spec, cfg->input_pins[i],
16673 auto_pin_cfg_labels[i],
16678 idx = alc662_input_pin_idx(codec, 0x22,
16679 cfg->input_pins[i]);
16681 imux->items[imux->num_items].label =
16682 auto_pin_cfg_labels[i];
16683 imux->items[imux->num_items].index = idx;
16691 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16692 hda_nid_t nid, int pin_type,
16695 alc_set_pin_output(codec, nid, pin_type);
16696 /* need the manual connection? */
16697 if (alc880_is_multi_pin(nid)) {
16698 struct alc_spec *spec = codec->spec;
16699 int idx = alc880_multi_pin_idx(nid);
16700 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16701 AC_VERB_SET_CONNECT_SEL,
16702 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16706 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16708 struct alc_spec *spec = codec->spec;
16711 for (i = 0; i <= HDA_SIDE; i++) {
16712 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16713 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16715 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16720 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16722 struct alc_spec *spec = codec->spec;
16725 pin = spec->autocfg.hp_pins[0];
16726 if (pin) /* connect to front */
16728 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16729 pin = spec->autocfg.speaker_pins[0];
16731 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16734 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16736 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16738 struct alc_spec *spec = codec->spec;
16741 for (i = 0; i < AUTO_PIN_LAST; i++) {
16742 hda_nid_t nid = spec->autocfg.input_pins[i];
16743 if (alc662_is_input_pin(codec, nid)) {
16744 alc_set_input_pin(codec, nid, i);
16745 if (nid != ALC662_PIN_CD_NID &&
16746 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16747 snd_hda_codec_write(codec, nid, 0,
16748 AC_VERB_SET_AMP_GAIN_MUTE,
16754 #define alc662_auto_init_input_src alc882_auto_init_input_src
16756 static int alc662_parse_auto_config(struct hda_codec *codec)
16758 struct alc_spec *spec = codec->spec;
16760 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16762 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16766 if (!spec->autocfg.line_outs)
16767 return 0; /* can't find valid BIOS pin config */
16769 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16772 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16775 err = alc662_auto_create_extra_out(spec,
16776 spec->autocfg.speaker_pins[0],
16780 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16784 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
16788 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16790 if (spec->autocfg.dig_outs)
16791 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16793 if (spec->kctls.list)
16794 add_mixer(spec, spec->kctls.list);
16796 spec->num_mux_defs = 1;
16797 spec->input_mux = &spec->private_imux[0];
16799 add_verb(spec, alc662_auto_init_verbs);
16800 if (codec->vendor_id == 0x10ec0663)
16801 add_verb(spec, alc663_auto_init_verbs);
16803 err = alc_auto_add_mic_boost(codec);
16807 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
16812 /* additional initialization for auto-configuration model */
16813 static void alc662_auto_init(struct hda_codec *codec)
16815 struct alc_spec *spec = codec->spec;
16816 alc662_auto_init_multi_out(codec);
16817 alc662_auto_init_hp_out(codec);
16818 alc662_auto_init_analog_input(codec);
16819 alc662_auto_init_input_src(codec);
16820 if (spec->unsol_event)
16821 alc_inithook(codec);
16824 static int patch_alc662(struct hda_codec *codec)
16826 struct alc_spec *spec;
16827 int err, board_config;
16829 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16833 codec->spec = spec;
16835 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16837 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16840 if (board_config < 0) {
16841 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16842 "trying auto-probe from BIOS...\n");
16843 board_config = ALC662_AUTO;
16846 if (board_config == ALC662_AUTO) {
16847 /* automatic parse from the BIOS config */
16848 err = alc662_parse_auto_config(codec);
16854 "hda_codec: Cannot set up configuration "
16855 "from BIOS. Using base mode...\n");
16856 board_config = ALC662_3ST_2ch_DIG;
16860 err = snd_hda_attach_beep_device(codec, 0x1);
16866 if (board_config != ALC662_AUTO)
16867 setup_preset(spec, &alc662_presets[board_config]);
16869 if (codec->vendor_id == 0x10ec0663) {
16870 spec->stream_name_analog = "ALC663 Analog";
16871 spec->stream_name_digital = "ALC663 Digital";
16872 } else if (codec->vendor_id == 0x10ec0272) {
16873 spec->stream_name_analog = "ALC272 Analog";
16874 spec->stream_name_digital = "ALC272 Digital";
16876 spec->stream_name_analog = "ALC662 Analog";
16877 spec->stream_name_digital = "ALC662 Digital";
16880 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16881 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16883 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16884 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16886 spec->adc_nids = alc662_adc_nids;
16887 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16888 spec->capsrc_nids = alc662_capsrc_nids;
16889 spec->capture_style = CAPT_MIX;
16891 if (!spec->cap_mixer)
16892 set_capture_mixer(spec);
16893 if (codec->vendor_id == 0x10ec0662)
16894 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
16896 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
16898 spec->vmaster_nid = 0x02;
16900 codec->patch_ops = alc_patch_ops;
16901 if (board_config == ALC662_AUTO)
16902 spec->init_hook = alc662_auto_init;
16903 #ifdef CONFIG_SND_HDA_POWER_SAVE
16904 if (!spec->loopback.amplist)
16905 spec->loopback.amplist = alc662_loopbacks;
16907 codec->proc_widget_hook = print_realtek_coef;
16915 static struct hda_codec_preset snd_hda_preset_realtek[] = {
16916 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16917 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16918 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16919 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16920 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16921 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16922 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16923 .patch = patch_alc861 },
16924 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16925 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16926 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16927 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16928 .patch = patch_alc883 },
16929 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16930 .patch = patch_alc662 },
16931 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16932 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16933 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16934 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16935 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16936 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16937 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16938 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16939 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16940 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16941 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16942 .patch = patch_alc883 },
16943 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16944 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16945 {} /* terminator */
16948 MODULE_ALIAS("snd-hda-codec-id:10ec*");
16950 MODULE_LICENSE("GPL");
16951 MODULE_DESCRIPTION("Realtek HD-audio codec");
16953 static struct hda_codec_preset_list realtek_list = {
16954 .preset = snd_hda_preset_realtek,
16955 .owner = THIS_MODULE,
16958 static int __init patch_realtek_init(void)
16960 return snd_hda_add_codec_preset(&realtek_list);
16963 static void __exit patch_realtek_exit(void)
16965 snd_hda_delete_codec_preset(&realtek_list);
16968 module_init(patch_realtek_init)
16969 module_exit(patch_realtek_exit)