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"
33 #include "hda_patch.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 */
81 #ifdef CONFIG_SND_DEBUG
85 ALC260_MODEL_LAST /* last tag */
95 ALC262_HP_BPC_D7000_WL,
96 ALC262_HP_BPC_D7000_WF,
108 ALC262_MODEL_LAST /* last tag */
117 ALC268_ACER_ASPIRE_ONE,
120 #ifdef CONFIG_SND_DEBUG
124 ALC268_MODEL_LAST /* last tag */
131 ALC269_ASUS_EEEPC_P703,
132 ALC269_ASUS_EEEPC_P901,
134 ALC269_MODEL_LAST /* last tag */
151 /* ALC861-VD models */
172 ALC662_ASUS_EEEPC_P701,
173 ALC662_ASUS_EEEPC_EP20,
212 ALC883_TARGA_2ch_DIG,
218 ALC883_LENOVO_101E_2ch,
219 ALC883_LENOVO_NB0763,
220 ALC888_LENOVO_MS7195_DIG,
227 ALC883_FUJITSU_PI2515,
228 ALC883_3ST_6ch_INTEL,
236 #define GPIO_MASK 0x03
239 /* codec parameterization */
240 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
241 unsigned int num_mixers;
243 const struct hda_verb *init_verbs[5]; /* initialization verbs
247 unsigned int num_init_verbs;
249 char *stream_name_analog; /* analog PCM stream */
250 struct hda_pcm_stream *stream_analog_playback;
251 struct hda_pcm_stream *stream_analog_capture;
252 struct hda_pcm_stream *stream_analog_alt_playback;
253 struct hda_pcm_stream *stream_analog_alt_capture;
255 char *stream_name_digital; /* digital PCM stream */
256 struct hda_pcm_stream *stream_digital_playback;
257 struct hda_pcm_stream *stream_digital_capture;
260 struct hda_multi_out multiout; /* playback set-up
261 * max_channels, dacs must be set
262 * dig_out_nid and hp_nid are optional
264 hda_nid_t alt_dac_nid;
267 unsigned int num_adc_nids;
269 hda_nid_t *capsrc_nids;
270 hda_nid_t dig_in_nid; /* digital-in NID; optional */
273 unsigned int num_mux_defs;
274 const struct hda_input_mux *input_mux;
275 unsigned int cur_mux[3];
278 const struct hda_channel_mode *channel_mode;
279 int num_channel_mode;
282 /* PCM information */
283 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
285 /* dynamic controls, init_verbs and input_mux */
286 struct auto_pin_cfg autocfg;
287 struct snd_array kctls;
288 struct hda_input_mux private_imux;
289 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
292 void (*init_hook)(struct hda_codec *codec);
293 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
295 /* for pin sensing */
296 unsigned int sense_updated: 1;
297 unsigned int jack_present: 1;
298 unsigned int master_sw: 1;
300 /* for virtual master */
301 hda_nid_t vmaster_nid;
302 #ifdef CONFIG_SND_HDA_POWER_SAVE
303 struct hda_loopback_check loopback;
308 unsigned int pll_coef_idx, pll_coef_bit;
312 * configuration template - to be copied to the spec instance
314 struct alc_config_preset {
315 struct snd_kcontrol_new *mixers[5]; /* should be identical size
318 const struct hda_verb *init_verbs[5];
319 unsigned int num_dacs;
321 hda_nid_t dig_out_nid; /* optional */
322 hda_nid_t hp_nid; /* optional */
323 unsigned int num_adc_nids;
325 hda_nid_t *capsrc_nids;
326 hda_nid_t dig_in_nid;
327 unsigned int num_channel_mode;
328 const struct hda_channel_mode *channel_mode;
330 unsigned int num_mux_defs;
331 const struct hda_input_mux *input_mux;
332 void (*unsol_event)(struct hda_codec *, unsigned int);
333 void (*init_hook)(struct hda_codec *);
334 #ifdef CONFIG_SND_HDA_POWER_SAVE
335 struct hda_amp_list *loopbacks;
343 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_info *uinfo)
346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347 struct alc_spec *spec = codec->spec;
348 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
349 if (mux_idx >= spec->num_mux_defs)
351 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
354 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
357 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct alc_spec *spec = codec->spec;
359 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
361 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
365 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
368 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct alc_spec *spec = codec->spec;
370 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
371 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
372 hda_nid_t nid = spec->capsrc_nids ?
373 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
374 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
375 nid, &spec->cur_mux[adc_idx]);
380 * channel mode setting
382 static int alc_ch_mode_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 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
388 spec->num_channel_mode);
391 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
392 struct snd_ctl_elem_value *ucontrol)
394 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
395 struct alc_spec *spec = codec->spec;
396 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
397 spec->num_channel_mode,
398 spec->multiout.max_channels);
401 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
405 struct alc_spec *spec = codec->spec;
406 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
407 spec->num_channel_mode,
408 &spec->multiout.max_channels);
409 if (err >= 0 && spec->need_dac_fix)
410 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
415 * Control the mode of pin widget settings via the mixer. "pc" is used
416 * instead of "%" to avoid consequences of accidently treating the % as
417 * being part of a format specifier. Maximum allowed length of a value is
418 * 63 characters plus NULL terminator.
420 * Note: some retasking pin complexes seem to ignore requests for input
421 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
422 * are requested. Therefore order this list so that this behaviour will not
423 * cause problems when mixer clients move through the enum sequentially.
424 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
427 static char *alc_pin_mode_names[] = {
428 "Mic 50pc bias", "Mic 80pc bias",
429 "Line in", "Line out", "Headphone out",
431 static unsigned char alc_pin_mode_values[] = {
432 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
434 /* The control can present all 5 options, or it can limit the options based
435 * in the pin being assumed to be exclusively an input or an output pin. In
436 * addition, "input" pins may or may not process the mic bias option
437 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
438 * accept requests for bias as of chip versions up to March 2006) and/or
439 * wiring in the computer.
441 #define ALC_PIN_DIR_IN 0x00
442 #define ALC_PIN_DIR_OUT 0x01
443 #define ALC_PIN_DIR_INOUT 0x02
444 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
445 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
447 /* Info about the pin modes supported by the different pin direction modes.
448 * For each direction the minimum and maximum values are given.
450 static signed char alc_pin_mode_dir_info[5][2] = {
451 { 0, 2 }, /* ALC_PIN_DIR_IN */
452 { 3, 4 }, /* ALC_PIN_DIR_OUT */
453 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
454 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
455 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
457 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
458 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
459 #define alc_pin_mode_n_items(_dir) \
460 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
462 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
463 struct snd_ctl_elem_info *uinfo)
465 unsigned int item_num = uinfo->value.enumerated.item;
466 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
468 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
470 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
472 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
473 item_num = alc_pin_mode_min(dir);
474 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
478 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
479 struct snd_ctl_elem_value *ucontrol)
482 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
483 hda_nid_t nid = kcontrol->private_value & 0xffff;
484 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
485 long *valp = ucontrol->value.integer.value;
486 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
487 AC_VERB_GET_PIN_WIDGET_CONTROL,
490 /* Find enumerated value for current pinctl setting */
491 i = alc_pin_mode_min(dir);
492 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
494 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
498 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
502 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
503 hda_nid_t nid = kcontrol->private_value & 0xffff;
504 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
505 long val = *ucontrol->value.integer.value;
506 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
507 AC_VERB_GET_PIN_WIDGET_CONTROL,
510 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
511 val = alc_pin_mode_min(dir);
513 change = pinctl != alc_pin_mode_values[val];
515 /* Set pin mode to that requested */
516 snd_hda_codec_write_cache(codec, nid, 0,
517 AC_VERB_SET_PIN_WIDGET_CONTROL,
518 alc_pin_mode_values[val]);
520 /* Also enable the retasking pin's input/output as required
521 * for the requested pin mode. Enum values of 2 or less are
524 * Dynamically switching the input/output buffers probably
525 * reduces noise slightly (particularly on input) so we'll
526 * do it. However, having both input and output buffers
527 * enabled simultaneously doesn't seem to be problematic if
528 * this turns out to be necessary in the future.
531 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
532 HDA_AMP_MUTE, HDA_AMP_MUTE);
533 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
536 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
537 HDA_AMP_MUTE, HDA_AMP_MUTE);
538 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
545 #define ALC_PIN_MODE(xname, nid, dir) \
546 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
547 .info = alc_pin_mode_info, \
548 .get = alc_pin_mode_get, \
549 .put = alc_pin_mode_put, \
550 .private_value = nid | (dir<<16) }
552 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
553 * together using a mask with more than one bit set. This control is
554 * currently used only by the ALC260 test model. At this stage they are not
555 * needed for any "production" models.
557 #ifdef CONFIG_SND_DEBUG
558 #define alc_gpio_data_info snd_ctl_boolean_mono_info
560 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
563 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
564 hda_nid_t nid = kcontrol->private_value & 0xffff;
565 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
566 long *valp = ucontrol->value.integer.value;
567 unsigned int val = snd_hda_codec_read(codec, nid, 0,
568 AC_VERB_GET_GPIO_DATA, 0x00);
570 *valp = (val & mask) != 0;
573 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_value *ucontrol)
577 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
578 hda_nid_t nid = kcontrol->private_value & 0xffff;
579 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
580 long val = *ucontrol->value.integer.value;
581 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
582 AC_VERB_GET_GPIO_DATA,
585 /* Set/unset the masked GPIO bit(s) as needed */
586 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
591 snd_hda_codec_write_cache(codec, nid, 0,
592 AC_VERB_SET_GPIO_DATA, gpio_data);
596 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
597 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
598 .info = alc_gpio_data_info, \
599 .get = alc_gpio_data_get, \
600 .put = alc_gpio_data_put, \
601 .private_value = nid | (mask<<16) }
602 #endif /* CONFIG_SND_DEBUG */
604 /* A switch control to allow the enabling of the digital IO pins on the
605 * ALC260. This is incredibly simplistic; the intention of this control is
606 * to provide something in the test model allowing digital outputs to be
607 * identified if present. If models are found which can utilise these
608 * outputs a more complete mixer control can be devised for those models if
611 #ifdef CONFIG_SND_DEBUG
612 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
614 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618 hda_nid_t nid = kcontrol->private_value & 0xffff;
619 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
620 long *valp = ucontrol->value.integer.value;
621 unsigned int val = snd_hda_codec_read(codec, nid, 0,
622 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
624 *valp = (val & mask) != 0;
627 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_value *ucontrol)
631 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
632 hda_nid_t nid = kcontrol->private_value & 0xffff;
633 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
634 long val = *ucontrol->value.integer.value;
635 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
636 AC_VERB_GET_DIGI_CONVERT_1,
639 /* Set/unset the masked control bit(s) as needed */
640 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
645 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
650 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
651 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
652 .info = alc_spdif_ctrl_info, \
653 .get = alc_spdif_ctrl_get, \
654 .put = alc_spdif_ctrl_put, \
655 .private_value = nid | (mask<<16) }
656 #endif /* CONFIG_SND_DEBUG */
658 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
659 * Again, this is only used in the ALC26x test models to help identify when
660 * the EAPD line must be asserted for features to work.
662 #ifdef CONFIG_SND_DEBUG
663 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
665 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
666 struct snd_ctl_elem_value *ucontrol)
668 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
669 hda_nid_t nid = kcontrol->private_value & 0xffff;
670 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
671 long *valp = ucontrol->value.integer.value;
672 unsigned int val = snd_hda_codec_read(codec, nid, 0,
673 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
675 *valp = (val & mask) != 0;
679 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
680 struct snd_ctl_elem_value *ucontrol)
683 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
684 hda_nid_t nid = kcontrol->private_value & 0xffff;
685 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
686 long val = *ucontrol->value.integer.value;
687 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
688 AC_VERB_GET_EAPD_BTLENABLE,
691 /* Set/unset the masked control bit(s) as needed */
692 change = (!val ? 0 : mask) != (ctrl_data & mask);
697 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
703 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
704 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
705 .info = alc_eapd_ctrl_info, \
706 .get = alc_eapd_ctrl_get, \
707 .put = alc_eapd_ctrl_put, \
708 .private_value = nid | (mask<<16) }
709 #endif /* CONFIG_SND_DEBUG */
712 * set up from the preset table
714 static void setup_preset(struct alc_spec *spec,
715 const struct alc_config_preset *preset)
719 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
720 spec->mixers[spec->num_mixers++] = preset->mixers[i];
721 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
723 spec->init_verbs[spec->num_init_verbs++] =
724 preset->init_verbs[i];
726 spec->channel_mode = preset->channel_mode;
727 spec->num_channel_mode = preset->num_channel_mode;
728 spec->need_dac_fix = preset->need_dac_fix;
730 spec->multiout.max_channels = spec->channel_mode[0].channels;
732 spec->multiout.num_dacs = preset->num_dacs;
733 spec->multiout.dac_nids = preset->dac_nids;
734 spec->multiout.dig_out_nid = preset->dig_out_nid;
735 spec->multiout.hp_nid = preset->hp_nid;
737 spec->num_mux_defs = preset->num_mux_defs;
738 if (!spec->num_mux_defs)
739 spec->num_mux_defs = 1;
740 spec->input_mux = preset->input_mux;
742 spec->num_adc_nids = preset->num_adc_nids;
743 spec->adc_nids = preset->adc_nids;
744 spec->capsrc_nids = preset->capsrc_nids;
745 spec->dig_in_nid = preset->dig_in_nid;
747 spec->unsol_event = preset->unsol_event;
748 spec->init_hook = preset->init_hook;
749 #ifdef CONFIG_SND_HDA_POWER_SAVE
750 spec->loopback.amplist = preset->loopbacks;
754 /* Enable GPIO mask and set output */
755 static struct hda_verb alc_gpio1_init_verbs[] = {
756 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
757 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
758 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
762 static struct hda_verb alc_gpio2_init_verbs[] = {
763 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
764 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
765 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
769 static struct hda_verb alc_gpio3_init_verbs[] = {
770 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
771 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
772 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
777 * Fix hardware PLL issue
778 * On some codecs, the analog PLL gating control must be off while
779 * the default value is 1.
781 static void alc_fix_pll(struct hda_codec *codec)
783 struct alc_spec *spec = codec->spec;
788 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
790 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
791 AC_VERB_GET_PROC_COEF, 0);
792 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
794 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
795 val & ~(1 << spec->pll_coef_bit));
798 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
799 unsigned int coef_idx, unsigned int coef_bit)
801 struct alc_spec *spec = codec->spec;
803 spec->pll_coef_idx = coef_idx;
804 spec->pll_coef_bit = coef_bit;
808 static void alc_sku_automute(struct hda_codec *codec)
810 struct alc_spec *spec = codec->spec;
811 unsigned int present;
812 unsigned int hp_nid = spec->autocfg.hp_pins[0];
813 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
815 /* need to execute and sync at first */
816 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
817 present = snd_hda_codec_read(codec, hp_nid, 0,
818 AC_VERB_GET_PIN_SENSE, 0);
819 spec->jack_present = (present & 0x80000000) != 0;
820 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
821 spec->jack_present ? 0 : PIN_OUT);
824 /* unsolicited event for HP jack sensing */
825 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
827 if (codec->vendor_id == 0x10ec0880)
831 if (res != ALC880_HP_EVENT)
834 alc_sku_automute(codec);
837 /* additional initialization for ALC888 variants */
838 static void alc888_coef_init(struct hda_codec *codec)
842 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
843 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
844 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
845 if ((tmp & 0xf0) == 2)
847 snd_hda_codec_read(codec, 0x20, 0,
848 AC_VERB_SET_PROC_COEF, 0x830);
851 snd_hda_codec_read(codec, 0x20, 0,
852 AC_VERB_SET_PROC_COEF, 0x3030);
855 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
856 * 31 ~ 16 : Manufacture ID
858 * 7 ~ 0 : Assembly ID
859 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
861 static void alc_subsystem_id(struct hda_codec *codec,
862 unsigned int porta, unsigned int porte,
865 unsigned int ass, tmp, i;
867 struct alc_spec *spec = codec->spec;
869 ass = codec->subsystem_id & 0xffff;
870 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
874 * 31~30 : port conetcivity
877 * 19~16 : Check sum (15:1)
882 if (codec->vendor_id == 0x10ec0260)
884 ass = snd_hda_codec_read(codec, nid, 0,
885 AC_VERB_GET_CONFIG_DEFAULT, 0);
886 if (!(ass & 1) && !(ass & 0x100000))
888 if ((ass >> 30) != 1) /* no physical connection */
893 for (i = 1; i < 16; i++) {
897 if (((ass >> 16) & 0xf) != tmp)
903 * 2 : 0 --> Desktop, 1 --> Laptop
904 * 3~5 : External Amplifier control
907 tmp = (ass & 0x38) >> 3; /* external Amp control */
910 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
913 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
916 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
918 case 5: /* set EAPD output high */
919 switch (codec->vendor_id) {
921 snd_hda_codec_write(codec, 0x0f, 0,
922 AC_VERB_SET_EAPD_BTLENABLE, 2);
923 snd_hda_codec_write(codec, 0x10, 0,
924 AC_VERB_SET_EAPD_BTLENABLE, 2);
935 snd_hda_codec_write(codec, 0x14, 0,
936 AC_VERB_SET_EAPD_BTLENABLE, 2);
937 snd_hda_codec_write(codec, 0x15, 0,
938 AC_VERB_SET_EAPD_BTLENABLE, 2);
941 switch (codec->vendor_id) {
943 snd_hda_codec_write(codec, 0x1a, 0,
944 AC_VERB_SET_COEF_INDEX, 7);
945 tmp = snd_hda_codec_read(codec, 0x1a, 0,
946 AC_VERB_GET_PROC_COEF, 0);
947 snd_hda_codec_write(codec, 0x1a, 0,
948 AC_VERB_SET_COEF_INDEX, 7);
949 snd_hda_codec_write(codec, 0x1a, 0,
950 AC_VERB_SET_PROC_COEF,
959 snd_hda_codec_write(codec, 0x20, 0,
960 AC_VERB_SET_COEF_INDEX, 7);
961 tmp = snd_hda_codec_read(codec, 0x20, 0,
962 AC_VERB_GET_PROC_COEF, 0);
963 snd_hda_codec_write(codec, 0x20, 0,
964 AC_VERB_SET_COEF_INDEX, 7);
965 snd_hda_codec_write(codec, 0x20, 0,
966 AC_VERB_SET_PROC_COEF,
970 /*alc888_coef_init(codec);*/ /* called in alc_init() */
974 snd_hda_codec_write(codec, 0x20, 0,
975 AC_VERB_SET_COEF_INDEX, 7);
976 tmp = snd_hda_codec_read(codec, 0x20, 0,
977 AC_VERB_GET_PROC_COEF, 0);
978 snd_hda_codec_write(codec, 0x20, 0,
979 AC_VERB_SET_COEF_INDEX, 7);
980 snd_hda_codec_write(codec, 0x20, 0,
981 AC_VERB_SET_PROC_COEF,
989 /* is laptop or Desktop and enable the function "Mute internal speaker
990 * when the external headphone out jack is plugged"
995 * 10~8 : Jack location
996 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
998 * 15 : 1 --> enable the function "Mute internal speaker
999 * when the external headphone out jack is plugged"
1001 if (!spec->autocfg.speaker_pins[0]) {
1002 if (spec->autocfg.line_out_pins[0])
1003 spec->autocfg.speaker_pins[0] =
1004 spec->autocfg.line_out_pins[0];
1009 if (!spec->autocfg.hp_pins[0]) {
1010 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1012 spec->autocfg.hp_pins[0] = porta;
1014 spec->autocfg.hp_pins[0] = porte;
1016 spec->autocfg.hp_pins[0] = portd;
1021 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1022 AC_VERB_SET_UNSOLICITED_ENABLE,
1023 AC_USRSP_EN | ALC880_HP_EVENT);
1025 spec->unsol_event = alc_sku_unsol_event;
1029 * Fix-up pin default configurations
1037 static void alc_fix_pincfg(struct hda_codec *codec,
1038 const struct snd_pci_quirk *quirk,
1039 const struct alc_pincfg **pinfix)
1041 const struct alc_pincfg *cfg;
1043 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1047 cfg = pinfix[quirk->value];
1048 for (; cfg->nid; cfg++) {
1051 for (i = 0; i < 4; i++) {
1052 snd_hda_codec_write(codec, cfg->nid, 0,
1053 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1061 * ALC880 3-stack model
1063 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1064 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1065 * F-Mic = 0x1b, HP = 0x19
1068 static hda_nid_t alc880_dac_nids[4] = {
1069 /* front, rear, clfe, rear_surr */
1070 0x02, 0x05, 0x04, 0x03
1073 static hda_nid_t alc880_adc_nids[3] = {
1078 /* The datasheet says the node 0x07 is connected from inputs,
1079 * but it shows zero connection in the real implementation on some devices.
1080 * Note: this is a 915GAV bug, fixed on 915GLV
1082 static hda_nid_t alc880_adc_nids_alt[2] = {
1087 #define ALC880_DIGOUT_NID 0x06
1088 #define ALC880_DIGIN_NID 0x0a
1090 static struct hda_input_mux alc880_capture_source = {
1094 { "Front Mic", 0x3 },
1100 /* channel source setting (2/6 channel selection for 3-stack) */
1102 static struct hda_verb alc880_threestack_ch2_init[] = {
1103 /* set line-in to input, mute it */
1104 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1105 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1106 /* set mic-in to input vref 80%, mute it */
1107 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1108 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1113 static struct hda_verb alc880_threestack_ch6_init[] = {
1114 /* set line-in to output, unmute it */
1115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1117 /* set mic-in to output, unmute it */
1118 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1119 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1123 static struct hda_channel_mode alc880_threestack_modes[2] = {
1124 { 2, alc880_threestack_ch2_init },
1125 { 6, alc880_threestack_ch6_init },
1128 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1129 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1130 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1131 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1132 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1133 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1134 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1135 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1136 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1137 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1138 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1139 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1140 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1142 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1143 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1144 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1145 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1146 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1150 .name = "Channel Mode",
1151 .info = alc_ch_mode_info,
1152 .get = alc_ch_mode_get,
1153 .put = alc_ch_mode_put,
1158 /* capture mixer elements */
1159 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1160 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1161 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1162 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1163 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1164 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1165 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1167 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1168 /* The multiple "Capture Source" controls confuse alsamixer
1169 * So call somewhat different..
1171 /* .name = "Capture Source", */
1172 .name = "Input Source",
1174 .info = alc_mux_enum_info,
1175 .get = alc_mux_enum_get,
1176 .put = alc_mux_enum_put,
1181 /* capture mixer elements (in case NID 0x07 not available) */
1182 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1183 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1184 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1185 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1186 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1189 /* The multiple "Capture Source" controls confuse alsamixer
1190 * So call somewhat different..
1192 /* .name = "Capture Source", */
1193 .name = "Input Source",
1195 .info = alc_mux_enum_info,
1196 .get = alc_mux_enum_get,
1197 .put = alc_mux_enum_put,
1205 * ALC880 5-stack model
1207 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1209 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1210 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1213 /* additional mixers to alc880_three_stack_mixer */
1214 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1215 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1216 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1220 /* channel source setting (6/8 channel selection for 5-stack) */
1222 static struct hda_verb alc880_fivestack_ch6_init[] = {
1223 /* set line-in to input, mute it */
1224 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1225 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1230 static struct hda_verb alc880_fivestack_ch8_init[] = {
1231 /* set line-in to output, unmute it */
1232 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1233 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1237 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1238 { 6, alc880_fivestack_ch6_init },
1239 { 8, alc880_fivestack_ch8_init },
1244 * ALC880 6-stack model
1246 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1247 * Side = 0x05 (0x0f)
1248 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1249 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1252 static hda_nid_t alc880_6st_dac_nids[4] = {
1253 /* front, rear, clfe, rear_surr */
1254 0x02, 0x03, 0x04, 0x05
1257 static struct hda_input_mux alc880_6stack_capture_source = {
1261 { "Front Mic", 0x1 },
1267 /* fixed 8-channels */
1268 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1272 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1273 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1274 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1275 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1276 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1277 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1278 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1279 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1280 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1281 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1282 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1283 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1284 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1286 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1288 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1289 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1290 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1291 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1292 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1294 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1295 .name = "Channel Mode",
1296 .info = alc_ch_mode_info,
1297 .get = alc_ch_mode_get,
1298 .put = alc_ch_mode_put,
1307 * W810 has rear IO for:
1310 * Center/LFE (DAC 04)
1313 * The system also has a pair of internal speakers, and a headphone jack.
1314 * These are both connected to Line2 on the codec, hence to DAC 02.
1316 * There is a variable resistor to control the speaker or headphone
1317 * volume. This is a hardware-only device without a software API.
1319 * Plugging headphones in will disable the internal speakers. This is
1320 * implemented in hardware, not via the driver using jack sense. In
1321 * a similar fashion, plugging into the rear socket marked "front" will
1322 * disable both the speakers and headphones.
1324 * For input, there's a microphone jack, and an "audio in" jack.
1325 * These may not do anything useful with this driver yet, because I
1326 * haven't setup any initialization verbs for these yet...
1329 static hda_nid_t alc880_w810_dac_nids[3] = {
1330 /* front, rear/surround, clfe */
1334 /* fixed 6 channels */
1335 static struct hda_channel_mode alc880_w810_modes[1] = {
1339 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1340 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1341 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1342 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1344 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1345 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1346 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1347 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1348 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1349 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1357 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1358 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1362 static hda_nid_t alc880_z71v_dac_nids[1] = {
1365 #define ALC880_Z71V_HP_DAC 0x03
1367 /* fixed 2 channels */
1368 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1372 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1373 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1374 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1375 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1376 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1377 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1378 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1379 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1380 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1386 * ALC880 F1734 model
1388 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1389 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1392 static hda_nid_t alc880_f1734_dac_nids[1] = {
1395 #define ALC880_F1734_HP_DAC 0x02
1397 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1398 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1399 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1400 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1401 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1403 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1409 static struct hda_input_mux alc880_f1734_capture_source = {
1421 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1422 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1423 * Mic = 0x18, Line = 0x1a
1426 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1427 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1429 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1432 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1433 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1434 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1435 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1436 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1437 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1438 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1439 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1440 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1441 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1443 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1446 .name = "Channel Mode",
1447 .info = alc_ch_mode_info,
1448 .get = alc_ch_mode_get,
1449 .put = alc_ch_mode_put,
1455 * ALC880 ASUS W1V model
1457 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1458 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1459 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1462 /* additional mixers to alc880_asus_mixer */
1463 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1464 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1465 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1469 /* additional mixers to alc880_asus_mixer */
1470 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1471 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1472 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1477 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1478 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1479 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1481 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1482 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1485 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1486 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1489 /* The multiple "Capture Source" controls confuse alsamixer
1490 * So call somewhat different..
1492 /* .name = "Capture Source", */
1493 .name = "Input Source",
1495 .info = alc_mux_enum_info,
1496 .get = alc_mux_enum_get,
1497 .put = alc_mux_enum_put,
1503 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1504 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1505 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1506 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1507 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1508 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1509 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1510 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1511 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1512 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1513 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1514 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1515 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1516 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1518 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1519 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1520 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1521 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1524 .name = "Channel Mode",
1525 .info = alc_ch_mode_info,
1526 .get = alc_ch_mode_get,
1527 .put = alc_ch_mode_put,
1532 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1533 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1534 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1535 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1536 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1537 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1538 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1539 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1540 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1541 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1542 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1546 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1547 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1548 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1549 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1550 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1551 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1552 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1557 * virtual master controls
1561 * slave controls for virtual master
1563 static const char *alc_slave_vols[] = {
1564 "Front Playback Volume",
1565 "Surround Playback Volume",
1566 "Center Playback Volume",
1567 "LFE Playback Volume",
1568 "Side Playback Volume",
1569 "Headphone Playback Volume",
1570 "Speaker Playback Volume",
1571 "Mono Playback Volume",
1572 "Line-Out Playback Volume",
1576 static const char *alc_slave_sws[] = {
1577 "Front Playback Switch",
1578 "Surround Playback Switch",
1579 "Center Playback Switch",
1580 "LFE Playback Switch",
1581 "Side Playback Switch",
1582 "Headphone Playback Switch",
1583 "Speaker Playback Switch",
1584 "Mono Playback Switch",
1585 "IEC958 Playback Switch",
1590 * build control elements
1593 static void alc_free_kctls(struct hda_codec *codec);
1595 static int alc_build_controls(struct hda_codec *codec)
1597 struct alc_spec *spec = codec->spec;
1601 for (i = 0; i < spec->num_mixers; i++) {
1602 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1607 if (spec->multiout.dig_out_nid) {
1608 err = snd_hda_create_spdif_out_ctls(codec,
1609 spec->multiout.dig_out_nid);
1612 err = snd_hda_create_spdif_share_sw(codec,
1616 spec->multiout.share_spdif = 1;
1618 if (spec->dig_in_nid) {
1619 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1624 /* if we have no master control, let's create it */
1625 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1626 unsigned int vmaster_tlv[4];
1627 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1628 HDA_OUTPUT, vmaster_tlv);
1629 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1630 vmaster_tlv, alc_slave_vols);
1634 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1635 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1636 NULL, alc_slave_sws);
1641 alc_free_kctls(codec); /* no longer needed */
1647 * initialize the codec volumes, etc
1651 * generic initialization of ADC, input mixers and output mixers
1653 static struct hda_verb alc880_volume_init_verbs[] = {
1655 * Unmute ADC0-2 and set the default input to mic-in
1657 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1658 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1659 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1660 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1661 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1662 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1664 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1666 * Note: PASD motherboards uses the Line In 2 as the input for front
1669 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1670 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1671 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1672 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1673 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1674 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1675 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1676 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1679 * Set up output mixers (0x0c - 0x0f)
1681 /* set vol=0 to output mixers */
1682 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1683 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1684 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1686 /* set up input amps for analog loopback */
1687 /* Amp Indices: DAC = 0, mixer = 1 */
1688 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1689 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1690 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1691 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1692 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1693 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1694 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1695 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1701 * 3-stack pin configuration:
1702 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1704 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1706 * preset connection lists of input pins
1707 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1709 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1710 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1711 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1714 * Set pin mode and muting
1716 /* set front pin widgets 0x14 for output */
1717 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1718 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1719 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1720 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1721 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1722 /* Mic2 (as headphone out) for HP output */
1723 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1724 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1725 /* Line In pin widget for input */
1726 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1727 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1728 /* Line2 (as front mic) pin widget for input and vref at 80% */
1729 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1730 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1731 /* CD pin widget for input */
1732 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1738 * 5-stack pin configuration:
1739 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1740 * line-in/side = 0x1a, f-mic = 0x1b
1742 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1744 * preset connection lists of input pins
1745 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1747 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1748 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1751 * Set pin mode and muting
1753 /* set pin widgets 0x14-0x17 for output */
1754 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1756 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1757 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1758 /* unmute pins for output (no gain on this amp) */
1759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1760 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1761 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1762 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1764 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1765 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1766 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1767 /* Mic2 (as headphone out) for HP output */
1768 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1769 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1770 /* Line In pin widget for input */
1771 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1772 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1773 /* Line2 (as front mic) pin widget for input and vref at 80% */
1774 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1775 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1776 /* CD pin widget for input */
1777 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1783 * W810 pin configuration:
1784 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1786 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1787 /* hphone/speaker input selector: front DAC */
1788 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1790 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1791 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1792 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1793 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1794 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1795 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1804 * Z71V pin configuration:
1805 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1807 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1809 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1813 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1814 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1815 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1816 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1822 * 6-stack pin configuration:
1823 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1824 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1826 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1827 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1829 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1830 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1832 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1833 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1834 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1835 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1836 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1838 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1839 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1840 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1841 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1842 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1843 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1844 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1845 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1846 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1852 * Uniwill pin configuration:
1853 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1856 static struct hda_verb alc880_uniwill_init_verbs[] = {
1857 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1859 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1865 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1866 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1867 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1868 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1869 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1870 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1871 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1876 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1877 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1878 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1880 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1881 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1882 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1884 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1885 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1892 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1894 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1895 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1897 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1898 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1899 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1901 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1902 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1905 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1906 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1907 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1908 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1910 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1911 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1912 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1913 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1914 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1915 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1917 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1918 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1923 static struct hda_verb alc880_beep_init_verbs[] = {
1924 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1928 /* toggle speaker-output according to the hp-jack state */
1929 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1931 unsigned int present;
1934 present = snd_hda_codec_read(codec, 0x14, 0,
1935 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1936 bits = present ? HDA_AMP_MUTE : 0;
1937 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1938 HDA_AMP_MUTE, bits);
1939 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1940 HDA_AMP_MUTE, bits);
1943 /* auto-toggle front mic */
1944 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1946 unsigned int present;
1949 present = snd_hda_codec_read(codec, 0x18, 0,
1950 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1951 bits = present ? HDA_AMP_MUTE : 0;
1952 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1955 static void alc880_uniwill_automute(struct hda_codec *codec)
1957 alc880_uniwill_hp_automute(codec);
1958 alc880_uniwill_mic_automute(codec);
1961 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1964 /* Looks like the unsol event is incompatible with the standard
1965 * definition. 4bit tag is placed at 28 bit!
1967 switch (res >> 28) {
1968 case ALC880_HP_EVENT:
1969 alc880_uniwill_hp_automute(codec);
1971 case ALC880_MIC_EVENT:
1972 alc880_uniwill_mic_automute(codec);
1977 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1979 unsigned int present;
1982 present = snd_hda_codec_read(codec, 0x14, 0,
1983 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1984 bits = present ? HDA_AMP_MUTE : 0;
1985 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
1988 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1990 unsigned int present;
1992 present = snd_hda_codec_read(codec, 0x21, 0,
1993 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1994 present &= HDA_AMP_VOLMASK;
1995 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1996 HDA_AMP_VOLMASK, present);
1997 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1998 HDA_AMP_VOLMASK, present);
2001 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2004 /* Looks like the unsol event is incompatible with the standard
2005 * definition. 4bit tag is placed at 28 bit!
2007 if ((res >> 28) == ALC880_HP_EVENT)
2008 alc880_uniwill_p53_hp_automute(codec);
2009 if ((res >> 28) == ALC880_DCVOL_EVENT)
2010 alc880_uniwill_p53_dcvol_automute(codec);
2014 * F1734 pin configuration:
2015 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2017 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2018 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2019 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2020 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2021 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2022 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2024 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2025 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2029 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2030 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2031 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2032 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2033 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2034 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2035 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2036 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2037 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2039 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2040 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2046 * ASUS pin configuration:
2047 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2049 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2050 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2051 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2052 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2053 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2055 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2059 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2061 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2062 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2064 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2065 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2066 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2067 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2068 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2069 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2070 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2071 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2072 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2077 /* Enable GPIO mask and set output */
2078 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2079 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2081 /* Clevo m520g init */
2082 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2083 /* headphone output */
2084 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2087 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2089 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2090 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2092 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2093 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2094 /* Mic1 (rear panel) */
2095 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2096 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2097 /* Mic2 (front panel) */
2098 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2099 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2102 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2103 /* change to EAPD mode */
2104 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2105 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2110 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2111 /* change to EAPD mode */
2112 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2113 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2115 /* Headphone output */
2116 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2118 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2119 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2121 /* Line In pin widget for input */
2122 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2123 /* CD pin widget for input */
2124 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2125 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2126 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2128 /* change to EAPD mode */
2129 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2130 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2136 * LG m1 express dual
2139 * Rear Line-In/Out (blue): 0x14
2140 * Build-in Mic-In: 0x15
2142 * HP-Out (green): 0x1b
2143 * Mic-In/Out (red): 0x19
2147 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2148 static hda_nid_t alc880_lg_dac_nids[3] = {
2152 /* seems analog CD is not working */
2153 static struct hda_input_mux alc880_lg_capture_source = {
2158 { "Internal Mic", 0x6 },
2162 /* 2,4,6 channel modes */
2163 static struct hda_verb alc880_lg_ch2_init[] = {
2164 /* set line-in and mic-in to input */
2165 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2166 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2170 static struct hda_verb alc880_lg_ch4_init[] = {
2171 /* set line-in to out and mic-in to input */
2172 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2173 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2177 static struct hda_verb alc880_lg_ch6_init[] = {
2178 /* set line-in and mic-in to output */
2179 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2180 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2184 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2185 { 2, alc880_lg_ch2_init },
2186 { 4, alc880_lg_ch4_init },
2187 { 6, alc880_lg_ch6_init },
2190 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2191 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2192 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2193 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2194 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2195 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2196 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2197 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2198 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2201 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2202 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2203 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2204 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2207 .name = "Channel Mode",
2208 .info = alc_ch_mode_info,
2209 .get = alc_ch_mode_get,
2210 .put = alc_ch_mode_put,
2215 static struct hda_verb alc880_lg_init_verbs[] = {
2216 /* set capture source to mic-in */
2217 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2218 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2219 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2220 /* mute all amp mixer inputs */
2221 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2222 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2223 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2224 /* line-in to input */
2225 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2228 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2229 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2231 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2232 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2233 /* mic-in to input */
2234 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2235 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2239 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2240 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2242 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2246 /* toggle speaker-output according to the hp-jack state */
2247 static void alc880_lg_automute(struct hda_codec *codec)
2249 unsigned int present;
2252 present = snd_hda_codec_read(codec, 0x1b, 0,
2253 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2254 bits = present ? HDA_AMP_MUTE : 0;
2255 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2256 HDA_AMP_MUTE, bits);
2259 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2261 /* Looks like the unsol event is incompatible with the standard
2262 * definition. 4bit tag is placed at 28 bit!
2264 if ((res >> 28) == 0x01)
2265 alc880_lg_automute(codec);
2274 * Built-in Mic-In: 0x19
2280 static struct hda_input_mux alc880_lg_lw_capture_source = {
2284 { "Internal Mic", 0x1 },
2289 #define alc880_lg_lw_modes alc880_threestack_modes
2291 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2292 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2293 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2294 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2295 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2296 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2297 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2298 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2299 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2301 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2303 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2304 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2305 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2307 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2308 .name = "Channel Mode",
2309 .info = alc_ch_mode_info,
2310 .get = alc_ch_mode_get,
2311 .put = alc_ch_mode_put,
2316 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2317 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2318 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2319 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2321 /* set capture source to mic-in */
2322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2323 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2324 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2325 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2327 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2328 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2330 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2331 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 /* mic-in to input */
2333 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2334 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2336 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2337 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2339 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2343 /* toggle speaker-output according to the hp-jack state */
2344 static void alc880_lg_lw_automute(struct hda_codec *codec)
2346 unsigned int present;
2349 present = snd_hda_codec_read(codec, 0x1b, 0,
2350 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2351 bits = present ? HDA_AMP_MUTE : 0;
2352 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2353 HDA_AMP_MUTE, bits);
2356 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2358 /* Looks like the unsol event is incompatible with the standard
2359 * definition. 4bit tag is placed at 28 bit!
2361 if ((res >> 28) == 0x01)
2362 alc880_lg_lw_automute(codec);
2365 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2366 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2367 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2369 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2370 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2371 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2375 static struct hda_input_mux alc880_medion_rim_capture_source = {
2379 { "Internal Mic", 0x1 },
2383 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2384 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2387 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2389 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2390 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2391 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2392 /* Mic2 (as headphone out) for HP output */
2393 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2394 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2395 /* Internal Speaker */
2396 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2397 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2399 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2400 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2402 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2406 /* toggle speaker-output according to the hp-jack state */
2407 static void alc880_medion_rim_automute(struct hda_codec *codec)
2409 unsigned int present;
2412 present = snd_hda_codec_read(codec, 0x14, 0,
2413 AC_VERB_GET_PIN_SENSE, 0)
2414 & AC_PINSENSE_PRESENCE;
2415 bits = present ? HDA_AMP_MUTE : 0;
2416 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2417 HDA_AMP_MUTE, bits);
2419 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2421 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2424 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2427 /* Looks like the unsol event is incompatible with the standard
2428 * definition. 4bit tag is placed at 28 bit!
2430 if ((res >> 28) == ALC880_HP_EVENT)
2431 alc880_medion_rim_automute(codec);
2434 #ifdef CONFIG_SND_HDA_POWER_SAVE
2435 static struct hda_amp_list alc880_loopbacks[] = {
2436 { 0x0b, HDA_INPUT, 0 },
2437 { 0x0b, HDA_INPUT, 1 },
2438 { 0x0b, HDA_INPUT, 2 },
2439 { 0x0b, HDA_INPUT, 3 },
2440 { 0x0b, HDA_INPUT, 4 },
2444 static struct hda_amp_list alc880_lg_loopbacks[] = {
2445 { 0x0b, HDA_INPUT, 1 },
2446 { 0x0b, HDA_INPUT, 6 },
2447 { 0x0b, HDA_INPUT, 7 },
2456 static int alc_init(struct hda_codec *codec)
2458 struct alc_spec *spec = codec->spec;
2462 if (codec->vendor_id == 0x10ec0888)
2463 alc888_coef_init(codec);
2465 for (i = 0; i < spec->num_init_verbs; i++)
2466 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2468 if (spec->init_hook)
2469 spec->init_hook(codec);
2474 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2476 struct alc_spec *spec = codec->spec;
2478 if (spec->unsol_event)
2479 spec->unsol_event(codec, res);
2482 #ifdef CONFIG_SND_HDA_POWER_SAVE
2483 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2485 struct alc_spec *spec = codec->spec;
2486 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2491 * Analog playback callbacks
2493 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2494 struct hda_codec *codec,
2495 struct snd_pcm_substream *substream)
2497 struct alc_spec *spec = codec->spec;
2498 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2502 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2503 struct hda_codec *codec,
2504 unsigned int stream_tag,
2505 unsigned int format,
2506 struct snd_pcm_substream *substream)
2508 struct alc_spec *spec = codec->spec;
2509 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2510 stream_tag, format, substream);
2513 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2514 struct hda_codec *codec,
2515 struct snd_pcm_substream *substream)
2517 struct alc_spec *spec = codec->spec;
2518 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2524 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2525 struct hda_codec *codec,
2526 struct snd_pcm_substream *substream)
2528 struct alc_spec *spec = codec->spec;
2529 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2532 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2533 struct hda_codec *codec,
2534 unsigned int stream_tag,
2535 unsigned int format,
2536 struct snd_pcm_substream *substream)
2538 struct alc_spec *spec = codec->spec;
2539 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2540 stream_tag, format, substream);
2543 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2544 struct hda_codec *codec,
2545 struct snd_pcm_substream *substream)
2547 struct alc_spec *spec = codec->spec;
2548 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2554 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2555 struct hda_codec *codec,
2556 unsigned int stream_tag,
2557 unsigned int format,
2558 struct snd_pcm_substream *substream)
2560 struct alc_spec *spec = codec->spec;
2562 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2563 stream_tag, 0, format);
2567 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2568 struct hda_codec *codec,
2569 struct snd_pcm_substream *substream)
2571 struct alc_spec *spec = codec->spec;
2573 snd_hda_codec_cleanup_stream(codec,
2574 spec->adc_nids[substream->number + 1]);
2581 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2585 /* NID is set in alc_build_pcms */
2587 .open = alc880_playback_pcm_open,
2588 .prepare = alc880_playback_pcm_prepare,
2589 .cleanup = alc880_playback_pcm_cleanup
2593 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2597 /* NID is set in alc_build_pcms */
2600 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2604 /* NID is set in alc_build_pcms */
2607 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2608 .substreams = 2, /* can be overridden */
2611 /* NID is set in alc_build_pcms */
2613 .prepare = alc880_alt_capture_pcm_prepare,
2614 .cleanup = alc880_alt_capture_pcm_cleanup
2618 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2622 /* NID is set in alc_build_pcms */
2624 .open = alc880_dig_playback_pcm_open,
2625 .close = alc880_dig_playback_pcm_close,
2626 .prepare = alc880_dig_playback_pcm_prepare
2630 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2634 /* NID is set in alc_build_pcms */
2637 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2638 static struct hda_pcm_stream alc_pcm_null_stream = {
2644 static int alc_build_pcms(struct hda_codec *codec)
2646 struct alc_spec *spec = codec->spec;
2647 struct hda_pcm *info = spec->pcm_rec;
2650 codec->num_pcms = 1;
2651 codec->pcm_info = info;
2653 info->name = spec->stream_name_analog;
2654 if (spec->stream_analog_playback) {
2655 if (snd_BUG_ON(!spec->multiout.dac_nids))
2657 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2658 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2660 if (spec->stream_analog_capture) {
2661 if (snd_BUG_ON(!spec->adc_nids))
2663 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2664 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2667 if (spec->channel_mode) {
2668 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2669 for (i = 0; i < spec->num_channel_mode; i++) {
2670 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2671 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2676 /* SPDIF for stream index #1 */
2677 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2678 codec->num_pcms = 2;
2679 info = spec->pcm_rec + 1;
2680 info->name = spec->stream_name_digital;
2681 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2682 if (spec->multiout.dig_out_nid &&
2683 spec->stream_digital_playback) {
2684 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2685 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2687 if (spec->dig_in_nid &&
2688 spec->stream_digital_capture) {
2689 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2690 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2692 /* FIXME: do we need this for all Realtek codec models? */
2693 codec->spdif_status_reset = 1;
2696 /* If the use of more than one ADC is requested for the current
2697 * model, configure a second analog capture-only PCM.
2699 /* Additional Analaog capture for index #2 */
2700 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2701 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2702 codec->num_pcms = 3;
2703 info = spec->pcm_rec + 2;
2704 info->name = spec->stream_name_analog;
2705 if (spec->alt_dac_nid) {
2706 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2707 *spec->stream_analog_alt_playback;
2708 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2711 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2712 alc_pcm_null_stream;
2713 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2715 if (spec->num_adc_nids > 1) {
2716 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2717 *spec->stream_analog_alt_capture;
2718 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2720 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2721 spec->num_adc_nids - 1;
2723 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2724 alc_pcm_null_stream;
2725 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2732 static void alc_free_kctls(struct hda_codec *codec)
2734 struct alc_spec *spec = codec->spec;
2736 if (spec->kctls.list) {
2737 struct snd_kcontrol_new *kctl = spec->kctls.list;
2739 for (i = 0; i < spec->kctls.used; i++)
2740 kfree(kctl[i].name);
2742 snd_array_free(&spec->kctls);
2745 static void alc_free(struct hda_codec *codec)
2747 struct alc_spec *spec = codec->spec;
2752 alc_free_kctls(codec);
2754 codec->spec = NULL; /* to be sure */
2759 static struct hda_codec_ops alc_patch_ops = {
2760 .build_controls = alc_build_controls,
2761 .build_pcms = alc_build_pcms,
2764 .unsol_event = alc_unsol_event,
2765 #ifdef CONFIG_SND_HDA_POWER_SAVE
2766 .check_power_status = alc_check_power_status,
2772 * Test configuration for debugging
2774 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2777 #ifdef CONFIG_SND_DEBUG
2778 static hda_nid_t alc880_test_dac_nids[4] = {
2779 0x02, 0x03, 0x04, 0x05
2782 static struct hda_input_mux alc880_test_capture_source = {
2791 { "Surround", 0x6 },
2795 static struct hda_channel_mode alc880_test_modes[4] = {
2802 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2803 struct snd_ctl_elem_info *uinfo)
2805 static char *texts[] = {
2806 "N/A", "Line Out", "HP Out",
2807 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2809 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2811 uinfo->value.enumerated.items = 8;
2812 if (uinfo->value.enumerated.item >= 8)
2813 uinfo->value.enumerated.item = 7;
2814 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2818 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2819 struct snd_ctl_elem_value *ucontrol)
2821 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2822 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2823 unsigned int pin_ctl, item = 0;
2825 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2826 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2827 if (pin_ctl & AC_PINCTL_OUT_EN) {
2828 if (pin_ctl & AC_PINCTL_HP_EN)
2832 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2833 switch (pin_ctl & AC_PINCTL_VREFEN) {
2834 case AC_PINCTL_VREF_HIZ: item = 3; break;
2835 case AC_PINCTL_VREF_50: item = 4; break;
2836 case AC_PINCTL_VREF_GRD: item = 5; break;
2837 case AC_PINCTL_VREF_80: item = 6; break;
2838 case AC_PINCTL_VREF_100: item = 7; break;
2841 ucontrol->value.enumerated.item[0] = item;
2845 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2846 struct snd_ctl_elem_value *ucontrol)
2848 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2849 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2850 static unsigned int ctls[] = {
2851 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2852 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2853 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2854 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2855 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2856 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2858 unsigned int old_ctl, new_ctl;
2860 old_ctl = snd_hda_codec_read(codec, nid, 0,
2861 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2862 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2863 if (old_ctl != new_ctl) {
2865 snd_hda_codec_write_cache(codec, nid, 0,
2866 AC_VERB_SET_PIN_WIDGET_CONTROL,
2868 val = ucontrol->value.enumerated.item[0] >= 3 ?
2870 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2877 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2878 struct snd_ctl_elem_info *uinfo)
2880 static char *texts[] = {
2881 "Front", "Surround", "CLFE", "Side"
2883 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2885 uinfo->value.enumerated.items = 4;
2886 if (uinfo->value.enumerated.item >= 4)
2887 uinfo->value.enumerated.item = 3;
2888 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2892 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2893 struct snd_ctl_elem_value *ucontrol)
2895 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2896 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2899 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2900 ucontrol->value.enumerated.item[0] = sel & 3;
2904 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2905 struct snd_ctl_elem_value *ucontrol)
2907 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2908 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2911 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2912 if (ucontrol->value.enumerated.item[0] != sel) {
2913 sel = ucontrol->value.enumerated.item[0] & 3;
2914 snd_hda_codec_write_cache(codec, nid, 0,
2915 AC_VERB_SET_CONNECT_SEL, sel);
2921 #define PIN_CTL_TEST(xname,nid) { \
2922 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2924 .info = alc_test_pin_ctl_info, \
2925 .get = alc_test_pin_ctl_get, \
2926 .put = alc_test_pin_ctl_put, \
2927 .private_value = nid \
2930 #define PIN_SRC_TEST(xname,nid) { \
2931 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2933 .info = alc_test_pin_src_info, \
2934 .get = alc_test_pin_src_get, \
2935 .put = alc_test_pin_src_put, \
2936 .private_value = nid \
2939 static struct snd_kcontrol_new alc880_test_mixer[] = {
2940 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2941 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2942 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2943 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2944 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2945 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2946 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2947 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2948 PIN_CTL_TEST("Front Pin Mode", 0x14),
2949 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2950 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2951 PIN_CTL_TEST("Side Pin Mode", 0x17),
2952 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2953 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2954 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2955 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2956 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2957 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2958 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2959 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2960 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2961 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2962 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2963 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2964 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2965 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2966 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2967 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2968 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2969 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2971 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2972 .name = "Channel Mode",
2973 .info = alc_ch_mode_info,
2974 .get = alc_ch_mode_get,
2975 .put = alc_ch_mode_put,
2980 static struct hda_verb alc880_test_init_verbs[] = {
2981 /* Unmute inputs of 0x0c - 0x0f */
2982 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2983 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2984 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2985 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2986 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2987 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2988 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2989 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2990 /* Vol output for 0x0c-0x0f */
2991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2993 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2994 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2995 /* Set output pins 0x14-0x17 */
2996 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2998 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2999 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3000 /* Unmute output pins 0x14-0x17 */
3001 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3003 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3004 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3005 /* Set input pins 0x18-0x1c */
3006 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3007 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3008 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3009 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3010 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3011 /* Mute input pins 0x18-0x1b */
3012 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3013 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3015 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3018 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3020 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3022 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3023 /* Analog input/passthru */
3024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3028 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3036 static const char *alc880_models[ALC880_MODEL_LAST] = {
3037 [ALC880_3ST] = "3stack",
3038 [ALC880_TCL_S700] = "tcl",
3039 [ALC880_3ST_DIG] = "3stack-digout",
3040 [ALC880_CLEVO] = "clevo",
3041 [ALC880_5ST] = "5stack",
3042 [ALC880_5ST_DIG] = "5stack-digout",
3043 [ALC880_W810] = "w810",
3044 [ALC880_Z71V] = "z71v",
3045 [ALC880_6ST] = "6stack",
3046 [ALC880_6ST_DIG] = "6stack-digout",
3047 [ALC880_ASUS] = "asus",
3048 [ALC880_ASUS_W1V] = "asus-w1v",
3049 [ALC880_ASUS_DIG] = "asus-dig",
3050 [ALC880_ASUS_DIG2] = "asus-dig2",
3051 [ALC880_UNIWILL_DIG] = "uniwill",
3052 [ALC880_UNIWILL_P53] = "uniwill-p53",
3053 [ALC880_FUJITSU] = "fujitsu",
3054 [ALC880_F1734] = "F1734",
3056 [ALC880_LG_LW] = "lg-lw",
3057 [ALC880_MEDION_RIM] = "medion",
3058 #ifdef CONFIG_SND_DEBUG
3059 [ALC880_TEST] = "test",
3061 [ALC880_AUTO] = "auto",
3064 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3065 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3066 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3067 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3068 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3069 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3070 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3071 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3072 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3073 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3074 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3075 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3076 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3077 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3078 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3079 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3080 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3081 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3082 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3083 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3084 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3085 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3086 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3087 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3088 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3089 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3090 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3091 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3092 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3093 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3094 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3095 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3096 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3097 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3098 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3099 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3100 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3101 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3102 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3103 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3104 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3105 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3106 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3107 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3108 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3109 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3110 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3111 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3112 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3113 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3114 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3115 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3116 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3117 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3118 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3119 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3120 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3121 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3122 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3123 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3124 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3125 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3126 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3127 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3128 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3129 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3130 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3131 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3132 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3133 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3134 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3135 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3140 * ALC880 codec presets
3142 static struct alc_config_preset alc880_presets[] = {
3144 .mixers = { alc880_three_stack_mixer },
3145 .init_verbs = { alc880_volume_init_verbs,
3146 alc880_pin_3stack_init_verbs },
3147 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3148 .dac_nids = alc880_dac_nids,
3149 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3150 .channel_mode = alc880_threestack_modes,
3152 .input_mux = &alc880_capture_source,
3154 [ALC880_3ST_DIG] = {
3155 .mixers = { alc880_three_stack_mixer },
3156 .init_verbs = { alc880_volume_init_verbs,
3157 alc880_pin_3stack_init_verbs },
3158 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3159 .dac_nids = alc880_dac_nids,
3160 .dig_out_nid = ALC880_DIGOUT_NID,
3161 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3162 .channel_mode = alc880_threestack_modes,
3164 .input_mux = &alc880_capture_source,
3166 [ALC880_TCL_S700] = {
3167 .mixers = { alc880_tcl_s700_mixer },
3168 .init_verbs = { alc880_volume_init_verbs,
3169 alc880_pin_tcl_S700_init_verbs,
3170 alc880_gpio2_init_verbs },
3171 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3172 .dac_nids = alc880_dac_nids,
3174 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3175 .channel_mode = alc880_2_jack_modes,
3176 .input_mux = &alc880_capture_source,
3179 .mixers = { alc880_three_stack_mixer,
3180 alc880_five_stack_mixer},
3181 .init_verbs = { alc880_volume_init_verbs,
3182 alc880_pin_5stack_init_verbs },
3183 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3184 .dac_nids = alc880_dac_nids,
3185 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3186 .channel_mode = alc880_fivestack_modes,
3187 .input_mux = &alc880_capture_source,
3189 [ALC880_5ST_DIG] = {
3190 .mixers = { alc880_three_stack_mixer,
3191 alc880_five_stack_mixer },
3192 .init_verbs = { alc880_volume_init_verbs,
3193 alc880_pin_5stack_init_verbs },
3194 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3195 .dac_nids = alc880_dac_nids,
3196 .dig_out_nid = ALC880_DIGOUT_NID,
3197 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3198 .channel_mode = alc880_fivestack_modes,
3199 .input_mux = &alc880_capture_source,
3202 .mixers = { alc880_six_stack_mixer },
3203 .init_verbs = { alc880_volume_init_verbs,
3204 alc880_pin_6stack_init_verbs },
3205 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3206 .dac_nids = alc880_6st_dac_nids,
3207 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3208 .channel_mode = alc880_sixstack_modes,
3209 .input_mux = &alc880_6stack_capture_source,
3211 [ALC880_6ST_DIG] = {
3212 .mixers = { alc880_six_stack_mixer },
3213 .init_verbs = { alc880_volume_init_verbs,
3214 alc880_pin_6stack_init_verbs },
3215 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3216 .dac_nids = alc880_6st_dac_nids,
3217 .dig_out_nid = ALC880_DIGOUT_NID,
3218 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3219 .channel_mode = alc880_sixstack_modes,
3220 .input_mux = &alc880_6stack_capture_source,
3223 .mixers = { alc880_w810_base_mixer },
3224 .init_verbs = { alc880_volume_init_verbs,
3225 alc880_pin_w810_init_verbs,
3226 alc880_gpio2_init_verbs },
3227 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3228 .dac_nids = alc880_w810_dac_nids,
3229 .dig_out_nid = ALC880_DIGOUT_NID,
3230 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3231 .channel_mode = alc880_w810_modes,
3232 .input_mux = &alc880_capture_source,
3235 .mixers = { alc880_z71v_mixer },
3236 .init_verbs = { alc880_volume_init_verbs,
3237 alc880_pin_z71v_init_verbs },
3238 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3239 .dac_nids = alc880_z71v_dac_nids,
3240 .dig_out_nid = ALC880_DIGOUT_NID,
3242 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3243 .channel_mode = alc880_2_jack_modes,
3244 .input_mux = &alc880_capture_source,
3247 .mixers = { alc880_f1734_mixer },
3248 .init_verbs = { alc880_volume_init_verbs,
3249 alc880_pin_f1734_init_verbs },
3250 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3251 .dac_nids = alc880_f1734_dac_nids,
3253 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3254 .channel_mode = alc880_2_jack_modes,
3255 .input_mux = &alc880_f1734_capture_source,
3256 .unsol_event = alc880_uniwill_p53_unsol_event,
3257 .init_hook = alc880_uniwill_p53_hp_automute,
3260 .mixers = { alc880_asus_mixer },
3261 .init_verbs = { alc880_volume_init_verbs,
3262 alc880_pin_asus_init_verbs,
3263 alc880_gpio1_init_verbs },
3264 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3265 .dac_nids = alc880_asus_dac_nids,
3266 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3267 .channel_mode = alc880_asus_modes,
3269 .input_mux = &alc880_capture_source,
3271 [ALC880_ASUS_DIG] = {
3272 .mixers = { alc880_asus_mixer },
3273 .init_verbs = { alc880_volume_init_verbs,
3274 alc880_pin_asus_init_verbs,
3275 alc880_gpio1_init_verbs },
3276 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3277 .dac_nids = alc880_asus_dac_nids,
3278 .dig_out_nid = ALC880_DIGOUT_NID,
3279 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3280 .channel_mode = alc880_asus_modes,
3282 .input_mux = &alc880_capture_source,
3284 [ALC880_ASUS_DIG2] = {
3285 .mixers = { alc880_asus_mixer },
3286 .init_verbs = { alc880_volume_init_verbs,
3287 alc880_pin_asus_init_verbs,
3288 alc880_gpio2_init_verbs }, /* use GPIO2 */
3289 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3290 .dac_nids = alc880_asus_dac_nids,
3291 .dig_out_nid = ALC880_DIGOUT_NID,
3292 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3293 .channel_mode = alc880_asus_modes,
3295 .input_mux = &alc880_capture_source,
3297 [ALC880_ASUS_W1V] = {
3298 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3299 .init_verbs = { alc880_volume_init_verbs,
3300 alc880_pin_asus_init_verbs,
3301 alc880_gpio1_init_verbs },
3302 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3303 .dac_nids = alc880_asus_dac_nids,
3304 .dig_out_nid = ALC880_DIGOUT_NID,
3305 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3306 .channel_mode = alc880_asus_modes,
3308 .input_mux = &alc880_capture_source,
3310 [ALC880_UNIWILL_DIG] = {
3311 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3312 .init_verbs = { alc880_volume_init_verbs,
3313 alc880_pin_asus_init_verbs },
3314 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3315 .dac_nids = alc880_asus_dac_nids,
3316 .dig_out_nid = ALC880_DIGOUT_NID,
3317 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3318 .channel_mode = alc880_asus_modes,
3320 .input_mux = &alc880_capture_source,
3322 [ALC880_UNIWILL] = {
3323 .mixers = { alc880_uniwill_mixer },
3324 .init_verbs = { alc880_volume_init_verbs,
3325 alc880_uniwill_init_verbs },
3326 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3327 .dac_nids = alc880_asus_dac_nids,
3328 .dig_out_nid = ALC880_DIGOUT_NID,
3329 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3330 .channel_mode = alc880_threestack_modes,
3332 .input_mux = &alc880_capture_source,
3333 .unsol_event = alc880_uniwill_unsol_event,
3334 .init_hook = alc880_uniwill_automute,
3336 [ALC880_UNIWILL_P53] = {
3337 .mixers = { alc880_uniwill_p53_mixer },
3338 .init_verbs = { alc880_volume_init_verbs,
3339 alc880_uniwill_p53_init_verbs },
3340 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3341 .dac_nids = alc880_asus_dac_nids,
3342 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3343 .channel_mode = alc880_threestack_modes,
3344 .input_mux = &alc880_capture_source,
3345 .unsol_event = alc880_uniwill_p53_unsol_event,
3346 .init_hook = alc880_uniwill_p53_hp_automute,
3348 [ALC880_FUJITSU] = {
3349 .mixers = { alc880_fujitsu_mixer,
3350 alc880_pcbeep_mixer, },
3351 .init_verbs = { alc880_volume_init_verbs,
3352 alc880_uniwill_p53_init_verbs,
3353 alc880_beep_init_verbs },
3354 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3355 .dac_nids = alc880_dac_nids,
3356 .dig_out_nid = ALC880_DIGOUT_NID,
3357 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3358 .channel_mode = alc880_2_jack_modes,
3359 .input_mux = &alc880_capture_source,
3360 .unsol_event = alc880_uniwill_p53_unsol_event,
3361 .init_hook = alc880_uniwill_p53_hp_automute,
3364 .mixers = { alc880_three_stack_mixer },
3365 .init_verbs = { alc880_volume_init_verbs,
3366 alc880_pin_clevo_init_verbs },
3367 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3368 .dac_nids = alc880_dac_nids,
3370 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3371 .channel_mode = alc880_threestack_modes,
3373 .input_mux = &alc880_capture_source,
3376 .mixers = { alc880_lg_mixer },
3377 .init_verbs = { alc880_volume_init_verbs,
3378 alc880_lg_init_verbs },
3379 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3380 .dac_nids = alc880_lg_dac_nids,
3381 .dig_out_nid = ALC880_DIGOUT_NID,
3382 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3383 .channel_mode = alc880_lg_ch_modes,
3385 .input_mux = &alc880_lg_capture_source,
3386 .unsol_event = alc880_lg_unsol_event,
3387 .init_hook = alc880_lg_automute,
3388 #ifdef CONFIG_SND_HDA_POWER_SAVE
3389 .loopbacks = alc880_lg_loopbacks,
3393 .mixers = { alc880_lg_lw_mixer },
3394 .init_verbs = { alc880_volume_init_verbs,
3395 alc880_lg_lw_init_verbs },
3396 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3397 .dac_nids = alc880_dac_nids,
3398 .dig_out_nid = ALC880_DIGOUT_NID,
3399 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3400 .channel_mode = alc880_lg_lw_modes,
3401 .input_mux = &alc880_lg_lw_capture_source,
3402 .unsol_event = alc880_lg_lw_unsol_event,
3403 .init_hook = alc880_lg_lw_automute,
3405 [ALC880_MEDION_RIM] = {
3406 .mixers = { alc880_medion_rim_mixer },
3407 .init_verbs = { alc880_volume_init_verbs,
3408 alc880_medion_rim_init_verbs,
3409 alc_gpio2_init_verbs },
3410 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3411 .dac_nids = alc880_dac_nids,
3412 .dig_out_nid = ALC880_DIGOUT_NID,
3413 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3414 .channel_mode = alc880_2_jack_modes,
3415 .input_mux = &alc880_medion_rim_capture_source,
3416 .unsol_event = alc880_medion_rim_unsol_event,
3417 .init_hook = alc880_medion_rim_automute,
3419 #ifdef CONFIG_SND_DEBUG
3421 .mixers = { alc880_test_mixer },
3422 .init_verbs = { alc880_test_init_verbs },
3423 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3424 .dac_nids = alc880_test_dac_nids,
3425 .dig_out_nid = ALC880_DIGOUT_NID,
3426 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3427 .channel_mode = alc880_test_modes,
3428 .input_mux = &alc880_test_capture_source,
3434 * Automatic parse of I/O pins from the BIOS configuration
3439 ALC_CTL_WIDGET_MUTE,
3442 static struct snd_kcontrol_new alc880_control_templates[] = {
3443 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3444 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3445 HDA_BIND_MUTE(NULL, 0, 0, 0),
3448 /* add dynamic controls */
3449 static int add_control(struct alc_spec *spec, int type, const char *name,
3452 struct snd_kcontrol_new *knew;
3454 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3455 knew = snd_array_new(&spec->kctls);
3458 *knew = alc880_control_templates[type];
3459 knew->name = kstrdup(name, GFP_KERNEL);
3462 knew->private_value = val;
3466 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3467 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3468 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3469 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3470 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3471 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3472 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3473 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3474 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3475 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3476 #define ALC880_PIN_CD_NID 0x1c
3478 /* fill in the dac_nids table from the parsed pin configuration */
3479 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3480 const struct auto_pin_cfg *cfg)
3486 memset(assigned, 0, sizeof(assigned));
3487 spec->multiout.dac_nids = spec->private_dac_nids;
3489 /* check the pins hardwired to audio widget */
3490 for (i = 0; i < cfg->line_outs; i++) {
3491 nid = cfg->line_out_pins[i];
3492 if (alc880_is_fixed_pin(nid)) {
3493 int idx = alc880_fixed_pin_idx(nid);
3494 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3498 /* left pins can be connect to any audio widget */
3499 for (i = 0; i < cfg->line_outs; i++) {
3500 nid = cfg->line_out_pins[i];
3501 if (alc880_is_fixed_pin(nid))
3503 /* search for an empty channel */
3504 for (j = 0; j < cfg->line_outs; j++) {
3506 spec->multiout.dac_nids[i] =
3507 alc880_idx_to_dac(j);
3513 spec->multiout.num_dacs = cfg->line_outs;
3517 /* add playback controls from the parsed DAC table */
3518 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3519 const struct auto_pin_cfg *cfg)
3522 static const char *chname[4] = {
3523 "Front", "Surround", NULL /*CLFE*/, "Side"
3528 for (i = 0; i < cfg->line_outs; i++) {
3529 if (!spec->multiout.dac_nids[i])
3531 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3534 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3535 "Center Playback Volume",
3536 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3540 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3541 "LFE Playback Volume",
3542 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3546 err = add_control(spec, ALC_CTL_BIND_MUTE,
3547 "Center Playback Switch",
3548 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3552 err = add_control(spec, ALC_CTL_BIND_MUTE,
3553 "LFE Playback Switch",
3554 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3559 sprintf(name, "%s Playback Volume", chname[i]);
3560 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3561 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3565 sprintf(name, "%s Playback Switch", chname[i]);
3566 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3567 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3576 /* add playback controls for speaker and HP outputs */
3577 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3587 if (alc880_is_fixed_pin(pin)) {
3588 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3589 /* specify the DAC as the extra output */
3590 if (!spec->multiout.hp_nid)
3591 spec->multiout.hp_nid = nid;
3593 spec->multiout.extra_out_nid[0] = nid;
3594 /* control HP volume/switch on the output mixer amp */
3595 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3596 sprintf(name, "%s Playback Volume", pfx);
3597 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3598 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3601 sprintf(name, "%s Playback Switch", pfx);
3602 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3603 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3606 } else if (alc880_is_multi_pin(pin)) {
3607 /* set manual connection */
3608 /* we have only a switch on HP-out PIN */
3609 sprintf(name, "%s Playback Switch", pfx);
3610 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3611 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3618 /* create input playback/capture controls for the given pin */
3619 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3620 const char *ctlname,
3621 int idx, hda_nid_t mix_nid)
3626 sprintf(name, "%s Playback Volume", ctlname);
3627 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3628 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3631 sprintf(name, "%s Playback Switch", ctlname);
3632 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3633 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3639 /* create playback/capture controls for input pins */
3640 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3641 const struct auto_pin_cfg *cfg)
3643 struct hda_input_mux *imux = &spec->private_imux;
3646 for (i = 0; i < AUTO_PIN_LAST; i++) {
3647 if (alc880_is_input_pin(cfg->input_pins[i])) {
3648 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3649 err = new_analog_input(spec, cfg->input_pins[i],
3650 auto_pin_cfg_labels[i],
3654 imux->items[imux->num_items].label =
3655 auto_pin_cfg_labels[i];
3656 imux->items[imux->num_items].index =
3657 alc880_input_pin_idx(cfg->input_pins[i]);
3664 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3665 unsigned int pin_type)
3667 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3670 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3674 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3675 hda_nid_t nid, int pin_type,
3678 alc_set_pin_output(codec, nid, pin_type);
3679 /* need the manual connection? */
3680 if (alc880_is_multi_pin(nid)) {
3681 struct alc_spec *spec = codec->spec;
3682 int idx = alc880_multi_pin_idx(nid);
3683 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3684 AC_VERB_SET_CONNECT_SEL,
3685 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3689 static int get_pin_type(int line_out_type)
3691 if (line_out_type == AUTO_PIN_HP_OUT)
3697 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3699 struct alc_spec *spec = codec->spec;
3702 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3703 for (i = 0; i < spec->autocfg.line_outs; i++) {
3704 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3705 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3706 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3710 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3712 struct alc_spec *spec = codec->spec;
3715 pin = spec->autocfg.speaker_pins[0];
3716 if (pin) /* connect to front */
3717 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3718 pin = spec->autocfg.hp_pins[0];
3719 if (pin) /* connect to front */
3720 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3723 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3725 struct alc_spec *spec = codec->spec;
3728 for (i = 0; i < AUTO_PIN_LAST; i++) {
3729 hda_nid_t nid = spec->autocfg.input_pins[i];
3730 if (alc880_is_input_pin(nid)) {
3731 snd_hda_codec_write(codec, nid, 0,
3732 AC_VERB_SET_PIN_WIDGET_CONTROL,
3733 i <= AUTO_PIN_FRONT_MIC ?
3734 PIN_VREF80 : PIN_IN);
3735 if (nid != ALC880_PIN_CD_NID)
3736 snd_hda_codec_write(codec, nid, 0,
3737 AC_VERB_SET_AMP_GAIN_MUTE,
3743 /* parse the BIOS configuration and set up the alc_spec */
3744 /* return 1 if successful, 0 if the proper config is not found,
3745 * or a negative error code
3747 static int alc880_parse_auto_config(struct hda_codec *codec)
3749 struct alc_spec *spec = codec->spec;
3751 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3753 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3757 if (!spec->autocfg.line_outs)
3758 return 0; /* can't find valid BIOS pin config */
3760 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3763 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3766 err = alc880_auto_create_extra_out(spec,
3767 spec->autocfg.speaker_pins[0],
3771 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3775 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3779 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3781 if (spec->autocfg.dig_out_pin)
3782 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3783 if (spec->autocfg.dig_in_pin)
3784 spec->dig_in_nid = ALC880_DIGIN_NID;
3786 if (spec->kctls.list)
3787 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3789 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3791 spec->num_mux_defs = 1;
3792 spec->input_mux = &spec->private_imux;
3797 /* additional initialization for auto-configuration model */
3798 static void alc880_auto_init(struct hda_codec *codec)
3800 struct alc_spec *spec = codec->spec;
3801 alc880_auto_init_multi_out(codec);
3802 alc880_auto_init_extra_out(codec);
3803 alc880_auto_init_analog_input(codec);
3804 if (spec->unsol_event)
3805 alc_sku_automute(codec);
3809 * OK, here we have finally the patch for ALC880
3812 static int patch_alc880(struct hda_codec *codec)
3814 struct alc_spec *spec;
3818 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3824 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3827 if (board_config < 0) {
3828 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3829 "trying auto-probe from BIOS...\n");
3830 board_config = ALC880_AUTO;
3833 if (board_config == ALC880_AUTO) {
3834 /* automatic parse from the BIOS config */
3835 err = alc880_parse_auto_config(codec);
3841 "hda_codec: Cannot set up configuration "
3842 "from BIOS. Using 3-stack mode...\n");
3843 board_config = ALC880_3ST;
3847 if (board_config != ALC880_AUTO)
3848 setup_preset(spec, &alc880_presets[board_config]);
3850 spec->stream_name_analog = "ALC880 Analog";
3851 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3852 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3853 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3855 spec->stream_name_digital = "ALC880 Digital";
3856 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3857 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3859 if (!spec->adc_nids && spec->input_mux) {
3860 /* check whether NID 0x07 is valid */
3861 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3863 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3864 if (wcap != AC_WID_AUD_IN) {
3865 spec->adc_nids = alc880_adc_nids_alt;
3866 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3867 spec->mixers[spec->num_mixers] =
3868 alc880_capture_alt_mixer;
3871 spec->adc_nids = alc880_adc_nids;
3872 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3873 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3878 spec->vmaster_nid = 0x0c;
3880 codec->patch_ops = alc_patch_ops;
3881 if (board_config == ALC880_AUTO)
3882 spec->init_hook = alc880_auto_init;
3883 #ifdef CONFIG_SND_HDA_POWER_SAVE
3884 if (!spec->loopback.amplist)
3885 spec->loopback.amplist = alc880_loopbacks;
3896 static hda_nid_t alc260_dac_nids[1] = {
3901 static hda_nid_t alc260_adc_nids[1] = {
3906 static hda_nid_t alc260_adc_nids_alt[1] = {
3911 static hda_nid_t alc260_hp_adc_nids[2] = {
3916 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3917 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3919 static hda_nid_t alc260_dual_adc_nids[2] = {
3924 #define ALC260_DIGOUT_NID 0x03
3925 #define ALC260_DIGIN_NID 0x06
3927 static struct hda_input_mux alc260_capture_source = {
3931 { "Front Mic", 0x1 },
3937 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3938 * headphone jack and the internal CD lines since these are the only pins at
3939 * which audio can appear. For flexibility, also allow the option of
3940 * recording the mixer output on the second ADC (ADC0 doesn't have a
3941 * connection to the mixer output).
3943 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3947 { "Mic/Line", 0x0 },
3949 { "Headphone", 0x2 },
3955 { "Mic/Line", 0x0 },
3957 { "Headphone", 0x2 },
3964 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3965 * the Fujitsu S702x, but jacks are marked differently.
3967 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3974 { "Headphone", 0x5 },
3983 { "Headphone", 0x6 },
3989 * This is just place-holder, so there's something for alc_build_pcms to look
3990 * at when it calculates the maximum number of channels. ALC260 has no mixer
3991 * element which allows changing the channel mode, so the verb list is
3994 static struct hda_channel_mode alc260_modes[1] = {
3999 /* Mixer combinations
4001 * basic: base_output + input + pc_beep + capture
4002 * HP: base_output + input + capture_alt
4003 * HP_3013: hp_3013 + input + capture
4004 * fujitsu: fujitsu + capture
4005 * acer: acer + capture
4008 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4009 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4010 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4011 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4012 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4013 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4014 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4018 static struct snd_kcontrol_new alc260_input_mixer[] = {
4019 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4020 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4021 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4022 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4024 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4025 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4026 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4030 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4031 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4032 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4036 /* update HP, line and mono out pins according to the master switch */
4037 static void alc260_hp_master_update(struct hda_codec *codec,
4038 hda_nid_t hp, hda_nid_t line,
4041 struct alc_spec *spec = codec->spec;
4042 unsigned int val = spec->master_sw ? PIN_HP : 0;
4043 /* change HP and line-out pins */
4044 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4046 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4048 /* mono (speaker) depending on the HP jack sense */
4049 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4050 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4054 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4055 struct snd_ctl_elem_value *ucontrol)
4057 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4058 struct alc_spec *spec = codec->spec;
4059 *ucontrol->value.integer.value = spec->master_sw;
4063 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4064 struct snd_ctl_elem_value *ucontrol)
4066 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4067 struct alc_spec *spec = codec->spec;
4068 int val = !!*ucontrol->value.integer.value;
4069 hda_nid_t hp, line, mono;
4071 if (val == spec->master_sw)
4073 spec->master_sw = val;
4074 hp = (kcontrol->private_value >> 16) & 0xff;
4075 line = (kcontrol->private_value >> 8) & 0xff;
4076 mono = kcontrol->private_value & 0xff;
4077 alc260_hp_master_update(codec, hp, line, mono);
4081 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4083 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4084 .name = "Master Playback Switch",
4085 .info = snd_ctl_boolean_mono_info,
4086 .get = alc260_hp_master_sw_get,
4087 .put = alc260_hp_master_sw_put,
4088 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4090 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4091 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4092 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4093 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4094 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4096 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4100 static struct hda_verb alc260_hp_unsol_verbs[] = {
4101 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4105 static void alc260_hp_automute(struct hda_codec *codec)
4107 struct alc_spec *spec = codec->spec;
4108 unsigned int present;
4110 present = snd_hda_codec_read(codec, 0x10, 0,
4111 AC_VERB_GET_PIN_SENSE, 0);
4112 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4113 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4116 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4118 if ((res >> 26) == ALC880_HP_EVENT)
4119 alc260_hp_automute(codec);
4122 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4125 .name = "Master Playback Switch",
4126 .info = snd_ctl_boolean_mono_info,
4127 .get = alc260_hp_master_sw_get,
4128 .put = alc260_hp_master_sw_put,
4129 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4131 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4132 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4133 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4134 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4135 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4137 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4138 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4142 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4143 .ops = &snd_hda_bind_vol,
4145 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4146 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4147 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4152 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4153 .ops = &snd_hda_bind_sw,
4155 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4156 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4161 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4162 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4163 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4164 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4165 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4169 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4170 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4174 static void alc260_hp_3013_automute(struct hda_codec *codec)
4176 struct alc_spec *spec = codec->spec;
4177 unsigned int present;
4179 present = snd_hda_codec_read(codec, 0x15, 0,
4180 AC_VERB_GET_PIN_SENSE, 0);
4181 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4182 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4185 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4188 if ((res >> 26) == ALC880_HP_EVENT)
4189 alc260_hp_3013_automute(codec);
4192 static void alc260_hp_3012_automute(struct hda_codec *codec)
4194 unsigned int present, bits;
4196 present = snd_hda_codec_read(codec, 0x10, 0,
4197 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4199 bits = present ? 0 : PIN_OUT;
4200 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4202 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4204 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4208 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4211 if ((res >> 26) == ALC880_HP_EVENT)
4212 alc260_hp_3012_automute(codec);
4215 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4216 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4218 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4219 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4220 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4221 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4222 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4223 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4224 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4225 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4226 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4227 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4228 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4229 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4230 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4234 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4235 * versions of the ALC260 don't act on requests to enable mic bias from NID
4236 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4237 * datasheet doesn't mention this restriction. At this stage it's not clear
4238 * whether this behaviour is intentional or is a hardware bug in chip
4239 * revisions available in early 2006. Therefore for now allow the
4240 * "Headphone Jack Mode" control to span all choices, but if it turns out
4241 * that the lack of mic bias for this NID is intentional we could change the
4242 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4244 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4245 * don't appear to make the mic bias available from the "line" jack, even
4246 * though the NID used for this jack (0x14) can supply it. The theory is
4247 * that perhaps Acer have included blocking capacitors between the ALC260
4248 * and the output jack. If this turns out to be the case for all such
4249 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4250 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4252 * The C20x Tablet series have a mono internal speaker which is controlled
4253 * via the chip's Mono sum widget and pin complex, so include the necessary
4254 * controls for such models. On models without a "mono speaker" the control
4255 * won't do anything.
4257 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4258 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4259 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4260 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4261 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4263 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4265 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4266 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4268 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4269 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4270 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4271 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4272 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4273 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4274 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4278 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4279 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4281 static struct snd_kcontrol_new alc260_will_mixer[] = {
4282 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4283 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4285 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4286 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4287 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4288 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4289 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4290 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4291 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4292 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4293 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4297 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4298 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4300 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4301 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4302 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4303 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4304 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4305 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4306 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4307 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4308 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4309 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4310 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4314 /* capture mixer elements */
4315 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4316 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4317 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4318 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4319 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4321 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4322 /* The multiple "Capture Source" controls confuse alsamixer
4323 * So call somewhat different..
4325 /* .name = "Capture Source", */
4326 .name = "Input Source",
4328 .info = alc_mux_enum_info,
4329 .get = alc_mux_enum_get,
4330 .put = alc_mux_enum_put,
4335 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4336 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4337 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4340 /* The multiple "Capture Source" controls confuse alsamixer
4341 * So call somewhat different..
4343 /* .name = "Capture Source", */
4344 .name = "Input Source",
4346 .info = alc_mux_enum_info,
4347 .get = alc_mux_enum_get,
4348 .put = alc_mux_enum_put,
4354 * initialization verbs
4356 static struct hda_verb alc260_init_verbs[] = {
4357 /* Line In pin widget for input */
4358 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4359 /* CD pin widget for input */
4360 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4361 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4362 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4363 /* Mic2 (front panel) pin widget for input and vref at 80% */
4364 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4365 /* LINE-2 is used for line-out in rear */
4366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4367 /* select line-out */
4368 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4370 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4372 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4374 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4375 /* mute capture amp left and right */
4376 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4377 /* set connection select to line in (default select for this ADC) */
4378 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4379 /* mute capture amp left and right */
4380 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4381 /* set connection select to line in (default select for this ADC) */
4382 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4383 /* set vol=0 Line-Out mixer amp left and right */
4384 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4385 /* unmute pin widget amp left and right (no gain on this amp) */
4386 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4387 /* set vol=0 HP mixer amp left and right */
4388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4389 /* unmute pin widget amp left and right (no gain on this amp) */
4390 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4391 /* set vol=0 Mono mixer amp left and right */
4392 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4393 /* unmute pin widget amp left and right (no gain on this amp) */
4394 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4395 /* unmute LINE-2 out pin */
4396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4397 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4400 /* mute analog inputs */
4401 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4405 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4406 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4407 /* mute Front out path */
4408 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4410 /* mute Headphone out path */
4411 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4412 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4413 /* mute Mono out path */
4414 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4415 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4419 #if 0 /* should be identical with alc260_init_verbs? */
4420 static struct hda_verb alc260_hp_init_verbs[] = {
4421 /* Headphone and output */
4422 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4424 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4425 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4426 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4427 /* Mic2 (front panel) pin widget for input and vref at 80% */
4428 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4429 /* Line In pin widget for input */
4430 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4431 /* Line-2 pin widget for output */
4432 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4433 /* CD pin widget for input */
4434 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4435 /* unmute amp left and right */
4436 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4437 /* set connection select to line in (default select for this ADC) */
4438 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4439 /* unmute Line-Out mixer amp left and right (volume = 0) */
4440 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4441 /* mute pin widget amp left and right (no gain on this amp) */
4442 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4443 /* unmute HP mixer amp left and right (volume = 0) */
4444 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4445 /* mute pin widget amp left and right (no gain on this amp) */
4446 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4447 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4450 /* mute analog inputs */
4451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4454 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4455 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4456 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4457 /* Unmute Front out path */
4458 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4459 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4460 /* Unmute Headphone out path */
4461 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4463 /* Unmute Mono out path */
4464 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4465 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4470 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4471 /* Line out and output */
4472 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4474 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4475 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4476 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4477 /* Mic2 (front panel) pin widget for input and vref at 80% */
4478 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4479 /* Line In pin widget for input */
4480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4481 /* Headphone pin widget for output */
4482 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4483 /* CD pin widget for input */
4484 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4485 /* unmute amp left and right */
4486 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4487 /* set connection select to line in (default select for this ADC) */
4488 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4489 /* unmute Line-Out mixer amp left and right (volume = 0) */
4490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4491 /* mute pin widget amp left and right (no gain on this amp) */
4492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4493 /* unmute HP mixer amp left and right (volume = 0) */
4494 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4495 /* mute pin widget amp left and right (no gain on this amp) */
4496 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4497 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4500 /* mute analog inputs */
4501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4506 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4507 /* Unmute Front out path */
4508 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4509 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4510 /* Unmute Headphone out path */
4511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4512 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4513 /* Unmute Mono out path */
4514 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4515 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4519 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4520 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4521 * audio = 0x16, internal speaker = 0x10.
4523 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4524 /* Disable all GPIOs */
4525 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4526 /* Internal speaker is connected to headphone pin */
4527 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4528 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4529 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4530 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4531 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4532 /* Ensure all other unused pins are disabled and muted. */
4533 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4534 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4535 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4536 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4537 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4538 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4542 /* Disable digital (SPDIF) pins */
4543 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4544 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4546 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4547 * when acting as an output.
4549 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4551 /* Start with output sum widgets muted and their output gains at min */
4552 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4553 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4555 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4556 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4557 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4558 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4559 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4560 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4562 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4563 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4564 /* Unmute Line1 pin widget output buffer since it starts as an output.
4565 * If the pin mode is changed by the user the pin mode control will
4566 * take care of enabling the pin's input/output buffers as needed.
4567 * Therefore there's no need to enable the input buffer at this
4570 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4571 /* Unmute input buffer of pin widget used for Line-in (no equiv
4574 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4576 /* Mute capture amp left and right */
4577 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4578 /* Set ADC connection select to match default mixer setting - line
4581 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4583 /* Do the same for the second ADC: mute capture input amp and
4584 * set ADC connection to line in (on mic1 pin)
4586 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4587 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4589 /* Mute all inputs to mixer widget (even unconnected ones) */
4590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4596 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4597 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4602 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4603 * similar laptops (adapted from Fujitsu init verbs).
4605 static struct hda_verb alc260_acer_init_verbs[] = {
4606 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4607 * the headphone jack. Turn this on and rely on the standard mute
4608 * methods whenever the user wants to turn these outputs off.
4610 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4611 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4612 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4613 /* Internal speaker/Headphone jack is connected to Line-out pin */
4614 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4615 /* Internal microphone/Mic jack is connected to Mic1 pin */
4616 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4617 /* Line In jack is connected to Line1 pin */
4618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4619 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4620 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4621 /* Ensure all other unused pins are disabled and muted. */
4622 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4623 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4624 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4625 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4626 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4627 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4628 /* Disable digital (SPDIF) pins */
4629 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4630 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4632 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4633 * bus when acting as outputs.
4635 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4636 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4638 /* Start with output sum widgets muted and their output gains at min */
4639 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4640 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4641 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4642 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4643 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4644 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4645 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4646 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4647 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4649 /* Unmute Line-out pin widget amp left and right
4650 * (no equiv mixer ctrl)
4652 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4653 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4654 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4655 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4656 * inputs. If the pin mode is changed by the user the pin mode control
4657 * will take care of enabling the pin's input/output buffers as needed.
4658 * Therefore there's no need to enable the input buffer at this
4661 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4662 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4664 /* Mute capture amp left and right */
4665 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4666 /* Set ADC connection select to match default mixer setting - mic
4669 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4671 /* Do similar with the second ADC: mute capture input amp and
4672 * set ADC connection to mic to match ALSA's default state.
4674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4675 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4677 /* Mute all inputs to mixer widget (even unconnected ones) */
4678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4679 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4690 static struct hda_verb alc260_will_verbs[] = {
4691 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4692 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4693 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4694 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4695 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4696 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4700 static struct hda_verb alc260_replacer_672v_verbs[] = {
4701 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4702 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4703 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4705 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4706 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4707 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4709 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4713 /* toggle speaker-output according to the hp-jack state */
4714 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4716 unsigned int present;
4718 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4719 present = snd_hda_codec_read(codec, 0x0f, 0,
4720 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4722 snd_hda_codec_write_cache(codec, 0x01, 0,
4723 AC_VERB_SET_GPIO_DATA, 1);
4724 snd_hda_codec_write_cache(codec, 0x0f, 0,
4725 AC_VERB_SET_PIN_WIDGET_CONTROL,
4728 snd_hda_codec_write_cache(codec, 0x01, 0,
4729 AC_VERB_SET_GPIO_DATA, 0);
4730 snd_hda_codec_write_cache(codec, 0x0f, 0,
4731 AC_VERB_SET_PIN_WIDGET_CONTROL,
4736 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4739 if ((res >> 26) == ALC880_HP_EVENT)
4740 alc260_replacer_672v_automute(codec);
4743 static struct hda_verb alc260_hp_dc7600_verbs[] = {
4744 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4745 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4746 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4747 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4748 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4749 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4750 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4751 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4752 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4753 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4757 /* Test configuration for debugging, modelled after the ALC880 test
4760 #ifdef CONFIG_SND_DEBUG
4761 static hda_nid_t alc260_test_dac_nids[1] = {
4764 static hda_nid_t alc260_test_adc_nids[2] = {
4767 /* For testing the ALC260, each input MUX needs its own definition since
4768 * the signal assignments are different. This assumes that the first ADC
4771 static struct hda_input_mux alc260_test_capture_sources[2] = {
4775 { "MIC1 pin", 0x0 },
4776 { "MIC2 pin", 0x1 },
4777 { "LINE1 pin", 0x2 },
4778 { "LINE2 pin", 0x3 },
4780 { "LINE-OUT pin", 0x5 },
4781 { "HP-OUT pin", 0x6 },
4787 { "MIC1 pin", 0x0 },
4788 { "MIC2 pin", 0x1 },
4789 { "LINE1 pin", 0x2 },
4790 { "LINE2 pin", 0x3 },
4793 { "LINE-OUT pin", 0x6 },
4794 { "HP-OUT pin", 0x7 },
4798 static struct snd_kcontrol_new alc260_test_mixer[] = {
4799 /* Output driver widgets */
4800 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4801 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4802 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4803 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4804 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4805 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4807 /* Modes for retasking pin widgets
4808 * Note: the ALC260 doesn't seem to act on requests to enable mic
4809 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4810 * mention this restriction. At this stage it's not clear whether
4811 * this behaviour is intentional or is a hardware bug in chip
4812 * revisions available at least up until early 2006. Therefore for
4813 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4814 * choices, but if it turns out that the lack of mic bias for these
4815 * NIDs is intentional we could change their modes from
4816 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4818 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4819 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4820 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4821 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4822 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4823 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4825 /* Loopback mixer controls */
4826 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4827 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4828 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4829 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4830 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4831 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4832 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4833 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4834 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4835 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4836 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4837 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4838 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4839 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4840 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4841 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4843 /* Controls for GPIO pins, assuming they are configured as outputs */
4844 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4845 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4846 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4847 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4849 /* Switches to allow the digital IO pins to be enabled. The datasheet
4850 * is ambigious as to which NID is which; testing on laptops which
4851 * make this output available should provide clarification.
4853 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4854 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4856 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4857 * this output to turn on an external amplifier.
4859 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4860 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4864 static struct hda_verb alc260_test_init_verbs[] = {
4865 /* Enable all GPIOs as outputs with an initial value of 0 */
4866 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4867 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4868 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4870 /* Enable retasking pins as output, initially without power amp */
4871 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4872 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4873 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4875 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4876 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4878 /* Disable digital (SPDIF) pins initially, but users can enable
4879 * them via a mixer switch. In the case of SPDIF-out, this initverb
4880 * payload also sets the generation to 0, output to be in "consumer"
4881 * PCM format, copyright asserted, no pre-emphasis and no validity
4884 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4885 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4887 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4888 * OUT1 sum bus when acting as an output.
4890 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4891 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4892 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4893 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4895 /* Start with output sum widgets muted and their output gains at min */
4896 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4897 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4898 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4899 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4900 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4901 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4902 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4903 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4904 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4906 /* Unmute retasking pin widget output buffers since the default
4907 * state appears to be output. As the pin mode is changed by the
4908 * user the pin mode control will take care of enabling the pin's
4909 * input/output buffers as needed.
4911 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4912 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4913 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4914 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4915 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4916 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4917 /* Also unmute the mono-out pin widget */
4918 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4920 /* Mute capture amp left and right */
4921 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4922 /* Set ADC connection select to match default mixer setting (mic1
4925 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4927 /* Do the same for the second ADC: mute capture input amp and
4928 * set ADC connection to mic1 pin
4930 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4931 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4933 /* Mute all inputs to mixer widget (even unconnected ones) */
4934 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4935 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4936 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4937 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4938 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4947 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4948 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
4950 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4951 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4954 * for BIOS auto-configuration
4957 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4961 unsigned long vol_val, sw_val;
4965 if (nid >= 0x0f && nid < 0x11) {
4966 nid_vol = nid - 0x7;
4967 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4968 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4969 } else if (nid == 0x11) {
4970 nid_vol = nid - 0x7;
4971 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4972 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4973 } else if (nid >= 0x12 && nid <= 0x15) {
4975 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4976 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4980 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4981 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4984 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4985 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4991 /* add playback controls from the parsed DAC table */
4992 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4993 const struct auto_pin_cfg *cfg)
4998 spec->multiout.num_dacs = 1;
4999 spec->multiout.dac_nids = spec->private_dac_nids;
5000 spec->multiout.dac_nids[0] = 0x02;
5002 nid = cfg->line_out_pins[0];
5004 err = alc260_add_playback_controls(spec, nid, "Front");
5009 nid = cfg->speaker_pins[0];
5011 err = alc260_add_playback_controls(spec, nid, "Speaker");
5016 nid = cfg->hp_pins[0];
5018 err = alc260_add_playback_controls(spec, nid, "Headphone");
5025 /* create playback/capture controls for input pins */
5026 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5027 const struct auto_pin_cfg *cfg)
5029 struct hda_input_mux *imux = &spec->private_imux;
5032 for (i = 0; i < AUTO_PIN_LAST; i++) {
5033 if (cfg->input_pins[i] >= 0x12) {
5034 idx = cfg->input_pins[i] - 0x12;
5035 err = new_analog_input(spec, cfg->input_pins[i],
5036 auto_pin_cfg_labels[i], idx,
5040 imux->items[imux->num_items].label =
5041 auto_pin_cfg_labels[i];
5042 imux->items[imux->num_items].index = idx;
5045 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5046 idx = cfg->input_pins[i] - 0x09;
5047 err = new_analog_input(spec, cfg->input_pins[i],
5048 auto_pin_cfg_labels[i], idx,
5052 imux->items[imux->num_items].label =
5053 auto_pin_cfg_labels[i];
5054 imux->items[imux->num_items].index = idx;
5061 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5062 hda_nid_t nid, int pin_type,
5065 alc_set_pin_output(codec, nid, pin_type);
5066 /* need the manual connection? */
5068 int idx = nid - 0x12;
5069 snd_hda_codec_write(codec, idx + 0x0b, 0,
5070 AC_VERB_SET_CONNECT_SEL, sel_idx);
5074 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5076 struct alc_spec *spec = codec->spec;
5079 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5080 nid = spec->autocfg.line_out_pins[0];
5082 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5083 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5086 nid = spec->autocfg.speaker_pins[0];
5088 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5090 nid = spec->autocfg.hp_pins[0];
5092 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5095 #define ALC260_PIN_CD_NID 0x16
5096 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5098 struct alc_spec *spec = codec->spec;
5101 for (i = 0; i < AUTO_PIN_LAST; i++) {
5102 hda_nid_t nid = spec->autocfg.input_pins[i];
5104 snd_hda_codec_write(codec, nid, 0,
5105 AC_VERB_SET_PIN_WIDGET_CONTROL,
5106 i <= AUTO_PIN_FRONT_MIC ?
5107 PIN_VREF80 : PIN_IN);
5108 if (nid != ALC260_PIN_CD_NID)
5109 snd_hda_codec_write(codec, nid, 0,
5110 AC_VERB_SET_AMP_GAIN_MUTE,
5117 * generic initialization of ADC, input mixers and output mixers
5119 static struct hda_verb alc260_volume_init_verbs[] = {
5121 * Unmute ADC0-1 and set the default input to mic-in
5123 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5124 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5125 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5126 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5128 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5130 * Note: PASD motherboards uses the Line In 2 as the input for
5131 * front panel mic (mic 2)
5133 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5134 /* mute analog inputs */
5135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5142 * Set up output mixers (0x08 - 0x0a)
5144 /* set vol=0 to output mixers */
5145 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5146 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5147 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5148 /* set up input amps for analog loopback */
5149 /* Amp Indices: DAC = 0, mixer = 1 */
5150 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5151 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5153 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5154 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5155 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5160 static int alc260_parse_auto_config(struct hda_codec *codec)
5162 struct alc_spec *spec = codec->spec;
5165 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5167 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5171 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5174 if (!spec->kctls.list)
5175 return 0; /* can't find valid BIOS pin config */
5176 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5180 spec->multiout.max_channels = 2;
5182 if (spec->autocfg.dig_out_pin)
5183 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5184 if (spec->kctls.list)
5185 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5187 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5189 spec->num_mux_defs = 1;
5190 spec->input_mux = &spec->private_imux;
5192 /* check whether NID 0x04 is valid */
5193 wcap = get_wcaps(codec, 0x04);
5194 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5195 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5196 spec->adc_nids = alc260_adc_nids_alt;
5197 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5198 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5200 spec->adc_nids = alc260_adc_nids;
5201 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5202 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5209 /* additional initialization for auto-configuration model */
5210 static void alc260_auto_init(struct hda_codec *codec)
5212 struct alc_spec *spec = codec->spec;
5213 alc260_auto_init_multi_out(codec);
5214 alc260_auto_init_analog_input(codec);
5215 if (spec->unsol_event)
5216 alc_sku_automute(codec);
5219 #ifdef CONFIG_SND_HDA_POWER_SAVE
5220 static struct hda_amp_list alc260_loopbacks[] = {
5221 { 0x07, HDA_INPUT, 0 },
5222 { 0x07, HDA_INPUT, 1 },
5223 { 0x07, HDA_INPUT, 2 },
5224 { 0x07, HDA_INPUT, 3 },
5225 { 0x07, HDA_INPUT, 4 },
5231 * ALC260 configurations
5233 static const char *alc260_models[ALC260_MODEL_LAST] = {
5234 [ALC260_BASIC] = "basic",
5236 [ALC260_HP_3013] = "hp-3013",
5237 [ALC260_HP_DC7600] = "hp-dc7600",
5238 [ALC260_FUJITSU_S702X] = "fujitsu",
5239 [ALC260_ACER] = "acer",
5240 [ALC260_WILL] = "will",
5241 [ALC260_REPLACER_672V] = "replacer",
5242 #ifdef CONFIG_SND_DEBUG
5243 [ALC260_TEST] = "test",
5245 [ALC260_AUTO] = "auto",
5248 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5249 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5250 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5251 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5252 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5253 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5254 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5255 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5256 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5257 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5258 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5259 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5260 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5261 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5262 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5263 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5264 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5265 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5266 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5270 static struct alc_config_preset alc260_presets[] = {
5272 .mixers = { alc260_base_output_mixer,
5274 alc260_pc_beep_mixer,
5275 alc260_capture_mixer },
5276 .init_verbs = { alc260_init_verbs },
5277 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5278 .dac_nids = alc260_dac_nids,
5279 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5280 .adc_nids = alc260_adc_nids,
5281 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5282 .channel_mode = alc260_modes,
5283 .input_mux = &alc260_capture_source,
5286 .mixers = { alc260_hp_output_mixer,
5288 alc260_capture_alt_mixer },
5289 .init_verbs = { alc260_init_verbs,
5290 alc260_hp_unsol_verbs },
5291 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5292 .dac_nids = alc260_dac_nids,
5293 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5294 .adc_nids = alc260_hp_adc_nids,
5295 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5296 .channel_mode = alc260_modes,
5297 .input_mux = &alc260_capture_source,
5298 .unsol_event = alc260_hp_unsol_event,
5299 .init_hook = alc260_hp_automute,
5301 [ALC260_HP_DC7600] = {
5302 .mixers = { alc260_hp_dc7600_mixer,
5304 alc260_capture_alt_mixer },
5305 .init_verbs = { alc260_init_verbs,
5306 alc260_hp_dc7600_verbs },
5307 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5308 .dac_nids = alc260_dac_nids,
5309 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5310 .adc_nids = alc260_hp_adc_nids,
5311 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5312 .channel_mode = alc260_modes,
5313 .input_mux = &alc260_capture_source,
5314 .unsol_event = alc260_hp_3012_unsol_event,
5315 .init_hook = alc260_hp_3012_automute,
5317 [ALC260_HP_3013] = {
5318 .mixers = { alc260_hp_3013_mixer,
5320 alc260_capture_alt_mixer },
5321 .init_verbs = { alc260_hp_3013_init_verbs,
5322 alc260_hp_3013_unsol_verbs },
5323 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5324 .dac_nids = alc260_dac_nids,
5325 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5326 .adc_nids = alc260_hp_adc_nids,
5327 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5328 .channel_mode = alc260_modes,
5329 .input_mux = &alc260_capture_source,
5330 .unsol_event = alc260_hp_3013_unsol_event,
5331 .init_hook = alc260_hp_3013_automute,
5333 [ALC260_FUJITSU_S702X] = {
5334 .mixers = { alc260_fujitsu_mixer,
5335 alc260_capture_mixer },
5336 .init_verbs = { alc260_fujitsu_init_verbs },
5337 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5338 .dac_nids = alc260_dac_nids,
5339 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5340 .adc_nids = alc260_dual_adc_nids,
5341 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5342 .channel_mode = alc260_modes,
5343 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5344 .input_mux = alc260_fujitsu_capture_sources,
5347 .mixers = { alc260_acer_mixer,
5348 alc260_capture_mixer },
5349 .init_verbs = { alc260_acer_init_verbs },
5350 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5351 .dac_nids = alc260_dac_nids,
5352 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5353 .adc_nids = alc260_dual_adc_nids,
5354 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5355 .channel_mode = alc260_modes,
5356 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5357 .input_mux = alc260_acer_capture_sources,
5360 .mixers = { alc260_will_mixer,
5361 alc260_capture_mixer },
5362 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5363 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5364 .dac_nids = alc260_dac_nids,
5365 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5366 .adc_nids = alc260_adc_nids,
5367 .dig_out_nid = ALC260_DIGOUT_NID,
5368 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5369 .channel_mode = alc260_modes,
5370 .input_mux = &alc260_capture_source,
5372 [ALC260_REPLACER_672V] = {
5373 .mixers = { alc260_replacer_672v_mixer,
5374 alc260_capture_mixer },
5375 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5376 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5377 .dac_nids = alc260_dac_nids,
5378 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5379 .adc_nids = alc260_adc_nids,
5380 .dig_out_nid = ALC260_DIGOUT_NID,
5381 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5382 .channel_mode = alc260_modes,
5383 .input_mux = &alc260_capture_source,
5384 .unsol_event = alc260_replacer_672v_unsol_event,
5385 .init_hook = alc260_replacer_672v_automute,
5387 #ifdef CONFIG_SND_DEBUG
5389 .mixers = { alc260_test_mixer,
5390 alc260_capture_mixer },
5391 .init_verbs = { alc260_test_init_verbs },
5392 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5393 .dac_nids = alc260_test_dac_nids,
5394 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5395 .adc_nids = alc260_test_adc_nids,
5396 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5397 .channel_mode = alc260_modes,
5398 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5399 .input_mux = alc260_test_capture_sources,
5404 static int patch_alc260(struct hda_codec *codec)
5406 struct alc_spec *spec;
5407 int err, board_config;
5409 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5415 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5418 if (board_config < 0) {
5419 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5420 "trying auto-probe from BIOS...\n");
5421 board_config = ALC260_AUTO;
5424 if (board_config == ALC260_AUTO) {
5425 /* automatic parse from the BIOS config */
5426 err = alc260_parse_auto_config(codec);
5432 "hda_codec: Cannot set up configuration "
5433 "from BIOS. Using base mode...\n");
5434 board_config = ALC260_BASIC;
5438 if (board_config != ALC260_AUTO)
5439 setup_preset(spec, &alc260_presets[board_config]);
5441 spec->stream_name_analog = "ALC260 Analog";
5442 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5443 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5445 spec->stream_name_digital = "ALC260 Digital";
5446 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5447 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5449 spec->vmaster_nid = 0x08;
5451 codec->patch_ops = alc_patch_ops;
5452 if (board_config == ALC260_AUTO)
5453 spec->init_hook = alc260_auto_init;
5454 #ifdef CONFIG_SND_HDA_POWER_SAVE
5455 if (!spec->loopback.amplist)
5456 spec->loopback.amplist = alc260_loopbacks;
5466 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5467 * configuration. Each pin widget can choose any input DACs and a mixer.
5468 * Each ADC is connected from a mixer of all inputs. This makes possible
5469 * 6-channel independent captures.
5471 * In addition, an independent DAC for the multi-playback (not used in this
5474 #define ALC882_DIGOUT_NID 0x06
5475 #define ALC882_DIGIN_NID 0x0a
5477 static struct hda_channel_mode alc882_ch_modes[1] = {
5481 static hda_nid_t alc882_dac_nids[4] = {
5482 /* front, rear, clfe, rear_surr */
5483 0x02, 0x03, 0x04, 0x05
5486 /* identical with ALC880 */
5487 #define alc882_adc_nids alc880_adc_nids
5488 #define alc882_adc_nids_alt alc880_adc_nids_alt
5490 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5491 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5494 /* FIXME: should be a matrix-type input source selection */
5496 static struct hda_input_mux alc882_capture_source = {
5500 { "Front Mic", 0x1 },
5505 #define alc882_mux_enum_info alc_mux_enum_info
5506 #define alc882_mux_enum_get alc_mux_enum_get
5508 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5509 struct snd_ctl_elem_value *ucontrol)
5511 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5512 struct alc_spec *spec = codec->spec;
5513 const struct hda_input_mux *imux = spec->input_mux;
5514 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5515 hda_nid_t nid = spec->capsrc_nids ?
5516 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5517 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5518 unsigned int i, idx;
5520 idx = ucontrol->value.enumerated.item[0];
5521 if (idx >= imux->num_items)
5522 idx = imux->num_items - 1;
5523 if (*cur_val == idx)
5525 for (i = 0; i < imux->num_items; i++) {
5526 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5527 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5528 imux->items[i].index,
5538 static struct hda_verb alc882_3ST_ch2_init[] = {
5539 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5540 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5541 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5542 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5549 static struct hda_verb alc882_3ST_ch6_init[] = {
5550 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5551 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5552 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5553 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5554 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5555 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5559 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5560 { 2, alc882_3ST_ch2_init },
5561 { 6, alc882_3ST_ch6_init },
5567 static struct hda_verb alc882_sixstack_ch6_init[] = {
5568 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5569 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5570 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5571 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5578 static struct hda_verb alc882_sixstack_ch8_init[] = {
5579 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5580 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5581 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5582 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5586 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5587 { 6, alc882_sixstack_ch6_init },
5588 { 8, alc882_sixstack_ch8_init },
5592 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5598 static struct hda_verb alc885_mbp_ch2_init[] = {
5599 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5600 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5601 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5608 static struct hda_verb alc885_mbp_ch6_init[] = {
5609 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5610 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5611 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5612 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5613 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5617 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5618 { 2, alc885_mbp_ch2_init },
5619 { 6, alc885_mbp_ch6_init },
5623 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5624 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5626 static struct snd_kcontrol_new alc882_base_mixer[] = {
5627 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5628 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5629 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5630 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5631 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5632 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5633 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5634 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5635 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5636 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5638 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5639 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5640 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5641 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5643 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5644 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5645 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5646 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5647 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5648 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5649 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5653 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5654 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5655 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5656 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5657 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5658 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5659 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5661 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5662 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5663 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5666 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5667 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5668 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5669 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5670 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5671 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5672 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5673 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5674 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5675 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5676 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5677 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5681 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5682 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5683 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5685 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5686 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5687 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5688 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5692 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5698 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5699 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5701 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5703 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5705 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5710 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5711 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5712 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5713 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5718 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5720 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5729 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5730 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5734 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5736 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5737 .name = "Channel Mode",
5738 .info = alc_ch_mode_info,
5739 .get = alc_ch_mode_get,
5740 .put = alc_ch_mode_put,
5745 static struct hda_verb alc882_init_verbs[] = {
5746 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5749 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5751 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5752 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5753 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5756 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5759 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5760 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5761 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5763 /* Front Pin: output 0 (0x0c) */
5764 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5766 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5767 /* Rear Pin: output 1 (0x0d) */
5768 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5769 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5770 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5771 /* CLFE Pin: output 2 (0x0e) */
5772 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5773 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5774 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5775 /* Side Pin: output 3 (0x0f) */
5776 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5777 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5778 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5779 /* Mic (rear) pin: input vref at 80% */
5780 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5781 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5782 /* Front Mic pin: input vref at 80% */
5783 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5784 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5785 /* Line In pin: input */
5786 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5787 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5788 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5789 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5790 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5791 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5792 /* CD pin widget for input */
5793 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5795 /* FIXME: use matrix-type input source selection */
5796 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5797 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5798 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5799 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5800 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5801 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5803 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5804 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5805 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5806 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5808 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5809 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5810 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5811 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5812 /* ADC1: mute amp left and right */
5813 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5814 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5815 /* ADC2: mute amp left and right */
5816 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5817 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5818 /* ADC3: mute amp left and right */
5819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5820 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5825 static struct hda_verb alc882_eapd_verbs[] = {
5826 /* change to EAPD mode */
5827 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5828 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5833 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5834 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5835 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5836 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5837 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5838 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5839 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5840 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5844 static struct hda_verb alc882_macpro_init_verbs[] = {
5845 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5847 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5848 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5849 /* Front Pin: output 0 (0x0c) */
5850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5852 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5853 /* Front Mic pin: input vref at 80% */
5854 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5855 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5856 /* Speaker: output */
5857 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5858 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5859 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5860 /* Headphone output (output 0 - 0x0c) */
5861 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5862 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5863 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5865 /* FIXME: use matrix-type input source selection */
5866 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5867 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5868 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5869 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5870 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5871 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5873 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5874 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5875 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5876 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5878 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5880 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5882 /* ADC1: mute amp left and right */
5883 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5884 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5885 /* ADC2: mute amp left and right */
5886 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5887 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5888 /* ADC3: mute amp left and right */
5889 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5890 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5895 /* Macbook Pro rev3 */
5896 static struct hda_verb alc885_mbp3_init_verbs[] = {
5897 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5898 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5899 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5900 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5902 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5903 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5904 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5905 /* Front Pin: output 0 (0x0c) */
5906 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5907 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5908 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5909 /* HP Pin: output 0 (0x0d) */
5910 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5912 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5913 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5914 /* Mic (rear) pin: input vref at 80% */
5915 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5916 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5917 /* Front Mic pin: input vref at 80% */
5918 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5919 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5920 /* Line In pin: use output 1 when in LineOut mode */
5921 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5922 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5923 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5925 /* FIXME: use matrix-type input source selection */
5926 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5927 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5929 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5930 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5931 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5934 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5935 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5936 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5939 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5940 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5941 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5942 /* ADC1: mute amp left and right */
5943 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5944 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5945 /* ADC2: mute amp left and right */
5946 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5947 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5948 /* ADC3: mute amp left and right */
5949 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5950 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5955 /* iMac 24 mixer. */
5956 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5957 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5958 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5962 /* iMac 24 init verbs. */
5963 static struct hda_verb alc885_imac24_init_verbs[] = {
5964 /* Internal speakers: output 0 (0x0c) */
5965 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5966 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5967 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5968 /* Internal speakers: output 0 (0x0c) */
5969 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5970 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5971 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5972 /* Headphone: output 0 (0x0c) */
5973 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5974 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5975 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5976 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5977 /* Front Mic: input vref at 80% */
5978 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5979 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5983 /* Toggle speaker-output according to the hp-jack state */
5984 static void alc885_imac24_automute(struct hda_codec *codec)
5986 unsigned int present;
5988 present = snd_hda_codec_read(codec, 0x14, 0,
5989 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5990 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5991 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5992 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5993 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5996 /* Processes unsolicited events. */
5997 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6000 /* Headphone insertion or removal. */
6001 if ((res >> 26) == ALC880_HP_EVENT)
6002 alc885_imac24_automute(codec);
6005 static void alc885_mbp3_automute(struct hda_codec *codec)
6007 unsigned int present;
6009 present = snd_hda_codec_read(codec, 0x15, 0,
6010 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6011 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6012 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6013 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6014 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6017 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6020 /* Headphone insertion or removal. */
6021 if ((res >> 26) == ALC880_HP_EVENT)
6022 alc885_mbp3_automute(codec);
6026 static struct hda_verb alc882_targa_verbs[] = {
6027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6028 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6030 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6031 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6033 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6034 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6035 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6037 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6038 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6039 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6040 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6044 /* toggle speaker-output according to the hp-jack state */
6045 static void alc882_targa_automute(struct hda_codec *codec)
6047 unsigned int present;
6049 present = snd_hda_codec_read(codec, 0x14, 0,
6050 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6051 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6052 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6053 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6057 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6059 /* Looks like the unsol event is incompatible with the standard
6060 * definition. 4bit tag is placed at 26 bit!
6062 if (((res >> 26) == ALC880_HP_EVENT)) {
6063 alc882_targa_automute(codec);
6067 static struct hda_verb alc882_asus_a7j_verbs[] = {
6068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6071 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6072 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6073 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6075 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6076 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6077 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6079 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6080 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6081 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6085 static struct hda_verb alc882_asus_a7m_verbs[] = {
6086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6087 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6089 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6091 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6093 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6094 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6095 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6097 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6098 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6099 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6103 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6105 unsigned int gpiostate, gpiomask, gpiodir;
6107 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6108 AC_VERB_GET_GPIO_DATA, 0);
6111 gpiostate |= (1 << pin);
6113 gpiostate &= ~(1 << pin);
6115 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6116 AC_VERB_GET_GPIO_MASK, 0);
6117 gpiomask |= (1 << pin);
6119 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6120 AC_VERB_GET_GPIO_DIRECTION, 0);
6121 gpiodir |= (1 << pin);
6124 snd_hda_codec_write(codec, codec->afg, 0,
6125 AC_VERB_SET_GPIO_MASK, gpiomask);
6126 snd_hda_codec_write(codec, codec->afg, 0,
6127 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6131 snd_hda_codec_write(codec, codec->afg, 0,
6132 AC_VERB_SET_GPIO_DATA, gpiostate);
6135 /* set up GPIO at initialization */
6136 static void alc885_macpro_init_hook(struct hda_codec *codec)
6138 alc882_gpio_mute(codec, 0, 0);
6139 alc882_gpio_mute(codec, 1, 0);
6142 /* set up GPIO and update auto-muting at initialization */
6143 static void alc885_imac24_init_hook(struct hda_codec *codec)
6145 alc885_macpro_init_hook(codec);
6146 alc885_imac24_automute(codec);
6150 * generic initialization of ADC, input mixers and output mixers
6152 static struct hda_verb alc882_auto_init_verbs[] = {
6154 * Unmute ADC0-2 and set the default input to mic-in
6156 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6158 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6159 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6160 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6161 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6163 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6165 * Note: PASD motherboards uses the Line In 2 as the input for
6166 * front panel mic (mic 2)
6168 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6170 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6171 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6172 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6176 * Set up output mixers (0x0c - 0x0f)
6178 /* set vol=0 to output mixers */
6179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6180 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6182 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6183 /* set up input amps for analog loopback */
6184 /* Amp Indices: DAC = 0, mixer = 1 */
6185 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6187 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6188 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6189 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6190 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6191 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6192 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6193 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6194 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6196 /* FIXME: use matrix-type input source selection */
6197 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6198 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6201 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6202 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6204 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6205 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6206 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6207 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6209 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6210 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6211 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6212 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6217 /* capture mixer elements */
6218 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6219 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6220 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6221 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6222 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6224 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6225 /* The multiple "Capture Source" controls confuse alsamixer
6226 * So call somewhat different..
6228 /* .name = "Capture Source", */
6229 .name = "Input Source",
6231 .info = alc882_mux_enum_info,
6232 .get = alc882_mux_enum_get,
6233 .put = alc882_mux_enum_put,
6238 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6239 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6240 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6241 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6242 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6243 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6244 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6246 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6247 /* The multiple "Capture Source" controls confuse alsamixer
6248 * So call somewhat different..
6250 /* .name = "Capture Source", */
6251 .name = "Input Source",
6253 .info = alc882_mux_enum_info,
6254 .get = alc882_mux_enum_get,
6255 .put = alc882_mux_enum_put,
6260 #ifdef CONFIG_SND_HDA_POWER_SAVE
6261 #define alc882_loopbacks alc880_loopbacks
6264 /* pcm configuration: identiacal with ALC880 */
6265 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6266 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6267 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6268 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6271 * configuration and preset
6273 static const char *alc882_models[ALC882_MODEL_LAST] = {
6274 [ALC882_3ST_DIG] = "3stack-dig",
6275 [ALC882_6ST_DIG] = "6stack-dig",
6276 [ALC882_ARIMA] = "arima",
6277 [ALC882_W2JC] = "w2jc",
6278 [ALC882_TARGA] = "targa",
6279 [ALC882_ASUS_A7J] = "asus-a7j",
6280 [ALC882_ASUS_A7M] = "asus-a7m",
6281 [ALC885_MACPRO] = "macpro",
6282 [ALC885_MBP3] = "mbp3",
6283 [ALC885_IMAC24] = "imac24",
6284 [ALC882_AUTO] = "auto",
6287 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6288 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6289 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6290 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6291 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6292 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6293 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6294 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6295 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6296 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6297 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6298 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6299 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6303 static struct alc_config_preset alc882_presets[] = {
6304 [ALC882_3ST_DIG] = {
6305 .mixers = { alc882_base_mixer },
6306 .init_verbs = { alc882_init_verbs },
6307 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6308 .dac_nids = alc882_dac_nids,
6309 .dig_out_nid = ALC882_DIGOUT_NID,
6310 .dig_in_nid = ALC882_DIGIN_NID,
6311 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6312 .channel_mode = alc882_ch_modes,
6314 .input_mux = &alc882_capture_source,
6316 [ALC882_6ST_DIG] = {
6317 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6318 .init_verbs = { alc882_init_verbs },
6319 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6320 .dac_nids = alc882_dac_nids,
6321 .dig_out_nid = ALC882_DIGOUT_NID,
6322 .dig_in_nid = ALC882_DIGIN_NID,
6323 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6324 .channel_mode = alc882_sixstack_modes,
6325 .input_mux = &alc882_capture_source,
6328 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6329 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6330 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6331 .dac_nids = alc882_dac_nids,
6332 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6333 .channel_mode = alc882_sixstack_modes,
6334 .input_mux = &alc882_capture_source,
6337 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6338 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6339 alc880_gpio1_init_verbs },
6340 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6341 .dac_nids = alc882_dac_nids,
6342 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6343 .channel_mode = alc880_threestack_modes,
6345 .input_mux = &alc882_capture_source,
6346 .dig_out_nid = ALC882_DIGOUT_NID,
6349 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6350 .init_verbs = { alc885_mbp3_init_verbs,
6351 alc880_gpio1_init_verbs },
6352 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6353 .dac_nids = alc882_dac_nids,
6354 .channel_mode = alc885_mbp_6ch_modes,
6355 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6356 .input_mux = &alc882_capture_source,
6357 .dig_out_nid = ALC882_DIGOUT_NID,
6358 .dig_in_nid = ALC882_DIGIN_NID,
6359 .unsol_event = alc885_mbp3_unsol_event,
6360 .init_hook = alc885_mbp3_automute,
6363 .mixers = { alc882_macpro_mixer },
6364 .init_verbs = { alc882_macpro_init_verbs },
6365 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6366 .dac_nids = alc882_dac_nids,
6367 .dig_out_nid = ALC882_DIGOUT_NID,
6368 .dig_in_nid = ALC882_DIGIN_NID,
6369 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6370 .channel_mode = alc882_ch_modes,
6371 .input_mux = &alc882_capture_source,
6372 .init_hook = alc885_macpro_init_hook,
6375 .mixers = { alc885_imac24_mixer },
6376 .init_verbs = { alc885_imac24_init_verbs },
6377 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6378 .dac_nids = alc882_dac_nids,
6379 .dig_out_nid = ALC882_DIGOUT_NID,
6380 .dig_in_nid = ALC882_DIGIN_NID,
6381 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6382 .channel_mode = alc882_ch_modes,
6383 .input_mux = &alc882_capture_source,
6384 .unsol_event = alc885_imac24_unsol_event,
6385 .init_hook = alc885_imac24_init_hook,
6388 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6389 alc882_capture_mixer },
6390 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6391 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6392 .dac_nids = alc882_dac_nids,
6393 .dig_out_nid = ALC882_DIGOUT_NID,
6394 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6395 .adc_nids = alc882_adc_nids,
6396 .capsrc_nids = alc882_capsrc_nids,
6397 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6398 .channel_mode = alc882_3ST_6ch_modes,
6400 .input_mux = &alc882_capture_source,
6401 .unsol_event = alc882_targa_unsol_event,
6402 .init_hook = alc882_targa_automute,
6404 [ALC882_ASUS_A7J] = {
6405 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6406 alc882_capture_mixer },
6407 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6408 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6409 .dac_nids = alc882_dac_nids,
6410 .dig_out_nid = ALC882_DIGOUT_NID,
6411 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6412 .adc_nids = alc882_adc_nids,
6413 .capsrc_nids = alc882_capsrc_nids,
6414 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6415 .channel_mode = alc882_3ST_6ch_modes,
6417 .input_mux = &alc882_capture_source,
6419 [ALC882_ASUS_A7M] = {
6420 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6421 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6422 alc880_gpio1_init_verbs,
6423 alc882_asus_a7m_verbs },
6424 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6425 .dac_nids = alc882_dac_nids,
6426 .dig_out_nid = ALC882_DIGOUT_NID,
6427 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6428 .channel_mode = alc880_threestack_modes,
6430 .input_mux = &alc882_capture_source,
6439 PINFIX_ABIT_AW9D_MAX
6442 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6443 { 0x15, 0x01080104 }, /* side */
6444 { 0x16, 0x01011012 }, /* rear */
6445 { 0x17, 0x01016011 }, /* clfe */
6449 static const struct alc_pincfg *alc882_pin_fixes[] = {
6450 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6453 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6454 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6459 * BIOS auto configuration
6461 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6462 hda_nid_t nid, int pin_type,
6466 struct alc_spec *spec = codec->spec;
6469 alc_set_pin_output(codec, nid, pin_type);
6470 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6473 idx = spec->multiout.dac_nids[dac_idx] - 2;
6474 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6478 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6480 struct alc_spec *spec = codec->spec;
6483 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6484 for (i = 0; i <= HDA_SIDE; i++) {
6485 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6486 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6488 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6493 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6495 struct alc_spec *spec = codec->spec;
6498 pin = spec->autocfg.hp_pins[0];
6499 if (pin) /* connect to front */
6501 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6502 pin = spec->autocfg.speaker_pins[0];
6504 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6507 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6508 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6510 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6512 struct alc_spec *spec = codec->spec;
6515 for (i = 0; i < AUTO_PIN_LAST; i++) {
6516 hda_nid_t nid = spec->autocfg.input_pins[i];
6521 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6522 unsigned int pincap;
6523 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6524 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6528 snd_hda_codec_write(codec, nid, 0,
6529 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6530 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6531 snd_hda_codec_write(codec, nid, 0,
6532 AC_VERB_SET_AMP_GAIN_MUTE,
6537 static void alc882_auto_init_input_src(struct hda_codec *codec)
6539 struct alc_spec *spec = codec->spec;
6540 const struct hda_input_mux *imux = spec->input_mux;
6543 for (c = 0; c < spec->num_adc_nids; c++) {
6544 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6545 hda_nid_t nid = spec->capsrc_nids[c];
6546 int conns, mute, idx, item;
6548 conns = snd_hda_get_connections(codec, nid, conn_list,
6549 ARRAY_SIZE(conn_list));
6552 for (idx = 0; idx < conns; idx++) {
6553 /* if the current connection is the selected one,
6554 * unmute it as default - otherwise mute it
6556 mute = AMP_IN_MUTE(idx);
6557 for (item = 0; item < imux->num_items; item++) {
6558 if (imux->items[item].index == idx) {
6559 if (spec->cur_mux[c] == item)
6560 mute = AMP_IN_UNMUTE(idx);
6564 snd_hda_codec_write(codec, nid, 0,
6565 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6570 /* add mic boosts if needed */
6571 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6573 struct alc_spec *spec = codec->spec;
6577 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6578 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6579 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6581 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6585 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6586 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6587 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6589 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6596 /* almost identical with ALC880 parser... */
6597 static int alc882_parse_auto_config(struct hda_codec *codec)
6599 struct alc_spec *spec = codec->spec;
6600 int err = alc880_parse_auto_config(codec);
6605 return 0; /* no config found */
6607 err = alc_auto_add_mic_boost(codec);
6611 /* hack - override the init verbs */
6612 spec->init_verbs[0] = alc882_auto_init_verbs;
6614 return 1; /* config found */
6617 /* additional initialization for auto-configuration model */
6618 static void alc882_auto_init(struct hda_codec *codec)
6620 struct alc_spec *spec = codec->spec;
6621 alc882_auto_init_multi_out(codec);
6622 alc882_auto_init_hp_out(codec);
6623 alc882_auto_init_analog_input(codec);
6624 alc882_auto_init_input_src(codec);
6625 if (spec->unsol_event)
6626 alc_sku_automute(codec);
6629 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6631 static int patch_alc882(struct hda_codec *codec)
6633 struct alc_spec *spec;
6634 int err, board_config;
6636 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6642 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6646 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6647 /* Pick up systems that don't supply PCI SSID */
6648 switch (codec->subsystem_id) {
6649 case 0x106b0c00: /* Mac Pro */
6650 board_config = ALC885_MACPRO;
6652 case 0x106b1000: /* iMac 24 */
6653 case 0x106b2800: /* AppleTV */
6654 board_config = ALC885_IMAC24;
6656 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6657 case 0x106b00a4: /* MacbookPro4,1 */
6658 case 0x106b2c00: /* Macbook Pro rev3 */
6659 case 0x106b3600: /* Macbook 3.1 */
6660 board_config = ALC885_MBP3;
6663 /* ALC889A is handled better as ALC888-compatible */
6664 if (codec->revision_id == 0x100101 ||
6665 codec->revision_id == 0x100103) {
6667 return patch_alc883(codec);
6669 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6670 "trying auto-probe from BIOS...\n");
6671 board_config = ALC882_AUTO;
6675 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6677 if (board_config == ALC882_AUTO) {
6678 /* automatic parse from the BIOS config */
6679 err = alc882_parse_auto_config(codec);
6685 "hda_codec: Cannot set up configuration "
6686 "from BIOS. Using base mode...\n");
6687 board_config = ALC882_3ST_DIG;
6691 if (board_config != ALC882_AUTO)
6692 setup_preset(spec, &alc882_presets[board_config]);
6694 if (codec->vendor_id == 0x10ec0885) {
6695 spec->stream_name_analog = "ALC885 Analog";
6696 spec->stream_name_digital = "ALC885 Digital";
6698 spec->stream_name_analog = "ALC882 Analog";
6699 spec->stream_name_digital = "ALC882 Digital";
6702 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6703 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6704 /* FIXME: setup DAC5 */
6705 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6706 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6708 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6709 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6711 if (!spec->adc_nids && spec->input_mux) {
6712 /* check whether NID 0x07 is valid */
6713 unsigned int wcap = get_wcaps(codec, 0x07);
6715 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6716 if (wcap != AC_WID_AUD_IN) {
6717 spec->adc_nids = alc882_adc_nids_alt;
6718 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6719 spec->capsrc_nids = alc882_capsrc_nids_alt;
6720 spec->mixers[spec->num_mixers] =
6721 alc882_capture_alt_mixer;
6724 spec->adc_nids = alc882_adc_nids;
6725 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6726 spec->capsrc_nids = alc882_capsrc_nids;
6727 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6732 spec->vmaster_nid = 0x0c;
6734 codec->patch_ops = alc_patch_ops;
6735 if (board_config == ALC882_AUTO)
6736 spec->init_hook = alc882_auto_init;
6737 #ifdef CONFIG_SND_HDA_POWER_SAVE
6738 if (!spec->loopback.amplist)
6739 spec->loopback.amplist = alc882_loopbacks;
6748 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6749 * configuration. Each pin widget can choose any input DACs and a mixer.
6750 * Each ADC is connected from a mixer of all inputs. This makes possible
6751 * 6-channel independent captures.
6753 * In addition, an independent DAC for the multi-playback (not used in this
6756 #define ALC883_DIGOUT_NID 0x06
6757 #define ALC883_DIGIN_NID 0x0a
6759 static hda_nid_t alc883_dac_nids[4] = {
6760 /* front, rear, clfe, rear_surr */
6761 0x02, 0x03, 0x04, 0x05
6764 static hda_nid_t alc883_adc_nids[2] = {
6769 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6772 /* FIXME: should be a matrix-type input source selection */
6774 static struct hda_input_mux alc883_capture_source = {
6778 { "Front Mic", 0x1 },
6784 static struct hda_input_mux alc883_3stack_6ch_intel = {
6788 { "Front Mic", 0x0 },
6794 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6802 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6812 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6820 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6824 { "Front Mic", 0x1 },
6829 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6837 #define alc883_mux_enum_info alc_mux_enum_info
6838 #define alc883_mux_enum_get alc_mux_enum_get
6839 /* ALC883 has the ALC882-type input selection */
6840 #define alc883_mux_enum_put alc882_mux_enum_put
6845 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6852 static struct hda_verb alc883_3ST_ch2_init[] = {
6853 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6854 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6855 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6856 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6863 static struct hda_verb alc883_3ST_ch4_init[] = {
6864 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6865 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6866 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6867 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6868 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6875 static struct hda_verb alc883_3ST_ch6_init[] = {
6876 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6877 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6878 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6879 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6880 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6881 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6885 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6886 { 2, alc883_3ST_ch2_init },
6887 { 4, alc883_3ST_ch4_init },
6888 { 6, alc883_3ST_ch6_init },
6894 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6895 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6896 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6897 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6898 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6905 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6906 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6907 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6908 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6909 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6910 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6917 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6918 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6919 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6920 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6921 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6922 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6923 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6927 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6928 { 2, alc883_3ST_ch2_intel_init },
6929 { 4, alc883_3ST_ch4_intel_init },
6930 { 6, alc883_3ST_ch6_intel_init },
6936 static struct hda_verb alc883_sixstack_ch6_init[] = {
6937 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6938 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6939 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6940 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6947 static struct hda_verb alc883_sixstack_ch8_init[] = {
6948 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6949 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6950 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6951 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6955 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6956 { 6, alc883_sixstack_ch6_init },
6957 { 8, alc883_sixstack_ch8_init },
6960 static struct hda_verb alc883_medion_eapd_verbs[] = {
6961 /* eanable EAPD on medion laptop */
6962 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6963 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6967 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6968 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6971 static struct snd_kcontrol_new alc883_base_mixer[] = {
6972 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6973 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6974 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6975 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6976 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6977 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6978 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6979 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6980 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6981 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6982 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6983 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6984 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6985 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6986 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6988 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6989 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6990 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6991 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6992 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6993 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6994 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6995 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6996 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6997 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6998 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7000 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7001 /* .name = "Capture Source", */
7002 .name = "Input Source",
7004 .info = alc883_mux_enum_info,
7005 .get = alc883_mux_enum_get,
7006 .put = alc883_mux_enum_put,
7011 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7012 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7014 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7015 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7016 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7017 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7018 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7020 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7021 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7022 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7023 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7024 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7025 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7026 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7027 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7028 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7031 /* .name = "Capture Source", */
7032 .name = "Input Source",
7034 .info = alc883_mux_enum_info,
7035 .get = alc883_mux_enum_get,
7036 .put = alc883_mux_enum_put,
7041 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7042 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7043 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7044 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7045 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7047 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7049 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7050 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7051 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7052 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7053 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7054 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7055 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7057 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7058 /* .name = "Capture Source", */
7059 .name = "Input Source",
7061 .info = alc883_mux_enum_info,
7062 .get = alc883_mux_enum_get,
7063 .put = alc883_mux_enum_put,
7068 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7069 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7070 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7071 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7072 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7073 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7074 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7075 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7076 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7077 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7078 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7079 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7080 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7081 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7082 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7084 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7085 /* .name = "Capture Source", */
7086 .name = "Input Source",
7088 .info = alc883_mux_enum_info,
7089 .get = alc883_mux_enum_get,
7090 .put = alc883_mux_enum_put,
7095 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7096 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7097 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7099 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7100 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7104 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7106 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7107 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7108 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7109 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7110 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7111 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7112 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7113 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7114 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7117 /* .name = "Capture Source", */
7118 .name = "Input Source",
7120 .info = alc883_mux_enum_info,
7121 .get = alc883_mux_enum_get,
7122 .put = alc883_mux_enum_put,
7127 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7128 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7129 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7130 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7131 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7132 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7133 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7134 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7135 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7137 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7138 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7139 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7140 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7142 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7145 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7146 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7147 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7148 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7149 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7150 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7152 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7153 /* .name = "Capture Source", */
7154 .name = "Input Source",
7156 .info = alc883_mux_enum_info,
7157 .get = alc883_mux_enum_get,
7158 .put = alc883_mux_enum_put,
7163 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7166 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7167 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7168 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7170 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7171 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7172 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7174 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7175 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7176 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7177 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7179 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7181 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7182 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7183 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7184 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7185 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7186 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7187 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7188 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7189 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7192 /* .name = "Capture Source", */
7193 .name = "Input Source",
7195 .info = alc883_mux_enum_info,
7196 .get = alc883_mux_enum_get,
7197 .put = alc883_mux_enum_put,
7202 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7204 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7205 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7206 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7207 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7212 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7213 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7217 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7220 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7222 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7223 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7224 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7225 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7228 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7229 /* .name = "Capture Source", */
7230 .name = "Input Source",
7232 .info = alc883_mux_enum_info,
7233 .get = alc883_mux_enum_get,
7234 .put = alc883_mux_enum_put,
7239 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7241 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7242 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7243 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7244 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7245 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7246 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7247 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7248 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7249 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7250 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7254 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7256 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7257 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7258 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7259 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7262 /* .name = "Capture Source", */
7263 .name = "Input Source",
7265 .info = alc883_mux_enum_info,
7266 .get = alc883_mux_enum_get,
7267 .put = alc883_mux_enum_put,
7272 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7273 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7274 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7275 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7279 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7280 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7281 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7282 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7283 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7284 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7285 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7286 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7287 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7289 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7290 /* .name = "Capture Source", */
7291 .name = "Input Source",
7293 .info = alc883_mux_enum_info,
7294 .get = alc883_mux_enum_get,
7295 .put = alc883_mux_enum_put,
7300 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7301 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7302 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7303 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7304 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7305 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7306 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7307 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7308 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7309 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7310 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7312 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7313 /* .name = "Capture Source", */
7314 .name = "Input Source",
7316 .info = alc883_mux_enum_info,
7317 .get = alc883_mux_enum_get,
7318 .put = alc883_mux_enum_put,
7323 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7324 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7325 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7327 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7328 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7329 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7331 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7332 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7333 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7334 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7335 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7336 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7339 /* .name = "Capture Source", */
7340 .name = "Input Source",
7342 .info = alc883_mux_enum_info,
7343 .get = alc883_mux_enum_get,
7344 .put = alc883_mux_enum_put,
7349 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7350 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7352 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7353 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7354 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7355 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7356 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7359 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7360 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7361 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7362 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7364 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7365 /* .name = "Capture Source", */
7366 .name = "Input Source",
7368 .info = alc883_mux_enum_info,
7369 .get = alc883_mux_enum_get,
7370 .put = alc883_mux_enum_put,
7375 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7376 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7377 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7378 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7379 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7380 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7382 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7384 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7385 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7386 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7387 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7390 /* .name = "Capture Source", */
7391 .name = "Input Source",
7393 .info = alc883_mux_enum_info,
7394 .get = alc883_mux_enum_get,
7395 .put = alc883_mux_enum_put,
7400 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7401 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7402 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7403 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7404 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7405 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7406 0x0d, 1, 0x0, HDA_OUTPUT),
7407 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7408 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7409 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7410 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7411 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7412 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7413 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7414 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7415 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7416 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7417 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7419 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7421 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7422 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7423 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7424 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7425 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7426 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7427 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7430 /* .name = "Capture Source", */
7431 .name = "Input Source",
7433 .info = alc883_mux_enum_info,
7434 .get = alc883_mux_enum_get,
7435 .put = alc883_mux_enum_put,
7440 static struct hda_bind_ctls alc883_bind_cap_vol = {
7441 .ops = &snd_hda_bind_vol,
7443 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7444 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7449 static struct hda_bind_ctls alc883_bind_cap_switch = {
7450 .ops = &snd_hda_bind_sw,
7452 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7453 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7458 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7459 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7460 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7461 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7465 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7467 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7468 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7471 /* .name = "Capture Source", */
7472 .name = "Input Source",
7474 .info = alc883_mux_enum_info,
7475 .get = alc883_mux_enum_get,
7476 .put = alc883_mux_enum_put,
7481 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7483 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7484 .name = "Channel Mode",
7485 .info = alc_ch_mode_info,
7486 .get = alc_ch_mode_get,
7487 .put = alc_ch_mode_put,
7492 static struct hda_verb alc883_init_verbs[] = {
7493 /* ADC1: mute amp left and right */
7494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7495 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7496 /* ADC2: mute amp left and right */
7497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7498 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7499 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7500 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7512 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7513 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7516 /* mute analog input loopbacks */
7517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7523 /* Front Pin: output 0 (0x0c) */
7524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7527 /* Rear Pin: output 1 (0x0d) */
7528 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7529 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7530 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7531 /* CLFE Pin: output 2 (0x0e) */
7532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7533 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7534 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7535 /* Side Pin: output 3 (0x0f) */
7536 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7537 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7538 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7539 /* Mic (rear) pin: input vref at 80% */
7540 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7542 /* Front Mic pin: input vref at 80% */
7543 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7544 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7545 /* Line In pin: input */
7546 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7547 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7548 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7549 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7550 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7551 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7552 /* CD pin widget for input */
7553 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7555 /* FIXME: use matrix-type input source selection */
7556 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7558 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7565 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7570 /* toggle speaker-output according to the hp-jack state */
7571 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7573 unsigned int present;
7575 present = snd_hda_codec_read(codec, 0x15, 0,
7576 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7577 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7578 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7579 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7580 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7583 /* auto-toggle front mic */
7585 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7587 unsigned int present;
7590 present = snd_hda_codec_read(codec, 0x18, 0,
7591 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7592 bits = present ? HDA_AMP_MUTE : 0;
7593 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7597 static void alc883_mitac_automute(struct hda_codec *codec)
7599 alc883_mitac_hp_automute(codec);
7600 /* alc883_mitac_mic_automute(codec); */
7603 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7606 switch (res >> 26) {
7607 case ALC880_HP_EVENT:
7608 alc883_mitac_hp_automute(codec);
7610 case ALC880_MIC_EVENT:
7611 /* alc883_mitac_mic_automute(codec); */
7616 static struct hda_verb alc883_mitac_verbs[] = {
7618 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7619 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7621 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7622 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7624 /* enable unsolicited event */
7625 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7626 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7631 static struct hda_verb alc883_clevo_m720_verbs[] = {
7633 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7634 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7636 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7637 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7639 /* enable unsolicited event */
7640 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7641 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7646 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7648 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7649 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7651 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7654 /* enable unsolicited event */
7655 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7660 static struct hda_verb alc883_tagra_verbs[] = {
7661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7664 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7665 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7667 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7668 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7669 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7671 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7672 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7673 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7674 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7679 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7680 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7681 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7682 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7686 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7687 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7689 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7690 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7694 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7698 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7699 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7703 static struct hda_verb alc883_haier_w66_verbs[] = {
7704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7709 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7710 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7711 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7712 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7716 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7719 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7720 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7721 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7722 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7723 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7724 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7728 static struct hda_verb alc888_3st_hp_verbs[] = {
7729 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7730 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7731 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7735 static struct hda_verb alc888_6st_dell_verbs[] = {
7736 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7740 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7741 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7742 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7743 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7744 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7748 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7749 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7750 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7751 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7756 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7757 { 2, alc888_3st_hp_2ch_init },
7758 { 6, alc888_3st_hp_6ch_init },
7761 /* toggle front-jack and RCA according to the hp-jack state */
7762 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7764 unsigned int present;
7766 present = snd_hda_codec_read(codec, 0x1b, 0,
7767 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7768 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7769 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7770 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7771 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7774 /* toggle RCA according to the front-jack state */
7775 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7777 unsigned int present;
7779 present = snd_hda_codec_read(codec, 0x14, 0,
7780 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7781 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7782 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7785 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7788 if ((res >> 26) == ALC880_HP_EVENT)
7789 alc888_lenovo_ms7195_front_automute(codec);
7790 if ((res >> 26) == ALC880_FRONT_EVENT)
7791 alc888_lenovo_ms7195_rca_automute(codec);
7794 static struct hda_verb alc883_medion_md2_verbs[] = {
7795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7798 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7800 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7804 /* toggle speaker-output according to the hp-jack state */
7805 static void alc883_medion_md2_automute(struct hda_codec *codec)
7807 unsigned int present;
7809 present = snd_hda_codec_read(codec, 0x14, 0,
7810 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7811 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7812 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7815 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7818 if ((res >> 26) == ALC880_HP_EVENT)
7819 alc883_medion_md2_automute(codec);
7822 /* toggle speaker-output according to the hp-jack state */
7823 static void alc883_tagra_automute(struct hda_codec *codec)
7825 unsigned int present;
7828 present = snd_hda_codec_read(codec, 0x14, 0,
7829 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7830 bits = present ? HDA_AMP_MUTE : 0;
7831 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7832 HDA_AMP_MUTE, bits);
7833 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7837 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7839 if ((res >> 26) == ALC880_HP_EVENT)
7840 alc883_tagra_automute(codec);
7843 /* toggle speaker-output according to the hp-jack state */
7844 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7846 unsigned int present;
7849 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7850 & AC_PINSENSE_PRESENCE;
7851 bits = present ? HDA_AMP_MUTE : 0;
7852 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7853 HDA_AMP_MUTE, bits);
7856 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7858 unsigned int present;
7860 present = snd_hda_codec_read(codec, 0x18, 0,
7861 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7862 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7863 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7866 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7868 alc883_clevo_m720_hp_automute(codec);
7869 alc883_clevo_m720_mic_automute(codec);
7872 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7875 switch (res >> 26) {
7876 case ALC880_HP_EVENT:
7877 alc883_clevo_m720_hp_automute(codec);
7879 case ALC880_MIC_EVENT:
7880 alc883_clevo_m720_mic_automute(codec);
7885 /* toggle speaker-output according to the hp-jack state */
7886 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7888 unsigned int present;
7891 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7892 & AC_PINSENSE_PRESENCE;
7893 bits = present ? HDA_AMP_MUTE : 0;
7894 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7895 HDA_AMP_MUTE, bits);
7898 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7901 if ((res >> 26) == ALC880_HP_EVENT)
7902 alc883_2ch_fujitsu_pi2515_automute(codec);
7905 static void alc883_haier_w66_automute(struct hda_codec *codec)
7907 unsigned int present;
7910 present = snd_hda_codec_read(codec, 0x1b, 0,
7911 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7912 bits = present ? 0x80 : 0;
7913 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7917 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7920 if ((res >> 26) == ALC880_HP_EVENT)
7921 alc883_haier_w66_automute(codec);
7924 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7926 unsigned int present;
7929 present = snd_hda_codec_read(codec, 0x14, 0,
7930 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7931 bits = present ? HDA_AMP_MUTE : 0;
7932 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7933 HDA_AMP_MUTE, bits);
7936 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7938 unsigned int present;
7941 present = snd_hda_codec_read(codec, 0x1b, 0,
7942 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7943 bits = present ? HDA_AMP_MUTE : 0;
7944 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7945 HDA_AMP_MUTE, bits);
7946 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7947 HDA_AMP_MUTE, bits);
7950 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7953 if ((res >> 26) == ALC880_HP_EVENT)
7954 alc883_lenovo_101e_all_automute(codec);
7955 if ((res >> 26) == ALC880_FRONT_EVENT)
7956 alc883_lenovo_101e_ispeaker_automute(codec);
7959 /* toggle speaker-output according to the hp-jack state */
7960 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7962 unsigned int present;
7964 present = snd_hda_codec_read(codec, 0x14, 0,
7965 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7966 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7967 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7968 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7969 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7972 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7975 if ((res >> 26) == ALC880_HP_EVENT)
7976 alc883_acer_aspire_automute(codec);
7979 static struct hda_verb alc883_acer_eapd_verbs[] = {
7980 /* HP Pin: output 0 (0x0c) */
7981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7982 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7983 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7984 /* Front Pin: output 0 (0x0c) */
7985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7987 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7988 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7989 /* eanable EAPD on medion laptop */
7990 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7991 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7992 /* enable unsolicited event */
7993 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7997 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7999 unsigned int present;
8001 present = snd_hda_codec_read(codec, 0x1b, 0,
8002 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8003 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8004 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8005 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8006 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8007 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8008 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8009 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8010 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8013 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8016 switch (res >> 26) {
8017 case ALC880_HP_EVENT:
8018 printk("hp_event\n");
8019 alc888_6st_dell_front_automute(codec);
8024 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8027 unsigned int present;
8029 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8030 present = snd_hda_codec_read(codec, 0x1b, 0,
8031 AC_VERB_GET_PIN_SENSE, 0);
8032 present = (present & 0x80000000) != 0;
8034 /* mute internal speaker */
8035 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8036 HDA_AMP_MUTE, HDA_AMP_MUTE);
8037 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8038 HDA_AMP_MUTE, HDA_AMP_MUTE);
8039 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8040 HDA_AMP_MUTE, HDA_AMP_MUTE);
8041 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8042 HDA_AMP_MUTE, HDA_AMP_MUTE);
8043 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8044 HDA_AMP_MUTE, HDA_AMP_MUTE);
8046 /* unmute internal speaker if necessary */
8047 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8048 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8049 HDA_AMP_MUTE, mute);
8050 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8051 HDA_AMP_MUTE, mute);
8052 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8053 HDA_AMP_MUTE, mute);
8054 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8055 HDA_AMP_MUTE, mute);
8056 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8057 HDA_AMP_MUTE, mute);
8061 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8064 if ((res >> 26) == ALC880_HP_EVENT)
8065 alc888_lenovo_sky_front_automute(codec);
8069 * generic initialization of ADC, input mixers and output mixers
8071 static struct hda_verb alc883_auto_init_verbs[] = {
8073 * Unmute ADC0-2 and set the default input to mic-in
8075 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8076 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8077 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8080 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8082 * Note: PASD motherboards uses the Line In 2 as the input for
8083 * front panel mic (mic 2)
8085 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8086 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8093 * Set up output mixers (0x0c - 0x0f)
8095 /* set vol=0 to output mixers */
8096 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8097 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8098 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8099 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8100 /* set up input amps for analog loopback */
8101 /* Amp Indices: DAC = 0, mixer = 1 */
8102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8106 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8107 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8108 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8109 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8110 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8111 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8113 /* FIXME: use matrix-type input source selection */
8114 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8119 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8125 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8131 /* capture mixer elements */
8132 static struct snd_kcontrol_new alc883_capture_mixer[] = {
8133 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8134 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8135 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8136 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8139 /* The multiple "Capture Source" controls confuse alsamixer
8140 * So call somewhat different..
8142 /* .name = "Capture Source", */
8143 .name = "Input Source",
8145 .info = alc882_mux_enum_info,
8146 .get = alc882_mux_enum_get,
8147 .put = alc882_mux_enum_put,
8152 static struct hda_verb alc888_asus_m90v_verbs[] = {
8153 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8156 /* enable unsolicited event */
8157 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8158 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8162 static void alc883_nb_mic_automute(struct hda_codec *codec)
8164 unsigned int present;
8166 present = snd_hda_codec_read(codec, 0x18, 0,
8167 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8168 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8169 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8170 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8171 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8174 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8176 unsigned int present;
8179 present = snd_hda_codec_read(codec, 0x1b, 0,
8180 AC_VERB_GET_PIN_SENSE, 0)
8181 & AC_PINSENSE_PRESENCE;
8182 bits = present ? 0 : PIN_OUT;
8183 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8185 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8187 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8191 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8194 switch (res >> 26) {
8195 case ALC880_HP_EVENT:
8196 alc883_M90V_speaker_automute(codec);
8198 case ALC880_MIC_EVENT:
8199 alc883_nb_mic_automute(codec);
8204 static void alc883_mode2_inithook(struct hda_codec *codec)
8206 alc883_M90V_speaker_automute(codec);
8207 alc883_nb_mic_automute(codec);
8210 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8211 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8212 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8213 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8216 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8217 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8218 /* enable unsolicited event */
8219 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8223 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8225 unsigned int present;
8228 present = snd_hda_codec_read(codec, 0x14, 0,
8229 AC_VERB_GET_PIN_SENSE, 0)
8230 & AC_PINSENSE_PRESENCE;
8231 bits = present ? 0 : PIN_OUT;
8232 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8236 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8239 switch (res >> 26) {
8240 case ALC880_HP_EVENT:
8241 alc883_eee1601_speaker_automute(codec);
8246 static void alc883_eee1601_inithook(struct hda_codec *codec)
8248 alc883_eee1601_speaker_automute(codec);
8251 #ifdef CONFIG_SND_HDA_POWER_SAVE
8252 #define alc883_loopbacks alc880_loopbacks
8255 /* pcm configuration: identiacal with ALC880 */
8256 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8257 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8258 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8259 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8260 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8263 * configuration and preset
8265 static const char *alc883_models[ALC883_MODEL_LAST] = {
8266 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8267 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8268 [ALC883_3ST_6ch] = "3stack-6ch",
8269 [ALC883_6ST_DIG] = "6stack-dig",
8270 [ALC883_TARGA_DIG] = "targa-dig",
8271 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8272 [ALC883_ACER] = "acer",
8273 [ALC883_ACER_ASPIRE] = "acer-aspire",
8274 [ALC883_MEDION] = "medion",
8275 [ALC883_MEDION_MD2] = "medion-md2",
8276 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8277 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8278 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8279 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8280 [ALC888_LENOVO_SKY] = "lenovo-sky",
8281 [ALC883_HAIER_W66] = "haier-w66",
8282 [ALC888_3ST_HP] = "3stack-hp",
8283 [ALC888_6ST_DELL] = "6stack-dell",
8284 [ALC883_MITAC] = "mitac",
8285 [ALC883_CLEVO_M720] = "clevo-m720",
8286 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8287 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8288 [ALC883_AUTO] = "auto",
8291 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8292 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8293 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8294 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8295 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8296 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8297 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8298 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8299 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8300 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8301 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8302 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8303 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8304 SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
8305 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8306 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8307 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8308 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8309 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8310 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8311 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8312 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8313 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8314 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8315 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8316 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8317 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8318 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8319 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8320 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8321 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8322 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8323 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8324 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8325 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8326 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8327 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8328 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8329 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8330 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8331 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8332 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8333 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8334 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8335 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8336 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8337 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8338 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8339 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8340 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8341 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8342 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8343 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8344 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8345 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8346 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8347 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8348 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8349 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8350 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8351 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8352 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8356 static struct alc_config_preset alc883_presets[] = {
8357 [ALC883_3ST_2ch_DIG] = {
8358 .mixers = { alc883_3ST_2ch_mixer },
8359 .init_verbs = { alc883_init_verbs },
8360 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8361 .dac_nids = alc883_dac_nids,
8362 .dig_out_nid = ALC883_DIGOUT_NID,
8363 .dig_in_nid = ALC883_DIGIN_NID,
8364 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8365 .channel_mode = alc883_3ST_2ch_modes,
8366 .input_mux = &alc883_capture_source,
8368 [ALC883_3ST_6ch_DIG] = {
8369 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8370 .init_verbs = { alc883_init_verbs },
8371 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8372 .dac_nids = alc883_dac_nids,
8373 .dig_out_nid = ALC883_DIGOUT_NID,
8374 .dig_in_nid = ALC883_DIGIN_NID,
8375 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8376 .channel_mode = alc883_3ST_6ch_modes,
8378 .input_mux = &alc883_capture_source,
8380 [ALC883_3ST_6ch] = {
8381 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8382 .init_verbs = { alc883_init_verbs },
8383 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8384 .dac_nids = alc883_dac_nids,
8385 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8386 .channel_mode = alc883_3ST_6ch_modes,
8388 .input_mux = &alc883_capture_source,
8390 [ALC883_3ST_6ch_INTEL] = {
8391 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8392 .init_verbs = { alc883_init_verbs },
8393 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8394 .dac_nids = alc883_dac_nids,
8395 .dig_out_nid = ALC883_DIGOUT_NID,
8396 .dig_in_nid = ALC883_DIGIN_NID,
8397 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8398 .channel_mode = alc883_3ST_6ch_intel_modes,
8400 .input_mux = &alc883_3stack_6ch_intel,
8402 [ALC883_6ST_DIG] = {
8403 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8404 .init_verbs = { alc883_init_verbs },
8405 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8406 .dac_nids = alc883_dac_nids,
8407 .dig_out_nid = ALC883_DIGOUT_NID,
8408 .dig_in_nid = ALC883_DIGIN_NID,
8409 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8410 .channel_mode = alc883_sixstack_modes,
8411 .input_mux = &alc883_capture_source,
8413 [ALC883_TARGA_DIG] = {
8414 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8415 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8416 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8417 .dac_nids = alc883_dac_nids,
8418 .dig_out_nid = ALC883_DIGOUT_NID,
8419 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8420 .channel_mode = alc883_3ST_6ch_modes,
8422 .input_mux = &alc883_capture_source,
8423 .unsol_event = alc883_tagra_unsol_event,
8424 .init_hook = alc883_tagra_automute,
8426 [ALC883_TARGA_2ch_DIG] = {
8427 .mixers = { alc883_tagra_2ch_mixer},
8428 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8429 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8430 .dac_nids = alc883_dac_nids,
8431 .dig_out_nid = ALC883_DIGOUT_NID,
8432 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8433 .channel_mode = alc883_3ST_2ch_modes,
8434 .input_mux = &alc883_capture_source,
8435 .unsol_event = alc883_tagra_unsol_event,
8436 .init_hook = alc883_tagra_automute,
8439 .mixers = { alc883_base_mixer },
8440 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8441 * and the headphone jack. Turn this on and rely on the
8442 * standard mute methods whenever the user wants to turn
8443 * these outputs off.
8445 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8446 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8447 .dac_nids = alc883_dac_nids,
8448 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8449 .channel_mode = alc883_3ST_2ch_modes,
8450 .input_mux = &alc883_capture_source,
8452 [ALC883_ACER_ASPIRE] = {
8453 .mixers = { alc883_acer_aspire_mixer },
8454 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8455 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8456 .dac_nids = alc883_dac_nids,
8457 .dig_out_nid = ALC883_DIGOUT_NID,
8458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8459 .channel_mode = alc883_3ST_2ch_modes,
8460 .input_mux = &alc883_capture_source,
8461 .unsol_event = alc883_acer_aspire_unsol_event,
8462 .init_hook = alc883_acer_aspire_automute,
8465 .mixers = { alc883_fivestack_mixer,
8466 alc883_chmode_mixer },
8467 .init_verbs = { alc883_init_verbs,
8468 alc883_medion_eapd_verbs },
8469 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8470 .dac_nids = alc883_dac_nids,
8471 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8472 .channel_mode = alc883_sixstack_modes,
8473 .input_mux = &alc883_capture_source,
8475 [ALC883_MEDION_MD2] = {
8476 .mixers = { alc883_medion_md2_mixer},
8477 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8478 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8479 .dac_nids = alc883_dac_nids,
8480 .dig_out_nid = ALC883_DIGOUT_NID,
8481 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8482 .channel_mode = alc883_3ST_2ch_modes,
8483 .input_mux = &alc883_capture_source,
8484 .unsol_event = alc883_medion_md2_unsol_event,
8485 .init_hook = alc883_medion_md2_automute,
8487 [ALC883_LAPTOP_EAPD] = {
8488 .mixers = { alc883_base_mixer },
8489 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8490 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8491 .dac_nids = alc883_dac_nids,
8492 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8493 .channel_mode = alc883_3ST_2ch_modes,
8494 .input_mux = &alc883_capture_source,
8496 [ALC883_CLEVO_M720] = {
8497 .mixers = { alc883_clevo_m720_mixer },
8498 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8499 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8500 .dac_nids = alc883_dac_nids,
8501 .dig_out_nid = ALC883_DIGOUT_NID,
8502 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8503 .channel_mode = alc883_3ST_2ch_modes,
8504 .input_mux = &alc883_capture_source,
8505 .unsol_event = alc883_clevo_m720_unsol_event,
8506 .init_hook = alc883_clevo_m720_automute,
8508 [ALC883_LENOVO_101E_2ch] = {
8509 .mixers = { alc883_lenovo_101e_2ch_mixer},
8510 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8511 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8512 .dac_nids = alc883_dac_nids,
8513 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8514 .channel_mode = alc883_3ST_2ch_modes,
8515 .input_mux = &alc883_lenovo_101e_capture_source,
8516 .unsol_event = alc883_lenovo_101e_unsol_event,
8517 .init_hook = alc883_lenovo_101e_all_automute,
8519 [ALC883_LENOVO_NB0763] = {
8520 .mixers = { alc883_lenovo_nb0763_mixer },
8521 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8522 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8523 .dac_nids = alc883_dac_nids,
8524 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8525 .channel_mode = alc883_3ST_2ch_modes,
8527 .input_mux = &alc883_lenovo_nb0763_capture_source,
8528 .unsol_event = alc883_medion_md2_unsol_event,
8529 .init_hook = alc883_medion_md2_automute,
8531 [ALC888_LENOVO_MS7195_DIG] = {
8532 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8533 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8534 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8535 .dac_nids = alc883_dac_nids,
8536 .dig_out_nid = ALC883_DIGOUT_NID,
8537 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8538 .channel_mode = alc883_3ST_6ch_modes,
8540 .input_mux = &alc883_capture_source,
8541 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8542 .init_hook = alc888_lenovo_ms7195_front_automute,
8544 [ALC883_HAIER_W66] = {
8545 .mixers = { alc883_tagra_2ch_mixer},
8546 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8547 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8548 .dac_nids = alc883_dac_nids,
8549 .dig_out_nid = ALC883_DIGOUT_NID,
8550 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8551 .channel_mode = alc883_3ST_2ch_modes,
8552 .input_mux = &alc883_capture_source,
8553 .unsol_event = alc883_haier_w66_unsol_event,
8554 .init_hook = alc883_haier_w66_automute,
8557 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8558 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8559 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8560 .dac_nids = alc883_dac_nids,
8561 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8562 .channel_mode = alc888_3st_hp_modes,
8564 .input_mux = &alc883_capture_source,
8566 [ALC888_6ST_DELL] = {
8567 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8568 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8569 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8570 .dac_nids = alc883_dac_nids,
8571 .dig_out_nid = ALC883_DIGOUT_NID,
8572 .dig_in_nid = ALC883_DIGIN_NID,
8573 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8574 .channel_mode = alc883_sixstack_modes,
8575 .input_mux = &alc883_capture_source,
8576 .unsol_event = alc888_6st_dell_unsol_event,
8577 .init_hook = alc888_6st_dell_front_automute,
8580 .mixers = { alc883_mitac_mixer },
8581 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8582 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8583 .dac_nids = alc883_dac_nids,
8584 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8585 .channel_mode = alc883_3ST_2ch_modes,
8586 .input_mux = &alc883_capture_source,
8587 .unsol_event = alc883_mitac_unsol_event,
8588 .init_hook = alc883_mitac_automute,
8590 [ALC883_FUJITSU_PI2515] = {
8591 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8592 .init_verbs = { alc883_init_verbs,
8593 alc883_2ch_fujitsu_pi2515_verbs},
8594 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8595 .dac_nids = alc883_dac_nids,
8596 .dig_out_nid = ALC883_DIGOUT_NID,
8597 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8598 .channel_mode = alc883_3ST_2ch_modes,
8599 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8600 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8601 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8603 [ALC888_LENOVO_SKY] = {
8604 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8605 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8606 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8607 .dac_nids = alc883_dac_nids,
8608 .dig_out_nid = ALC883_DIGOUT_NID,
8609 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8610 .adc_nids = alc883_adc_nids,
8611 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8612 .channel_mode = alc883_sixstack_modes,
8614 .input_mux = &alc883_lenovo_sky_capture_source,
8615 .unsol_event = alc883_lenovo_sky_unsol_event,
8616 .init_hook = alc888_lenovo_sky_front_automute,
8618 [ALC888_ASUS_M90V] = {
8619 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8620 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8621 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8622 .dac_nids = alc883_dac_nids,
8623 .dig_out_nid = ALC883_DIGOUT_NID,
8624 .dig_in_nid = ALC883_DIGIN_NID,
8625 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8626 .channel_mode = alc883_3ST_6ch_modes,
8628 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8629 .unsol_event = alc883_mode2_unsol_event,
8630 .init_hook = alc883_mode2_inithook,
8632 [ALC888_ASUS_EEE1601] = {
8633 .mixers = { alc883_asus_eee1601_mixer },
8634 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8635 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8636 .dac_nids = alc883_dac_nids,
8637 .dig_out_nid = ALC883_DIGOUT_NID,
8638 .dig_in_nid = ALC883_DIGIN_NID,
8639 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8640 .channel_mode = alc883_3ST_2ch_modes,
8642 .input_mux = &alc883_asus_eee1601_capture_source,
8643 .unsol_event = alc883_eee1601_unsol_event,
8644 .init_hook = alc883_eee1601_inithook,
8650 * BIOS auto configuration
8652 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8653 hda_nid_t nid, int pin_type,
8657 struct alc_spec *spec = codec->spec;
8660 alc_set_pin_output(codec, nid, pin_type);
8661 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8664 idx = spec->multiout.dac_nids[dac_idx] - 2;
8665 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8669 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8671 struct alc_spec *spec = codec->spec;
8674 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8675 for (i = 0; i <= HDA_SIDE; i++) {
8676 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8677 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8679 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8684 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8686 struct alc_spec *spec = codec->spec;
8689 pin = spec->autocfg.hp_pins[0];
8690 if (pin) /* connect to front */
8692 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8693 pin = spec->autocfg.speaker_pins[0];
8695 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8698 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8699 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8701 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8703 struct alc_spec *spec = codec->spec;
8706 for (i = 0; i < AUTO_PIN_LAST; i++) {
8707 hda_nid_t nid = spec->autocfg.input_pins[i];
8708 if (alc883_is_input_pin(nid)) {
8709 snd_hda_codec_write(codec, nid, 0,
8710 AC_VERB_SET_PIN_WIDGET_CONTROL,
8711 (i <= AUTO_PIN_FRONT_MIC ?
8712 PIN_VREF80 : PIN_IN));
8713 if (nid != ALC883_PIN_CD_NID)
8714 snd_hda_codec_write(codec, nid, 0,
8715 AC_VERB_SET_AMP_GAIN_MUTE,
8721 #define alc883_auto_init_input_src alc882_auto_init_input_src
8723 /* almost identical with ALC880 parser... */
8724 static int alc883_parse_auto_config(struct hda_codec *codec)
8726 struct alc_spec *spec = codec->spec;
8727 int err = alc880_parse_auto_config(codec);
8732 return 0; /* no config found */
8734 err = alc_auto_add_mic_boost(codec);
8738 /* hack - override the init verbs */
8739 spec->init_verbs[0] = alc883_auto_init_verbs;
8740 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8743 return 1; /* config found */
8746 /* additional initialization for auto-configuration model */
8747 static void alc883_auto_init(struct hda_codec *codec)
8749 struct alc_spec *spec = codec->spec;
8750 alc883_auto_init_multi_out(codec);
8751 alc883_auto_init_hp_out(codec);
8752 alc883_auto_init_analog_input(codec);
8753 alc883_auto_init_input_src(codec);
8754 if (spec->unsol_event)
8755 alc_sku_automute(codec);
8758 static int patch_alc883(struct hda_codec *codec)
8760 struct alc_spec *spec;
8761 int err, board_config;
8763 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8769 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8771 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8774 if (board_config < 0) {
8775 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8776 "trying auto-probe from BIOS...\n");
8777 board_config = ALC883_AUTO;
8780 if (board_config == ALC883_AUTO) {
8781 /* automatic parse from the BIOS config */
8782 err = alc883_parse_auto_config(codec);
8788 "hda_codec: Cannot set up configuration "
8789 "from BIOS. Using base mode...\n");
8790 board_config = ALC883_3ST_2ch_DIG;
8794 if (board_config != ALC883_AUTO)
8795 setup_preset(spec, &alc883_presets[board_config]);
8797 switch (codec->vendor_id) {
8799 spec->stream_name_analog = "ALC888 Analog";
8800 spec->stream_name_digital = "ALC888 Digital";
8803 spec->stream_name_analog = "ALC889 Analog";
8804 spec->stream_name_digital = "ALC889 Digital";
8807 spec->stream_name_analog = "ALC883 Analog";
8808 spec->stream_name_digital = "ALC883 Digital";
8812 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8813 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8814 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8816 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8817 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8819 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8820 spec->adc_nids = alc883_adc_nids;
8821 spec->capsrc_nids = alc883_capsrc_nids;
8823 spec->vmaster_nid = 0x0c;
8825 codec->patch_ops = alc_patch_ops;
8826 if (board_config == ALC883_AUTO)
8827 spec->init_hook = alc883_auto_init;
8829 #ifdef CONFIG_SND_HDA_POWER_SAVE
8830 if (!spec->loopback.amplist)
8831 spec->loopback.amplist = alc883_loopbacks;
8841 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8842 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8844 #define alc262_dac_nids alc260_dac_nids
8845 #define alc262_adc_nids alc882_adc_nids
8846 #define alc262_adc_nids_alt alc882_adc_nids_alt
8847 #define alc262_capsrc_nids alc882_capsrc_nids
8848 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8850 #define alc262_modes alc260_modes
8851 #define alc262_capture_source alc882_capture_source
8853 static hda_nid_t alc262_dmic_adc_nids[1] = {
8858 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8860 static struct snd_kcontrol_new alc262_base_mixer[] = {
8861 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8862 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8863 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8864 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8865 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8866 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8867 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8868 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8869 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8870 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8871 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8872 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8873 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8874 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8875 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8876 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8877 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8878 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8882 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8883 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8884 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8885 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8886 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8887 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8888 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8889 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8891 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8892 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8893 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8894 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8895 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8896 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8897 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8898 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8902 /* update HP, line and mono-out pins according to the master switch */
8903 static void alc262_hp_master_update(struct hda_codec *codec)
8905 struct alc_spec *spec = codec->spec;
8906 int val = spec->master_sw;
8909 snd_hda_codec_write_cache(codec, 0x1b, 0,
8910 AC_VERB_SET_PIN_WIDGET_CONTROL,
8912 snd_hda_codec_write_cache(codec, 0x15, 0,
8913 AC_VERB_SET_PIN_WIDGET_CONTROL,
8915 /* mono (speaker) depending on the HP jack sense */
8916 val = val && !spec->jack_present;
8917 snd_hda_codec_write_cache(codec, 0x16, 0,
8918 AC_VERB_SET_PIN_WIDGET_CONTROL,
8922 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8924 struct alc_spec *spec = codec->spec;
8925 unsigned int presence;
8926 presence = snd_hda_codec_read(codec, 0x1b, 0,
8927 AC_VERB_GET_PIN_SENSE, 0);
8928 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8929 alc262_hp_master_update(codec);
8932 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8934 if ((res >> 26) != ALC880_HP_EVENT)
8936 alc262_hp_bpc_automute(codec);
8939 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8941 struct alc_spec *spec = codec->spec;
8942 unsigned int presence;
8943 presence = snd_hda_codec_read(codec, 0x15, 0,
8944 AC_VERB_GET_PIN_SENSE, 0);
8945 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8946 alc262_hp_master_update(codec);
8949 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8952 if ((res >> 26) != ALC880_HP_EVENT)
8954 alc262_hp_wildwest_automute(codec);
8957 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8958 struct snd_ctl_elem_value *ucontrol)
8960 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8961 struct alc_spec *spec = codec->spec;
8962 *ucontrol->value.integer.value = spec->master_sw;
8966 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8967 struct snd_ctl_elem_value *ucontrol)
8969 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8970 struct alc_spec *spec = codec->spec;
8971 int val = !!*ucontrol->value.integer.value;
8973 if (val == spec->master_sw)
8975 spec->master_sw = val;
8976 alc262_hp_master_update(codec);
8980 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8982 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8983 .name = "Master Playback Switch",
8984 .info = snd_ctl_boolean_mono_info,
8985 .get = alc262_hp_master_sw_get,
8986 .put = alc262_hp_master_sw_put,
8988 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8989 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8990 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8993 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9001 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9002 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9003 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9004 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9005 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9006 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9007 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9008 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9012 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9014 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9015 .name = "Master Playback Switch",
9016 .info = snd_ctl_boolean_mono_info,
9017 .get = alc262_hp_master_sw_get,
9018 .put = alc262_hp_master_sw_put,
9020 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9021 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9022 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9023 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9024 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9026 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9028 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9029 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9030 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9033 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9034 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9035 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9036 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9040 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9041 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9042 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9043 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9047 /* mute/unmute internal speaker according to the hp jack and mute state */
9048 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9050 struct alc_spec *spec = codec->spec;
9052 if (force || !spec->sense_updated) {
9053 unsigned int present;
9054 present = snd_hda_codec_read(codec, 0x15, 0,
9055 AC_VERB_GET_PIN_SENSE, 0);
9056 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9057 spec->sense_updated = 1;
9059 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9060 spec->jack_present ? HDA_AMP_MUTE : 0);
9063 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9066 if ((res >> 26) != ALC880_HP_EVENT)
9068 alc262_hp_t5735_automute(codec, 1);
9071 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9073 alc262_hp_t5735_automute(codec, 1);
9076 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9077 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9078 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9080 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9082 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9083 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9087 static struct hda_verb alc262_hp_t5735_verbs[] = {
9088 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9089 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9091 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9095 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9096 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9097 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9098 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9099 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9101 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9105 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9106 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9107 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9108 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9109 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9110 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9111 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9112 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9113 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9119 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9126 /* bind hp and internal speaker mute (with plug check) */
9127 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9128 struct snd_ctl_elem_value *ucontrol)
9130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9131 long *valp = ucontrol->value.integer.value;
9134 /* change hp mute */
9135 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9137 valp[0] ? 0 : HDA_AMP_MUTE);
9138 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9140 valp[1] ? 0 : HDA_AMP_MUTE);
9142 /* change speaker according to HP jack state */
9143 struct alc_spec *spec = codec->spec;
9145 if (spec->jack_present)
9146 mute = HDA_AMP_MUTE;
9148 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9150 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9151 HDA_AMP_MUTE, mute);
9156 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9157 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9160 .name = "Master Playback Switch",
9161 .info = snd_hda_mixer_amp_switch_info,
9162 .get = snd_hda_mixer_amp_switch_get,
9163 .put = alc262_sony_master_sw_put,
9164 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9168 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9169 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9173 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9174 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9175 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9179 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9180 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9184 #define alc262_capture_mixer alc882_capture_mixer
9185 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9188 * generic initialization of ADC, input mixers and output mixers
9190 static struct hda_verb alc262_init_verbs[] = {
9192 * Unmute ADC0-2 and set the default input to mic-in
9194 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9196 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9197 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9198 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9199 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9201 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9203 * Note: PASD motherboards uses the Line In 2 as the input for
9204 * front panel mic (mic 2)
9206 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9207 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9208 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9214 * Set up output mixers (0x0c - 0x0e)
9216 /* set vol=0 to output mixers */
9217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9218 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9219 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9220 /* set up input amps for analog loopback */
9221 /* Amp Indices: DAC = 0, mixer = 1 */
9222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9223 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9224 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9225 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9226 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9227 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9229 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9230 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9231 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9232 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9233 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9234 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9236 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9237 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9238 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9239 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9240 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9242 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9243 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9245 /* FIXME: use matrix-type input source selection */
9246 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9247 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9248 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9249 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9251 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9253 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9254 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9255 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9256 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9266 static struct hda_verb alc262_eapd_verbs[] = {
9267 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9268 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9272 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9273 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9274 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9278 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9279 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9280 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9281 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9283 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9284 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9288 static struct hda_verb alc262_sony_unsol_verbs[] = {
9289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9290 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9291 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9293 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9294 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9298 static struct hda_input_mux alc262_dmic_capture_source = {
9301 { "Int DMic", 0x9 },
9306 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9307 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9308 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9310 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9311 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9312 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9313 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9316 /* The multiple "Capture Source" controls confuse alsamixer
9317 * So call somewhat different..
9319 /* .name = "Capture Source", */
9320 .name = "Input Source",
9322 .info = alc_mux_enum_info,
9323 .get = alc_mux_enum_get,
9324 .put = alc_mux_enum_put,
9329 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9330 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9332 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9333 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9334 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9335 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9336 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9341 static void alc262_dmic_automute(struct hda_codec *codec)
9343 unsigned int present;
9345 present = snd_hda_codec_read(codec, 0x18, 0,
9346 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9347 snd_hda_codec_write(codec, 0x22, 0,
9348 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9351 /* toggle speaker-output according to the hp-jack state */
9352 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9354 unsigned int present;
9357 present = snd_hda_codec_read(codec, 0x15, 0,
9358 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9359 bits = present ? 0 : PIN_OUT;
9360 snd_hda_codec_write(codec, 0x14, 0,
9361 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9366 /* unsolicited event for HP jack sensing */
9367 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9370 if ((res >> 26) == ALC880_HP_EVENT)
9371 alc262_toshiba_s06_speaker_automute(codec);
9372 if ((res >> 26) == ALC880_MIC_EVENT)
9373 alc262_dmic_automute(codec);
9377 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9379 alc262_toshiba_s06_speaker_automute(codec);
9380 alc262_dmic_automute(codec);
9383 /* mute/unmute internal speaker according to the hp jack and mute state */
9384 static void alc262_hippo_automute(struct hda_codec *codec)
9386 struct alc_spec *spec = codec->spec;
9388 unsigned int present;
9390 /* need to execute and sync at first */
9391 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9392 present = snd_hda_codec_read(codec, 0x15, 0,
9393 AC_VERB_GET_PIN_SENSE, 0);
9394 spec->jack_present = (present & 0x80000000) != 0;
9395 if (spec->jack_present) {
9396 /* mute internal speaker */
9397 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9398 HDA_AMP_MUTE, HDA_AMP_MUTE);
9400 /* unmute internal speaker if necessary */
9401 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9402 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9403 HDA_AMP_MUTE, mute);
9407 /* unsolicited event for HP jack sensing */
9408 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9411 if ((res >> 26) != ALC880_HP_EVENT)
9413 alc262_hippo_automute(codec);
9416 static void alc262_hippo1_automute(struct hda_codec *codec)
9419 unsigned int present;
9421 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9422 present = snd_hda_codec_read(codec, 0x1b, 0,
9423 AC_VERB_GET_PIN_SENSE, 0);
9424 present = (present & 0x80000000) != 0;
9426 /* mute internal speaker */
9427 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9428 HDA_AMP_MUTE, HDA_AMP_MUTE);
9430 /* unmute internal speaker if necessary */
9431 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9432 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9433 HDA_AMP_MUTE, mute);
9437 /* unsolicited event for HP jack sensing */
9438 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9441 if ((res >> 26) != ALC880_HP_EVENT)
9443 alc262_hippo1_automute(codec);
9449 * 0x16 = internal speaker
9450 * 0x18 = external mic
9453 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9454 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9455 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9459 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9461 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9466 static struct hda_verb alc262_nec_verbs[] = {
9467 /* Unmute Speaker */
9468 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9471 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9472 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9474 /* External mic to headphone */
9475 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9476 /* External mic to speaker */
9477 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9483 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9484 * 0x1b = port replicator headphone out
9487 #define ALC_HP_EVENT 0x37
9489 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9490 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9491 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9492 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9493 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9497 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9498 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9499 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9503 static struct hda_input_mux alc262_fujitsu_capture_source = {
9512 static struct hda_input_mux alc262_HP_capture_source = {
9516 { "Front Mic", 0x1 },
9523 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9527 { "Front Mic", 0x2 },
9533 /* mute/unmute internal speaker according to the hp jacks and mute state */
9534 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9536 struct alc_spec *spec = codec->spec;
9539 if (force || !spec->sense_updated) {
9540 unsigned int present;
9541 /* need to execute and sync at first */
9542 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9543 /* check laptop HP jack */
9544 present = snd_hda_codec_read(codec, 0x14, 0,
9545 AC_VERB_GET_PIN_SENSE, 0);
9546 /* need to execute and sync at first */
9547 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9548 /* check docking HP jack */
9549 present |= snd_hda_codec_read(codec, 0x1b, 0,
9550 AC_VERB_GET_PIN_SENSE, 0);
9551 if (present & AC_PINSENSE_PRESENCE)
9552 spec->jack_present = 1;
9554 spec->jack_present = 0;
9555 spec->sense_updated = 1;
9557 /* unmute internal speaker only if both HPs are unplugged and
9558 * master switch is on
9560 if (spec->jack_present)
9561 mute = HDA_AMP_MUTE;
9563 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9564 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9565 HDA_AMP_MUTE, mute);
9568 /* unsolicited event for HP jack sensing */
9569 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9572 if ((res >> 26) != ALC_HP_EVENT)
9574 alc262_fujitsu_automute(codec, 1);
9577 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9579 alc262_fujitsu_automute(codec, 1);
9582 /* bind volumes of both NID 0x0c and 0x0d */
9583 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9584 .ops = &snd_hda_bind_vol,
9586 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9587 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9592 /* mute/unmute internal speaker according to the hp jack and mute state */
9593 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9595 struct alc_spec *spec = codec->spec;
9598 if (force || !spec->sense_updated) {
9599 unsigned int present_int_hp;
9600 /* need to execute and sync at first */
9601 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9602 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9603 AC_VERB_GET_PIN_SENSE, 0);
9604 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9605 spec->sense_updated = 1;
9607 if (spec->jack_present) {
9608 /* mute internal speaker */
9609 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9610 HDA_AMP_MUTE, HDA_AMP_MUTE);
9611 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9612 HDA_AMP_MUTE, HDA_AMP_MUTE);
9614 /* unmute internal speaker if necessary */
9615 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9616 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9617 HDA_AMP_MUTE, mute);
9618 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9619 HDA_AMP_MUTE, mute);
9623 /* unsolicited event for HP jack sensing */
9624 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9627 if ((res >> 26) != ALC_HP_EVENT)
9629 alc262_lenovo_3000_automute(codec, 1);
9632 /* bind hp and internal speaker mute (with plug check) */
9633 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9634 struct snd_ctl_elem_value *ucontrol)
9636 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9637 long *valp = ucontrol->value.integer.value;
9640 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9642 valp ? 0 : HDA_AMP_MUTE);
9643 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9645 valp ? 0 : HDA_AMP_MUTE);
9648 alc262_fujitsu_automute(codec, 0);
9652 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9653 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9656 .name = "Master Playback Switch",
9657 .info = snd_hda_mixer_amp_switch_info,
9658 .get = snd_hda_mixer_amp_switch_get,
9659 .put = alc262_fujitsu_master_sw_put,
9660 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9662 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9663 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9664 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9665 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9666 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9669 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9670 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9671 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9675 /* bind hp and internal speaker mute (with plug check) */
9676 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9677 struct snd_ctl_elem_value *ucontrol)
9679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9680 long *valp = ucontrol->value.integer.value;
9683 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9685 valp ? 0 : HDA_AMP_MUTE);
9688 alc262_lenovo_3000_automute(codec, 0);
9692 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9693 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9695 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9696 .name = "Master Playback Switch",
9697 .info = snd_hda_mixer_amp_switch_info,
9698 .get = snd_hda_mixer_amp_switch_get,
9699 .put = alc262_lenovo_3000_master_sw_put,
9700 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9702 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9703 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9704 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9707 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9708 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9709 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9713 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9714 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9717 .name = "Master Playback Switch",
9718 .info = snd_hda_mixer_amp_switch_info,
9719 .get = snd_hda_mixer_amp_switch_get,
9720 .put = alc262_sony_master_sw_put,
9721 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9723 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9724 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9725 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9726 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9727 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9728 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9732 /* additional init verbs for Benq laptops */
9733 static struct hda_verb alc262_EAPD_verbs[] = {
9734 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9735 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9739 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9740 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9741 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9743 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9744 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9748 /* Samsung Q1 Ultra Vista model setup */
9749 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9750 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9751 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9752 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9753 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9754 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9755 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9759 static struct hda_verb alc262_ultra_verbs[] = {
9761 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9762 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9768 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9773 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9774 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9776 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9777 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9778 /* ADC, choose mic */
9779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9780 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9781 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9782 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9783 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9784 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9785 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9786 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9787 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9788 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9792 /* mute/unmute internal speaker according to the hp jack and mute state */
9793 static void alc262_ultra_automute(struct hda_codec *codec)
9795 struct alc_spec *spec = codec->spec;
9799 /* auto-mute only when HP is used as HP */
9800 if (!spec->cur_mux[0]) {
9801 unsigned int present;
9802 /* need to execute and sync at first */
9803 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9804 present = snd_hda_codec_read(codec, 0x15, 0,
9805 AC_VERB_GET_PIN_SENSE, 0);
9806 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9807 if (spec->jack_present)
9808 mute = HDA_AMP_MUTE;
9810 /* mute/unmute internal speaker */
9811 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9812 HDA_AMP_MUTE, mute);
9813 /* mute/unmute HP */
9814 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9815 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9818 /* unsolicited event for HP jack sensing */
9819 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9822 if ((res >> 26) != ALC880_HP_EVENT)
9824 alc262_ultra_automute(codec);
9827 static struct hda_input_mux alc262_ultra_capture_source = {
9831 { "Headphone", 0x7 },
9835 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9836 struct snd_ctl_elem_value *ucontrol)
9838 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9839 struct alc_spec *spec = codec->spec;
9842 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9845 /* reprogram the HP pin as mic or HP according to the input source */
9846 snd_hda_codec_write_cache(codec, 0x15, 0,
9847 AC_VERB_SET_PIN_WIDGET_CONTROL,
9848 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9849 alc262_ultra_automute(codec); /* mute/unmute HP */
9853 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9854 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9855 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9857 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9858 .name = "Capture Source",
9859 .info = alc882_mux_enum_info,
9860 .get = alc882_mux_enum_get,
9861 .put = alc262_ultra_mux_enum_put,
9866 /* add playback controls from the parsed DAC table */
9867 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9868 const struct auto_pin_cfg *cfg)
9873 spec->multiout.num_dacs = 1; /* only use one dac */
9874 spec->multiout.dac_nids = spec->private_dac_nids;
9875 spec->multiout.dac_nids[0] = 2;
9877 nid = cfg->line_out_pins[0];
9879 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9880 "Front Playback Volume",
9881 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9884 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9885 "Front Playback Switch",
9886 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9891 nid = cfg->speaker_pins[0];
9894 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9895 "Speaker Playback Volume",
9896 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9900 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9901 "Speaker Playback Switch",
9902 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9907 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9908 "Speaker Playback Switch",
9909 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9915 nid = cfg->hp_pins[0];
9917 /* spec->multiout.hp_nid = 2; */
9919 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9920 "Headphone Playback Volume",
9921 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9925 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9926 "Headphone Playback Switch",
9927 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9932 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9933 "Headphone Playback Switch",
9934 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9943 /* identical with ALC880 */
9944 #define alc262_auto_create_analog_input_ctls \
9945 alc880_auto_create_analog_input_ctls
9948 * generic initialization of ADC, input mixers and output mixers
9950 static struct hda_verb alc262_volume_init_verbs[] = {
9952 * Unmute ADC0-2 and set the default input to mic-in
9954 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9955 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9956 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9957 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9958 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9961 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9963 * Note: PASD motherboards uses the Line In 2 as the input for
9964 * front panel mic (mic 2)
9966 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9967 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9968 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9969 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9970 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9971 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9974 * Set up output mixers (0x0c - 0x0f)
9976 /* set vol=0 to output mixers */
9977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9978 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9979 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9981 /* set up input amps for analog loopback */
9982 /* Amp Indices: DAC = 0, mixer = 1 */
9983 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9984 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9985 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9986 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9987 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9988 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9990 /* FIXME: use matrix-type input source selection */
9991 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9992 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9998 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9999 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10003 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10011 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10013 * Unmute ADC0-2 and set the default input to mic-in
10015 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10017 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10019 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10022 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10024 * Note: PASD motherboards uses the Line In 2 as the input for
10025 * front panel mic (mic 2)
10027 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10028 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10029 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10030 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10031 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10032 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10033 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10034 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10037 * Set up output mixers (0x0c - 0x0e)
10039 /* set vol=0 to output mixers */
10040 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10042 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10044 /* set up input amps for analog loopback */
10045 /* Amp Indices: DAC = 0, mixer = 1 */
10046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10048 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10050 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10053 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10055 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10058 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10060 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10061 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10064 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10065 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10066 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10067 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10069 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10070 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10071 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10073 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10074 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10077 /* FIXME: use matrix-type input source selection */
10078 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10079 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10081 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10082 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10083 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10085 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10086 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10087 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10088 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10090 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10091 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10092 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10093 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10095 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10100 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10102 * Unmute ADC0-2 and set the default input to mic-in
10104 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10106 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10107 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10108 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10109 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10111 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10113 * Note: PASD motherboards uses the Line In 2 as the input for front
10114 * panel mic (mic 2)
10116 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10122 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10123 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10124 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10126 * Set up output mixers (0x0c - 0x0e)
10128 /* set vol=0 to output mixers */
10129 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10130 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10131 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10133 /* set up input amps for analog loopback */
10134 /* Amp Indices: DAC = 0, mixer = 1 */
10135 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10137 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10138 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10139 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10140 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10143 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10144 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10145 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10146 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10147 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10149 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10151 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10152 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10154 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10155 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10157 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10158 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10159 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10160 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10161 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10162 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10164 /* FIXME: use matrix-type input source selection */
10165 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10166 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10167 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10168 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10169 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10170 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10171 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10172 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10173 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10175 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10176 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10177 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10178 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10179 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10180 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10183 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10184 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10185 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10186 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10187 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10188 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10189 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10191 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10196 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10198 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10199 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10200 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10202 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10203 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10204 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10205 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10207 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10208 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10209 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10214 #ifdef CONFIG_SND_HDA_POWER_SAVE
10215 #define alc262_loopbacks alc880_loopbacks
10218 /* pcm configuration: identiacal with ALC880 */
10219 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10220 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10221 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10222 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10225 * BIOS auto configuration
10227 static int alc262_parse_auto_config(struct hda_codec *codec)
10229 struct alc_spec *spec = codec->spec;
10231 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10233 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10237 if (!spec->autocfg.line_outs)
10238 return 0; /* can't find valid BIOS pin config */
10239 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10242 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10246 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10248 if (spec->autocfg.dig_out_pin)
10249 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10250 if (spec->autocfg.dig_in_pin)
10251 spec->dig_in_nid = ALC262_DIGIN_NID;
10253 if (spec->kctls.list)
10254 spec->mixers[spec->num_mixers++] = spec->kctls.list;
10256 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
10257 spec->num_mux_defs = 1;
10258 spec->input_mux = &spec->private_imux;
10260 err = alc_auto_add_mic_boost(codec);
10267 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10268 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10269 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10270 #define alc262_auto_init_input_src alc882_auto_init_input_src
10273 /* init callback for auto-configuration model -- overriding the default init */
10274 static void alc262_auto_init(struct hda_codec *codec)
10276 struct alc_spec *spec = codec->spec;
10277 alc262_auto_init_multi_out(codec);
10278 alc262_auto_init_hp_out(codec);
10279 alc262_auto_init_analog_input(codec);
10280 alc262_auto_init_input_src(codec);
10281 if (spec->unsol_event)
10282 alc_sku_automute(codec);
10286 * configuration and preset
10288 static const char *alc262_models[ALC262_MODEL_LAST] = {
10289 [ALC262_BASIC] = "basic",
10290 [ALC262_HIPPO] = "hippo",
10291 [ALC262_HIPPO_1] = "hippo_1",
10292 [ALC262_FUJITSU] = "fujitsu",
10293 [ALC262_HP_BPC] = "hp-bpc",
10294 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10295 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10296 [ALC262_HP_RP5700] = "hp-rp5700",
10297 [ALC262_BENQ_ED8] = "benq",
10298 [ALC262_BENQ_T31] = "benq-t31",
10299 [ALC262_SONY_ASSAMD] = "sony-assamd",
10300 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10301 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10302 [ALC262_ULTRA] = "ultra",
10303 [ALC262_LENOVO_3000] = "lenovo-3000",
10304 [ALC262_NEC] = "nec",
10305 [ALC262_AUTO] = "auto",
10308 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10309 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10310 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10311 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10312 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10313 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10314 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10315 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10316 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10317 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10318 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10319 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10320 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10321 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10322 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10323 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10324 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10325 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10326 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10327 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10328 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10329 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10330 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10331 ALC262_HP_TC_T5735),
10332 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10333 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10334 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10335 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10336 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10337 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10338 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10339 ALC262_TOSHIBA_RX1),
10340 SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
10341 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10342 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10343 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10344 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10345 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10346 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10347 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10348 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10352 static struct alc_config_preset alc262_presets[] = {
10354 .mixers = { alc262_base_mixer },
10355 .init_verbs = { alc262_init_verbs },
10356 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10357 .dac_nids = alc262_dac_nids,
10359 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10360 .channel_mode = alc262_modes,
10361 .input_mux = &alc262_capture_source,
10364 .mixers = { alc262_base_mixer },
10365 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10366 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10367 .dac_nids = alc262_dac_nids,
10369 .dig_out_nid = ALC262_DIGOUT_NID,
10370 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10371 .channel_mode = alc262_modes,
10372 .input_mux = &alc262_capture_source,
10373 .unsol_event = alc262_hippo_unsol_event,
10374 .init_hook = alc262_hippo_automute,
10376 [ALC262_HIPPO_1] = {
10377 .mixers = { alc262_hippo1_mixer },
10378 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10379 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10380 .dac_nids = alc262_dac_nids,
10382 .dig_out_nid = ALC262_DIGOUT_NID,
10383 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10384 .channel_mode = alc262_modes,
10385 .input_mux = &alc262_capture_source,
10386 .unsol_event = alc262_hippo1_unsol_event,
10387 .init_hook = alc262_hippo1_automute,
10389 [ALC262_FUJITSU] = {
10390 .mixers = { alc262_fujitsu_mixer },
10391 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10392 alc262_fujitsu_unsol_verbs },
10393 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10394 .dac_nids = alc262_dac_nids,
10396 .dig_out_nid = ALC262_DIGOUT_NID,
10397 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10398 .channel_mode = alc262_modes,
10399 .input_mux = &alc262_fujitsu_capture_source,
10400 .unsol_event = alc262_fujitsu_unsol_event,
10401 .init_hook = alc262_fujitsu_init_hook,
10403 [ALC262_HP_BPC] = {
10404 .mixers = { alc262_HP_BPC_mixer },
10405 .init_verbs = { alc262_HP_BPC_init_verbs },
10406 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10407 .dac_nids = alc262_dac_nids,
10409 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10410 .channel_mode = alc262_modes,
10411 .input_mux = &alc262_HP_capture_source,
10412 .unsol_event = alc262_hp_bpc_unsol_event,
10413 .init_hook = alc262_hp_bpc_automute,
10415 [ALC262_HP_BPC_D7000_WF] = {
10416 .mixers = { alc262_HP_BPC_WildWest_mixer },
10417 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10418 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10419 .dac_nids = alc262_dac_nids,
10421 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10422 .channel_mode = alc262_modes,
10423 .input_mux = &alc262_HP_D7000_capture_source,
10424 .unsol_event = alc262_hp_wildwest_unsol_event,
10425 .init_hook = alc262_hp_wildwest_automute,
10427 [ALC262_HP_BPC_D7000_WL] = {
10428 .mixers = { alc262_HP_BPC_WildWest_mixer,
10429 alc262_HP_BPC_WildWest_option_mixer },
10430 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10431 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10432 .dac_nids = alc262_dac_nids,
10434 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10435 .channel_mode = alc262_modes,
10436 .input_mux = &alc262_HP_D7000_capture_source,
10437 .unsol_event = alc262_hp_wildwest_unsol_event,
10438 .init_hook = alc262_hp_wildwest_automute,
10440 [ALC262_HP_TC_T5735] = {
10441 .mixers = { alc262_hp_t5735_mixer },
10442 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10443 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10444 .dac_nids = alc262_dac_nids,
10446 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10447 .channel_mode = alc262_modes,
10448 .input_mux = &alc262_capture_source,
10449 .unsol_event = alc262_hp_t5735_unsol_event,
10450 .init_hook = alc262_hp_t5735_init_hook,
10452 [ALC262_HP_RP5700] = {
10453 .mixers = { alc262_hp_rp5700_mixer },
10454 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10455 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10456 .dac_nids = alc262_dac_nids,
10457 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10458 .channel_mode = alc262_modes,
10459 .input_mux = &alc262_hp_rp5700_capture_source,
10461 [ALC262_BENQ_ED8] = {
10462 .mixers = { alc262_base_mixer },
10463 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10464 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10465 .dac_nids = alc262_dac_nids,
10467 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10468 .channel_mode = alc262_modes,
10469 .input_mux = &alc262_capture_source,
10471 [ALC262_SONY_ASSAMD] = {
10472 .mixers = { alc262_sony_mixer },
10473 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10474 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10475 .dac_nids = alc262_dac_nids,
10477 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10478 .channel_mode = alc262_modes,
10479 .input_mux = &alc262_capture_source,
10480 .unsol_event = alc262_hippo_unsol_event,
10481 .init_hook = alc262_hippo_automute,
10483 [ALC262_BENQ_T31] = {
10484 .mixers = { alc262_benq_t31_mixer },
10485 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10486 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10487 .dac_nids = alc262_dac_nids,
10489 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10490 .channel_mode = alc262_modes,
10491 .input_mux = &alc262_capture_source,
10492 .unsol_event = alc262_hippo_unsol_event,
10493 .init_hook = alc262_hippo_automute,
10496 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10497 .init_verbs = { alc262_ultra_verbs },
10498 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10499 .dac_nids = alc262_dac_nids,
10500 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10501 .channel_mode = alc262_modes,
10502 .input_mux = &alc262_ultra_capture_source,
10503 .adc_nids = alc262_adc_nids, /* ADC0 */
10504 .capsrc_nids = alc262_capsrc_nids,
10505 .num_adc_nids = 1, /* single ADC */
10506 .unsol_event = alc262_ultra_unsol_event,
10507 .init_hook = alc262_ultra_automute,
10509 [ALC262_LENOVO_3000] = {
10510 .mixers = { alc262_lenovo_3000_mixer },
10511 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10512 alc262_lenovo_3000_unsol_verbs },
10513 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10514 .dac_nids = alc262_dac_nids,
10516 .dig_out_nid = ALC262_DIGOUT_NID,
10517 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10518 .channel_mode = alc262_modes,
10519 .input_mux = &alc262_fujitsu_capture_source,
10520 .unsol_event = alc262_lenovo_3000_unsol_event,
10523 .mixers = { alc262_nec_mixer },
10524 .init_verbs = { alc262_nec_verbs },
10525 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10526 .dac_nids = alc262_dac_nids,
10528 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10529 .channel_mode = alc262_modes,
10530 .input_mux = &alc262_capture_source,
10532 [ALC262_TOSHIBA_S06] = {
10533 .mixers = { alc262_toshiba_s06_mixer },
10534 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10535 alc262_eapd_verbs },
10536 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10537 .capsrc_nids = alc262_dmic_capsrc_nids,
10538 .dac_nids = alc262_dac_nids,
10539 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10540 .dig_out_nid = ALC262_DIGOUT_NID,
10541 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10542 .channel_mode = alc262_modes,
10543 .input_mux = &alc262_dmic_capture_source,
10544 .unsol_event = alc262_toshiba_s06_unsol_event,
10545 .init_hook = alc262_toshiba_s06_init_hook,
10547 [ALC262_TOSHIBA_RX1] = {
10548 .mixers = { alc262_toshiba_rx1_mixer },
10549 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10550 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10551 .dac_nids = alc262_dac_nids,
10553 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10554 .channel_mode = alc262_modes,
10555 .input_mux = &alc262_capture_source,
10556 .unsol_event = alc262_hippo_unsol_event,
10557 .init_hook = alc262_hippo_automute,
10561 static int patch_alc262(struct hda_codec *codec)
10563 struct alc_spec *spec;
10567 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10571 codec->spec = spec;
10573 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10578 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10579 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10580 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10581 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10585 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10587 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10591 if (board_config < 0) {
10592 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10593 "trying auto-probe from BIOS...\n");
10594 board_config = ALC262_AUTO;
10597 if (board_config == ALC262_AUTO) {
10598 /* automatic parse from the BIOS config */
10599 err = alc262_parse_auto_config(codec);
10605 "hda_codec: Cannot set up configuration "
10606 "from BIOS. Using base mode...\n");
10607 board_config = ALC262_BASIC;
10611 if (board_config != ALC262_AUTO)
10612 setup_preset(spec, &alc262_presets[board_config]);
10614 spec->stream_name_analog = "ALC262 Analog";
10615 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10616 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10618 spec->stream_name_digital = "ALC262 Digital";
10619 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10620 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10622 if (!spec->adc_nids && spec->input_mux) {
10623 /* check whether NID 0x07 is valid */
10624 unsigned int wcap = get_wcaps(codec, 0x07);
10627 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10628 if (wcap != AC_WID_AUD_IN) {
10629 spec->adc_nids = alc262_adc_nids_alt;
10630 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10631 spec->capsrc_nids = alc262_capsrc_nids_alt;
10632 spec->mixers[spec->num_mixers] =
10633 alc262_capture_alt_mixer;
10634 spec->num_mixers++;
10636 spec->adc_nids = alc262_adc_nids;
10637 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10638 spec->capsrc_nids = alc262_capsrc_nids;
10639 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10640 spec->num_mixers++;
10644 spec->vmaster_nid = 0x0c;
10646 codec->patch_ops = alc_patch_ops;
10647 if (board_config == ALC262_AUTO)
10648 spec->init_hook = alc262_auto_init;
10649 #ifdef CONFIG_SND_HDA_POWER_SAVE
10650 if (!spec->loopback.amplist)
10651 spec->loopback.amplist = alc262_loopbacks;
10658 * ALC268 channel source setting (2 channel)
10660 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10661 #define alc268_modes alc260_modes
10663 static hda_nid_t alc268_dac_nids[2] = {
10668 static hda_nid_t alc268_adc_nids[2] = {
10673 static hda_nid_t alc268_adc_nids_alt[1] = {
10678 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10680 static struct snd_kcontrol_new alc268_base_mixer[] = {
10681 /* output mixer control */
10682 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10683 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10687 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10688 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10692 /* bind Beep switches of both NID 0x0f and 0x10 */
10693 static struct hda_bind_ctls alc268_bind_beep_sw = {
10694 .ops = &snd_hda_bind_sw,
10696 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10697 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10702 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10703 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10704 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10708 static struct hda_verb alc268_eapd_verbs[] = {
10709 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10710 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10714 /* Toshiba specific */
10715 #define alc268_toshiba_automute alc262_hippo_automute
10717 static struct hda_verb alc268_toshiba_verbs[] = {
10718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10722 static struct hda_input_mux alc268_acer_lc_capture_source = {
10730 /* Acer specific */
10731 /* bind volumes of both NID 0x02 and 0x03 */
10732 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10733 .ops = &snd_hda_bind_vol,
10735 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10736 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10741 /* mute/unmute internal speaker according to the hp jack and mute state */
10742 static void alc268_acer_automute(struct hda_codec *codec, int force)
10744 struct alc_spec *spec = codec->spec;
10747 if (force || !spec->sense_updated) {
10748 unsigned int present;
10749 present = snd_hda_codec_read(codec, 0x14, 0,
10750 AC_VERB_GET_PIN_SENSE, 0);
10751 spec->jack_present = (present & 0x80000000) != 0;
10752 spec->sense_updated = 1;
10754 if (spec->jack_present)
10755 mute = HDA_AMP_MUTE; /* mute internal speaker */
10756 else /* unmute internal speaker if necessary */
10757 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10758 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10759 HDA_AMP_MUTE, mute);
10763 /* bind hp and internal speaker mute (with plug check) */
10764 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10765 struct snd_ctl_elem_value *ucontrol)
10767 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10768 long *valp = ucontrol->value.integer.value;
10771 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10773 valp[0] ? 0 : HDA_AMP_MUTE);
10774 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10776 valp[1] ? 0 : HDA_AMP_MUTE);
10778 alc268_acer_automute(codec, 0);
10782 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10783 /* output mixer control */
10784 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10787 .name = "Master Playback Switch",
10788 .info = snd_hda_mixer_amp_switch_info,
10789 .get = snd_hda_mixer_amp_switch_get,
10790 .put = alc268_acer_master_sw_put,
10791 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10793 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10797 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10798 /* output mixer control */
10799 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10802 .name = "Master Playback Switch",
10803 .info = snd_hda_mixer_amp_switch_info,
10804 .get = snd_hda_mixer_amp_switch_get,
10805 .put = alc268_acer_master_sw_put,
10806 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10808 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10809 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10810 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10814 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10815 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10816 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10817 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10818 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10819 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10824 static struct hda_verb alc268_acer_verbs[] = {
10825 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10826 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10829 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10830 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10831 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10835 /* unsolicited event for HP jack sensing */
10836 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10839 if ((res >> 26) != ALC880_HP_EVENT)
10841 alc268_toshiba_automute(codec);
10844 static void alc268_acer_unsol_event(struct hda_codec *codec,
10847 if ((res >> 26) != ALC880_HP_EVENT)
10849 alc268_acer_automute(codec, 1);
10852 static void alc268_acer_init_hook(struct hda_codec *codec)
10854 alc268_acer_automute(codec, 1);
10857 /* toggle speaker-output according to the hp-jack state */
10858 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10860 unsigned int present;
10861 unsigned char bits;
10863 present = snd_hda_codec_read(codec, 0x15, 0,
10864 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10865 bits = present ? AMP_IN_MUTE(0) : 0;
10866 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10867 AMP_IN_MUTE(0), bits);
10868 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10869 AMP_IN_MUTE(0), bits);
10873 static void alc268_acer_mic_automute(struct hda_codec *codec)
10875 unsigned int present;
10877 present = snd_hda_codec_read(codec, 0x18, 0,
10878 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10879 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10880 present ? 0x0 : 0x6);
10883 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10886 if ((res >> 26) == ALC880_HP_EVENT)
10887 alc268_aspire_one_speaker_automute(codec);
10888 if ((res >> 26) == ALC880_MIC_EVENT)
10889 alc268_acer_mic_automute(codec);
10892 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10894 alc268_aspire_one_speaker_automute(codec);
10895 alc268_acer_mic_automute(codec);
10898 static struct snd_kcontrol_new alc268_dell_mixer[] = {
10899 /* output mixer control */
10900 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10901 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10902 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10903 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10904 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10905 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10909 static struct hda_verb alc268_dell_verbs[] = {
10910 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10911 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10912 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10916 /* mute/unmute internal speaker according to the hp jack and mute state */
10917 static void alc268_dell_automute(struct hda_codec *codec)
10919 unsigned int present;
10922 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10923 if (present & 0x80000000)
10924 mute = HDA_AMP_MUTE;
10926 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10927 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10928 HDA_AMP_MUTE, mute);
10931 static void alc268_dell_unsol_event(struct hda_codec *codec,
10934 if ((res >> 26) != ALC880_HP_EVENT)
10936 alc268_dell_automute(codec);
10939 #define alc268_dell_init_hook alc268_dell_automute
10941 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10943 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10944 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10946 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10947 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10948 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10949 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10953 static struct hda_verb alc267_quanta_il1_verbs[] = {
10954 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10955 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10959 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10961 unsigned int present;
10963 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10964 & AC_PINSENSE_PRESENCE;
10965 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10966 present ? 0 : PIN_OUT);
10969 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10971 unsigned int present;
10973 present = snd_hda_codec_read(codec, 0x18, 0,
10974 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10975 snd_hda_codec_write(codec, 0x23, 0,
10976 AC_VERB_SET_CONNECT_SEL,
10977 present ? 0x00 : 0x01);
10980 static void alc267_quanta_il1_automute(struct hda_codec *codec)
10982 alc267_quanta_il1_hp_automute(codec);
10983 alc267_quanta_il1_mic_automute(codec);
10986 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10989 switch (res >> 26) {
10990 case ALC880_HP_EVENT:
10991 alc267_quanta_il1_hp_automute(codec);
10993 case ALC880_MIC_EVENT:
10994 alc267_quanta_il1_mic_automute(codec);
11000 * generic initialization of ADC, input mixers and output mixers
11002 static struct hda_verb alc268_base_init_verbs[] = {
11003 /* Unmute DAC0-1 and set vol = 0 */
11004 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11005 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11006 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11007 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11008 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11009 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11012 * Set up output mixers (0x0c - 0x0e)
11014 /* set vol=0 to output mixers */
11015 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11016 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11017 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11018 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11021 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11023 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11024 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11025 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11026 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11027 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11028 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11029 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11030 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11032 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11034 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11035 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11036 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11037 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11038 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11040 /* set PCBEEP vol = 0, mute connections */
11041 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11043 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11045 /* Unmute Selector 23h,24h and set the default input to mic-in */
11047 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11048 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11049 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11050 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11056 * generic initialization of ADC, input mixers and output mixers
11058 static struct hda_verb alc268_volume_init_verbs[] = {
11059 /* set output DAC */
11060 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11061 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11062 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11063 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11065 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11066 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11067 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11068 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11069 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11072 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11073 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11074 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11075 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11077 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11079 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11080 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11082 /* set PCBEEP vol = 0, mute connections */
11083 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11084 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11085 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11090 #define alc268_mux_enum_info alc_mux_enum_info
11091 #define alc268_mux_enum_get alc_mux_enum_get
11092 #define alc268_mux_enum_put alc_mux_enum_put
11094 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11095 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11096 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11099 /* The multiple "Capture Source" controls confuse alsamixer
11100 * So call somewhat different..
11102 /* .name = "Capture Source", */
11103 .name = "Input Source",
11105 .info = alc268_mux_enum_info,
11106 .get = alc268_mux_enum_get,
11107 .put = alc268_mux_enum_put,
11112 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11113 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11114 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11115 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11116 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11119 /* The multiple "Capture Source" controls confuse alsamixer
11120 * So call somewhat different..
11122 /* .name = "Capture Source", */
11123 .name = "Input Source",
11125 .info = alc268_mux_enum_info,
11126 .get = alc268_mux_enum_get,
11127 .put = alc268_mux_enum_put,
11132 static struct hda_input_mux alc268_capture_source = {
11136 { "Front Mic", 0x1 },
11142 static struct hda_input_mux alc268_acer_capture_source = {
11146 { "Internal Mic", 0x6 },
11151 #ifdef CONFIG_SND_DEBUG
11152 static struct snd_kcontrol_new alc268_test_mixer[] = {
11153 /* Volume widgets */
11154 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11155 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11156 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11157 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11158 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11159 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11160 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11161 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11162 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11163 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11164 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11165 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11166 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11167 /* The below appears problematic on some hardwares */
11168 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11169 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11170 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11171 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11172 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11174 /* Modes for retasking pin widgets */
11175 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11176 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11177 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11178 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11180 /* Controls for GPIO pins, assuming they are configured as outputs */
11181 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11182 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11183 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11184 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11186 /* Switches to allow the digital SPDIF output pin to be enabled.
11187 * The ALC268 does not have an SPDIF input.
11189 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11191 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11192 * this output to turn on an external amplifier.
11194 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11195 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11201 /* create input playback/capture controls for the given pin */
11202 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11203 const char *ctlname, int idx)
11208 sprintf(name, "%s Playback Volume", ctlname);
11210 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11211 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11215 } else if (nid == 0x15) {
11216 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11217 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11223 sprintf(name, "%s Playback Switch", ctlname);
11224 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11225 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11231 /* add playback controls from the parsed DAC table */
11232 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11233 const struct auto_pin_cfg *cfg)
11238 spec->multiout.num_dacs = 2; /* only use one dac */
11239 spec->multiout.dac_nids = spec->private_dac_nids;
11240 spec->multiout.dac_nids[0] = 2;
11241 spec->multiout.dac_nids[1] = 3;
11243 nid = cfg->line_out_pins[0];
11245 alc268_new_analog_output(spec, nid, "Front", 0);
11247 nid = cfg->speaker_pins[0];
11249 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11250 "Speaker Playback Volume",
11251 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11255 nid = cfg->hp_pins[0];
11257 alc268_new_analog_output(spec, nid, "Headphone", 0);
11259 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11261 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11262 "Mono Playback Switch",
11263 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11270 /* create playback/capture controls for input pins */
11271 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11272 const struct auto_pin_cfg *cfg)
11274 struct hda_input_mux *imux = &spec->private_imux;
11277 for (i = 0; i < AUTO_PIN_LAST; i++) {
11278 switch(cfg->input_pins[i]) {
11280 idx1 = 0; /* Mic 1 */
11283 idx1 = 1; /* Mic 2 */
11286 idx1 = 2; /* Line In */
11293 idx1 = 6; /* digital mics */
11298 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11299 imux->items[imux->num_items].index = idx1;
11305 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11307 struct alc_spec *spec = codec->spec;
11308 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11309 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11310 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11311 unsigned int dac_vol1, dac_vol2;
11314 snd_hda_codec_write(codec, speaker_nid, 0,
11315 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11316 snd_hda_codec_write(codec, 0x0f, 0,
11317 AC_VERB_SET_AMP_GAIN_MUTE,
11319 snd_hda_codec_write(codec, 0x10, 0,
11320 AC_VERB_SET_AMP_GAIN_MUTE,
11323 snd_hda_codec_write(codec, 0x0f, 0,
11324 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11325 snd_hda_codec_write(codec, 0x10, 0,
11326 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11329 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11330 if (line_nid == 0x14)
11331 dac_vol2 = AMP_OUT_ZERO;
11332 else if (line_nid == 0x15)
11333 dac_vol1 = AMP_OUT_ZERO;
11334 if (hp_nid == 0x14)
11335 dac_vol2 = AMP_OUT_ZERO;
11336 else if (hp_nid == 0x15)
11337 dac_vol1 = AMP_OUT_ZERO;
11338 if (line_nid != 0x16 || hp_nid != 0x16 ||
11339 spec->autocfg.line_out_pins[1] != 0x16 ||
11340 spec->autocfg.line_out_pins[2] != 0x16)
11341 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11343 snd_hda_codec_write(codec, 0x02, 0,
11344 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11345 snd_hda_codec_write(codec, 0x03, 0,
11346 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11349 /* pcm configuration: identiacal with ALC880 */
11350 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11351 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11352 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11353 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11356 * BIOS auto configuration
11358 static int alc268_parse_auto_config(struct hda_codec *codec)
11360 struct alc_spec *spec = codec->spec;
11362 static hda_nid_t alc268_ignore[] = { 0 };
11364 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11368 if (!spec->autocfg.line_outs)
11369 return 0; /* can't find valid BIOS pin config */
11371 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11374 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11378 spec->multiout.max_channels = 2;
11380 /* digital only support output */
11381 if (spec->autocfg.dig_out_pin)
11382 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11384 if (spec->kctls.list)
11385 spec->mixers[spec->num_mixers++] = spec->kctls.list;
11387 if (spec->autocfg.speaker_pins[0] != 0x1d)
11388 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11390 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11391 spec->num_mux_defs = 1;
11392 spec->input_mux = &spec->private_imux;
11394 err = alc_auto_add_mic_boost(codec);
11401 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11402 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11403 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11405 /* init callback for auto-configuration model -- overriding the default init */
11406 static void alc268_auto_init(struct hda_codec *codec)
11408 struct alc_spec *spec = codec->spec;
11409 alc268_auto_init_multi_out(codec);
11410 alc268_auto_init_hp_out(codec);
11411 alc268_auto_init_mono_speaker_out(codec);
11412 alc268_auto_init_analog_input(codec);
11413 if (spec->unsol_event)
11414 alc_sku_automute(codec);
11418 * configuration and preset
11420 static const char *alc268_models[ALC268_MODEL_LAST] = {
11421 [ALC267_QUANTA_IL1] = "quanta-il1",
11422 [ALC268_3ST] = "3stack",
11423 [ALC268_TOSHIBA] = "toshiba",
11424 [ALC268_ACER] = "acer",
11425 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11426 [ALC268_DELL] = "dell",
11427 [ALC268_ZEPTO] = "zepto",
11428 #ifdef CONFIG_SND_DEBUG
11429 [ALC268_TEST] = "test",
11431 [ALC268_AUTO] = "auto",
11434 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11435 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11436 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11437 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11438 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11439 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11440 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11441 ALC268_ACER_ASPIRE_ONE),
11442 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11443 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11444 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11445 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11446 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11447 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11448 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11449 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11450 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11451 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11455 static struct alc_config_preset alc268_presets[] = {
11456 [ALC267_QUANTA_IL1] = {
11457 .mixers = { alc267_quanta_il1_mixer },
11458 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11459 alc267_quanta_il1_verbs },
11460 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11461 .dac_nids = alc268_dac_nids,
11462 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11463 .adc_nids = alc268_adc_nids_alt,
11465 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11466 .channel_mode = alc268_modes,
11467 .input_mux = &alc268_capture_source,
11468 .unsol_event = alc267_quanta_il1_unsol_event,
11469 .init_hook = alc267_quanta_il1_automute,
11472 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11473 alc268_beep_mixer },
11474 .init_verbs = { alc268_base_init_verbs },
11475 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11476 .dac_nids = alc268_dac_nids,
11477 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11478 .adc_nids = alc268_adc_nids_alt,
11479 .capsrc_nids = alc268_capsrc_nids,
11481 .dig_out_nid = ALC268_DIGOUT_NID,
11482 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11483 .channel_mode = alc268_modes,
11484 .input_mux = &alc268_capture_source,
11486 [ALC268_TOSHIBA] = {
11487 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11488 alc268_beep_mixer },
11489 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11490 alc268_toshiba_verbs },
11491 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11492 .dac_nids = alc268_dac_nids,
11493 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11494 .adc_nids = alc268_adc_nids_alt,
11495 .capsrc_nids = alc268_capsrc_nids,
11497 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11498 .channel_mode = alc268_modes,
11499 .input_mux = &alc268_capture_source,
11500 .unsol_event = alc268_toshiba_unsol_event,
11501 .init_hook = alc268_toshiba_automute,
11504 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11505 alc268_beep_mixer },
11506 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11507 alc268_acer_verbs },
11508 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11509 .dac_nids = alc268_dac_nids,
11510 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11511 .adc_nids = alc268_adc_nids_alt,
11512 .capsrc_nids = alc268_capsrc_nids,
11514 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11515 .channel_mode = alc268_modes,
11516 .input_mux = &alc268_acer_capture_source,
11517 .unsol_event = alc268_acer_unsol_event,
11518 .init_hook = alc268_acer_init_hook,
11520 [ALC268_ACER_ASPIRE_ONE] = {
11521 .mixers = { alc268_acer_aspire_one_mixer,
11522 alc268_capture_alt_mixer },
11523 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11524 alc268_acer_aspire_one_verbs },
11525 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11526 .dac_nids = alc268_dac_nids,
11527 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11528 .adc_nids = alc268_adc_nids_alt,
11529 .capsrc_nids = alc268_capsrc_nids,
11531 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11532 .channel_mode = alc268_modes,
11533 .input_mux = &alc268_acer_lc_capture_source,
11534 .unsol_event = alc268_acer_lc_unsol_event,
11535 .init_hook = alc268_acer_lc_init_hook,
11538 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11539 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11540 alc268_dell_verbs },
11541 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11542 .dac_nids = alc268_dac_nids,
11544 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11545 .channel_mode = alc268_modes,
11546 .unsol_event = alc268_dell_unsol_event,
11547 .init_hook = alc268_dell_init_hook,
11548 .input_mux = &alc268_capture_source,
11551 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11552 alc268_beep_mixer },
11553 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11554 alc268_toshiba_verbs },
11555 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11556 .dac_nids = alc268_dac_nids,
11557 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11558 .adc_nids = alc268_adc_nids_alt,
11559 .capsrc_nids = alc268_capsrc_nids,
11561 .dig_out_nid = ALC268_DIGOUT_NID,
11562 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11563 .channel_mode = alc268_modes,
11564 .input_mux = &alc268_capture_source,
11565 .unsol_event = alc268_toshiba_unsol_event,
11566 .init_hook = alc268_toshiba_automute
11568 #ifdef CONFIG_SND_DEBUG
11570 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11571 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11572 alc268_volume_init_verbs },
11573 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11574 .dac_nids = alc268_dac_nids,
11575 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11576 .adc_nids = alc268_adc_nids_alt,
11577 .capsrc_nids = alc268_capsrc_nids,
11579 .dig_out_nid = ALC268_DIGOUT_NID,
11580 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11581 .channel_mode = alc268_modes,
11582 .input_mux = &alc268_capture_source,
11587 static int patch_alc268(struct hda_codec *codec)
11589 struct alc_spec *spec;
11593 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11597 codec->spec = spec;
11599 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11603 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11604 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11605 "trying auto-probe from BIOS...\n");
11606 board_config = ALC268_AUTO;
11609 if (board_config == ALC268_AUTO) {
11610 /* automatic parse from the BIOS config */
11611 err = alc268_parse_auto_config(codec);
11617 "hda_codec: Cannot set up configuration "
11618 "from BIOS. Using base mode...\n");
11619 board_config = ALC268_3ST;
11623 if (board_config != ALC268_AUTO)
11624 setup_preset(spec, &alc268_presets[board_config]);
11626 if (codec->vendor_id == 0x10ec0267) {
11627 spec->stream_name_analog = "ALC267 Analog";
11628 spec->stream_name_digital = "ALC267 Digital";
11630 spec->stream_name_analog = "ALC268 Analog";
11631 spec->stream_name_digital = "ALC268 Digital";
11634 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11635 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11636 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11638 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11640 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11641 /* override the amp caps for beep generator */
11642 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11643 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11644 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11645 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11646 (0 << AC_AMPCAP_MUTE_SHIFT));
11648 if (!spec->adc_nids && spec->input_mux) {
11649 /* check whether NID 0x07 is valid */
11650 unsigned int wcap = get_wcaps(codec, 0x07);
11654 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11655 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11656 spec->adc_nids = alc268_adc_nids_alt;
11657 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11658 spec->mixers[spec->num_mixers] =
11659 alc268_capture_alt_mixer;
11660 spec->num_mixers++;
11662 spec->adc_nids = alc268_adc_nids;
11663 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11664 spec->mixers[spec->num_mixers] =
11665 alc268_capture_mixer;
11666 spec->num_mixers++;
11668 spec->capsrc_nids = alc268_capsrc_nids;
11669 /* set default input source */
11670 for (i = 0; i < spec->num_adc_nids; i++)
11671 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11672 0, AC_VERB_SET_CONNECT_SEL,
11673 spec->input_mux->items[0].index);
11676 spec->vmaster_nid = 0x02;
11678 codec->patch_ops = alc_patch_ops;
11679 if (board_config == ALC268_AUTO)
11680 spec->init_hook = alc268_auto_init;
11686 * ALC269 channel source setting (2 channel)
11688 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11690 #define alc269_dac_nids alc260_dac_nids
11692 static hda_nid_t alc269_adc_nids[1] = {
11697 static hda_nid_t alc269_capsrc_nids[1] = {
11701 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11705 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11713 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11721 #define alc269_modes alc260_modes
11722 #define alc269_capture_source alc880_lg_lw_capture_source
11724 static struct snd_kcontrol_new alc269_base_mixer[] = {
11725 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11726 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11727 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11728 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11731 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11732 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11733 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11734 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11735 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11736 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11738 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11742 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11743 /* output mixer control */
11744 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11747 .name = "Master Playback Switch",
11748 .info = snd_hda_mixer_amp_switch_info,
11749 .get = snd_hda_mixer_amp_switch_get,
11750 .put = alc268_acer_master_sw_put,
11751 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11753 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11755 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11756 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11757 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11758 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11759 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11760 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11764 /* bind volumes of both NID 0x0c and 0x0d */
11765 static struct hda_bind_ctls alc269_epc_bind_vol = {
11766 .ops = &snd_hda_bind_vol,
11768 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11769 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11774 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11775 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11776 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11777 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11781 /* capture mixer elements */
11782 static struct snd_kcontrol_new alc269_capture_mixer[] = {
11783 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11784 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11787 /* The multiple "Capture Source" controls confuse alsamixer
11788 * So call somewhat different..
11790 /* .name = "Capture Source", */
11791 .name = "Input Source",
11793 .info = alc_mux_enum_info,
11794 .get = alc_mux_enum_get,
11795 .put = alc_mux_enum_put,
11800 /* capture mixer elements */
11801 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11802 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11803 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11808 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11809 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11810 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11814 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11815 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11816 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11818 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11819 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11820 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11824 /* toggle speaker-output according to the hp-jack state */
11825 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11827 unsigned int present;
11828 unsigned char bits;
11830 present = snd_hda_codec_read(codec, 0x15, 0,
11831 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11832 bits = present ? AMP_IN_MUTE(0) : 0;
11833 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11834 AMP_IN_MUTE(0), bits);
11835 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11836 AMP_IN_MUTE(0), bits);
11838 snd_hda_codec_write(codec, 0x20, 0,
11839 AC_VERB_SET_COEF_INDEX, 0x0c);
11840 snd_hda_codec_write(codec, 0x20, 0,
11841 AC_VERB_SET_PROC_COEF, 0x680);
11843 snd_hda_codec_write(codec, 0x20, 0,
11844 AC_VERB_SET_COEF_INDEX, 0x0c);
11845 snd_hda_codec_write(codec, 0x20, 0,
11846 AC_VERB_SET_PROC_COEF, 0x480);
11849 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11851 unsigned int present;
11853 present = snd_hda_codec_read(codec, 0x18, 0,
11854 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11855 snd_hda_codec_write(codec, 0x23, 0,
11856 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11859 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11862 if ((res >> 26) == ALC880_HP_EVENT)
11863 alc269_quanta_fl1_speaker_automute(codec);
11864 if ((res >> 26) == ALC880_MIC_EVENT)
11865 alc269_quanta_fl1_mic_automute(codec);
11868 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11870 alc269_quanta_fl1_speaker_automute(codec);
11871 alc269_quanta_fl1_mic_automute(codec);
11874 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11875 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11876 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11877 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11878 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11879 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11880 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11881 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11885 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11886 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11887 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11888 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11889 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11890 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11891 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11895 /* toggle speaker-output according to the hp-jack state */
11896 static void alc269_speaker_automute(struct hda_codec *codec)
11898 unsigned int present;
11899 unsigned char bits;
11901 present = snd_hda_codec_read(codec, 0x15, 0,
11902 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11903 bits = present ? AMP_IN_MUTE(0) : 0;
11904 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11905 AMP_IN_MUTE(0), bits);
11906 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11907 AMP_IN_MUTE(0), bits);
11910 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11912 unsigned int present;
11914 present = snd_hda_codec_read(codec, 0x18, 0,
11915 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11916 snd_hda_codec_write(codec, 0x23, 0,
11917 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
11920 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11922 unsigned int present;
11924 present = snd_hda_codec_read(codec, 0x18, 0,
11925 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11926 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11927 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11928 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11929 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11932 /* unsolicited event for HP jack sensing */
11933 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11936 if ((res >> 26) == ALC880_HP_EVENT)
11937 alc269_speaker_automute(codec);
11939 if ((res >> 26) == ALC880_MIC_EVENT)
11940 alc269_eeepc_dmic_automute(codec);
11943 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11945 alc269_speaker_automute(codec);
11946 alc269_eeepc_dmic_automute(codec);
11949 /* unsolicited event for HP jack sensing */
11950 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11953 if ((res >> 26) == ALC880_HP_EVENT)
11954 alc269_speaker_automute(codec);
11956 if ((res >> 26) == ALC880_MIC_EVENT)
11957 alc269_eeepc_amic_automute(codec);
11960 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11962 alc269_speaker_automute(codec);
11963 alc269_eeepc_amic_automute(codec);
11967 * generic initialization of ADC, input mixers and output mixers
11969 static struct hda_verb alc269_init_verbs[] = {
11971 * Unmute ADC0 and set the default input to mic-in
11973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11975 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11976 * analog-loopback mixer widget
11977 * Note: PASD motherboards uses the Line In 2 as the input for
11978 * front panel mic (mic 2)
11980 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11981 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11982 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11983 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11988 * Set up output mixers (0x0c - 0x0e)
11990 /* set vol=0 to output mixers */
11991 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11992 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11994 /* set up input amps for analog loopback */
11995 /* Amp Indices: DAC = 0, mixer = 1 */
11996 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11998 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12000 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12001 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12006 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12007 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12008 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12009 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12013 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12014 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12015 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12016 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12017 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12019 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12020 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12022 /* FIXME: use matrix-type input source selection */
12023 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12024 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12031 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12032 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12036 /* add playback controls from the parsed DAC table */
12037 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12038 const struct auto_pin_cfg *cfg)
12043 spec->multiout.num_dacs = 1; /* only use one dac */
12044 spec->multiout.dac_nids = spec->private_dac_nids;
12045 spec->multiout.dac_nids[0] = 2;
12047 nid = cfg->line_out_pins[0];
12049 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12050 "Front Playback Volume",
12051 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12054 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12055 "Front Playback Switch",
12056 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12061 nid = cfg->speaker_pins[0];
12063 if (!cfg->line_out_pins[0]) {
12064 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12065 "Speaker Playback Volume",
12066 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12072 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12073 "Speaker Playback Switch",
12074 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12079 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12080 "Speaker Playback Switch",
12081 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12087 nid = cfg->hp_pins[0];
12089 /* spec->multiout.hp_nid = 2; */
12090 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12091 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12092 "Headphone Playback Volume",
12093 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12099 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12100 "Headphone Playback Switch",
12101 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12106 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12107 "Headphone Playback Switch",
12108 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12117 #define alc269_auto_create_analog_input_ctls \
12118 alc880_auto_create_analog_input_ctls
12120 #ifdef CONFIG_SND_HDA_POWER_SAVE
12121 #define alc269_loopbacks alc880_loopbacks
12124 /* pcm configuration: identiacal with ALC880 */
12125 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12126 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12127 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12128 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12131 * BIOS auto configuration
12133 static int alc269_parse_auto_config(struct hda_codec *codec)
12135 struct alc_spec *spec = codec->spec;
12137 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12139 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12144 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12147 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12151 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12153 if (spec->autocfg.dig_out_pin)
12154 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12156 if (spec->kctls.list)
12157 spec->mixers[spec->num_mixers++] = spec->kctls.list;
12159 /* create a beep mixer control if the pin 0x1d isn't assigned */
12160 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12161 if (spec->autocfg.input_pins[i] == 0x1d)
12163 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12164 spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12166 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12167 spec->num_mux_defs = 1;
12168 spec->input_mux = &spec->private_imux;
12169 /* set default input source */
12170 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12171 0, AC_VERB_SET_CONNECT_SEL,
12172 spec->input_mux->items[0].index);
12174 err = alc_auto_add_mic_boost(codec);
12178 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12179 spec->num_mixers++;
12184 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12185 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12186 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12189 /* init callback for auto-configuration model -- overriding the default init */
12190 static void alc269_auto_init(struct hda_codec *codec)
12192 struct alc_spec *spec = codec->spec;
12193 alc269_auto_init_multi_out(codec);
12194 alc269_auto_init_hp_out(codec);
12195 alc269_auto_init_analog_input(codec);
12196 if (spec->unsol_event)
12197 alc_sku_automute(codec);
12201 * configuration and preset
12203 static const char *alc269_models[ALC269_MODEL_LAST] = {
12204 [ALC269_BASIC] = "basic",
12205 [ALC269_QUANTA_FL1] = "quanta",
12206 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12207 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901"
12210 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12211 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12212 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12213 ALC269_ASUS_EEEPC_P703),
12214 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12215 ALC269_ASUS_EEEPC_P901),
12216 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12217 ALC269_ASUS_EEEPC_P901),
12221 static struct alc_config_preset alc269_presets[] = {
12223 .mixers = { alc269_base_mixer, alc269_capture_mixer },
12224 .init_verbs = { alc269_init_verbs },
12225 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12226 .dac_nids = alc269_dac_nids,
12228 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12229 .channel_mode = alc269_modes,
12230 .input_mux = &alc269_capture_source,
12232 [ALC269_QUANTA_FL1] = {
12233 .mixers = { alc269_quanta_fl1_mixer },
12234 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12235 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12236 .dac_nids = alc269_dac_nids,
12238 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12239 .channel_mode = alc269_modes,
12240 .input_mux = &alc269_capture_source,
12241 .unsol_event = alc269_quanta_fl1_unsol_event,
12242 .init_hook = alc269_quanta_fl1_init_hook,
12244 [ALC269_ASUS_EEEPC_P703] = {
12245 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12246 .init_verbs = { alc269_init_verbs,
12247 alc269_eeepc_amic_init_verbs },
12248 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12249 .dac_nids = alc269_dac_nids,
12251 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12252 .channel_mode = alc269_modes,
12253 .input_mux = &alc269_eeepc_amic_capture_source,
12254 .unsol_event = alc269_eeepc_amic_unsol_event,
12255 .init_hook = alc269_eeepc_amic_inithook,
12257 [ALC269_ASUS_EEEPC_P901] = {
12258 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12259 .init_verbs = { alc269_init_verbs,
12260 alc269_eeepc_dmic_init_verbs },
12261 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12262 .dac_nids = alc269_dac_nids,
12264 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12265 .channel_mode = alc269_modes,
12266 .input_mux = &alc269_eeepc_dmic_capture_source,
12267 .unsol_event = alc269_eeepc_dmic_unsol_event,
12268 .init_hook = alc269_eeepc_dmic_inithook,
12272 static int patch_alc269(struct hda_codec *codec)
12274 struct alc_spec *spec;
12278 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12282 codec->spec = spec;
12284 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12286 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12290 if (board_config < 0) {
12291 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12292 "trying auto-probe from BIOS...\n");
12293 board_config = ALC269_AUTO;
12296 if (board_config == ALC269_AUTO) {
12297 /* automatic parse from the BIOS config */
12298 err = alc269_parse_auto_config(codec);
12304 "hda_codec: Cannot set up configuration "
12305 "from BIOS. Using base mode...\n");
12306 board_config = ALC269_BASIC;
12310 if (board_config != ALC269_AUTO)
12311 setup_preset(spec, &alc269_presets[board_config]);
12313 spec->stream_name_analog = "ALC269 Analog";
12314 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12315 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12317 spec->stream_name_digital = "ALC269 Digital";
12318 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12319 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12321 spec->adc_nids = alc269_adc_nids;
12322 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12323 spec->capsrc_nids = alc269_capsrc_nids;
12325 codec->patch_ops = alc_patch_ops;
12326 if (board_config == ALC269_AUTO)
12327 spec->init_hook = alc269_auto_init;
12328 #ifdef CONFIG_SND_HDA_POWER_SAVE
12329 if (!spec->loopback.amplist)
12330 spec->loopback.amplist = alc269_loopbacks;
12337 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12341 * set the path ways for 2 channel output
12342 * need to set the codec line out and mic 1 pin widgets to inputs
12344 static struct hda_verb alc861_threestack_ch2_init[] = {
12345 /* set pin widget 1Ah (line in) for input */
12346 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12347 /* set pin widget 18h (mic1/2) for input, for mic also enable
12350 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12352 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12354 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12355 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12361 * need to set the codec line out and mic 1 pin widgets to outputs
12363 static struct hda_verb alc861_threestack_ch6_init[] = {
12364 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12365 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12366 /* set pin widget 18h (mic1) for output (CLFE)*/
12367 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12369 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12370 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12372 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12374 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12375 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12380 static struct hda_channel_mode alc861_threestack_modes[2] = {
12381 { 2, alc861_threestack_ch2_init },
12382 { 6, alc861_threestack_ch6_init },
12384 /* Set mic1 as input and unmute the mixer */
12385 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12386 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12390 /* Set mic1 as output and mute mixer */
12391 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12392 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12393 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12397 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12398 { 2, alc861_uniwill_m31_ch2_init },
12399 { 4, alc861_uniwill_m31_ch4_init },
12402 /* Set mic1 and line-in as input and unmute the mixer */
12403 static struct hda_verb alc861_asus_ch2_init[] = {
12404 /* set pin widget 1Ah (line in) for input */
12405 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12406 /* set pin widget 18h (mic1/2) for input, for mic also enable
12409 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12411 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12413 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12414 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12418 /* Set mic1 nad line-in as output and mute mixer */
12419 static struct hda_verb alc861_asus_ch6_init[] = {
12420 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12421 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12422 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12423 /* set pin widget 18h (mic1) for output (CLFE)*/
12424 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12425 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12426 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12427 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12429 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12431 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12432 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12437 static struct hda_channel_mode alc861_asus_modes[2] = {
12438 { 2, alc861_asus_ch2_init },
12439 { 6, alc861_asus_ch6_init },
12444 static struct snd_kcontrol_new alc861_base_mixer[] = {
12445 /* output mixer control */
12446 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12447 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12448 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12449 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12450 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12452 /*Input mixer control */
12453 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12454 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12455 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12456 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12457 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12458 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12460 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12461 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12464 /* Capture mixer control */
12465 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12466 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12468 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12469 .name = "Capture Source",
12471 .info = alc_mux_enum_info,
12472 .get = alc_mux_enum_get,
12473 .put = alc_mux_enum_put,
12478 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12479 /* output mixer control */
12480 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12481 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12482 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12483 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12484 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12486 /* Input mixer control */
12487 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12488 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12489 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12490 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12491 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12492 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12494 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12495 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12496 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12498 /* Capture mixer control */
12499 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12500 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12503 .name = "Capture Source",
12505 .info = alc_mux_enum_info,
12506 .get = alc_mux_enum_get,
12507 .put = alc_mux_enum_put,
12510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12511 .name = "Channel Mode",
12512 .info = alc_ch_mode_info,
12513 .get = alc_ch_mode_get,
12514 .put = alc_ch_mode_put,
12515 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12520 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12521 /* output mixer control */
12522 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12523 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12524 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12526 /*Capture mixer control */
12527 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12528 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12531 .name = "Capture Source",
12533 .info = alc_mux_enum_info,
12534 .get = alc_mux_enum_get,
12535 .put = alc_mux_enum_put,
12541 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12542 /* output mixer control */
12543 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12544 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12545 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12546 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12547 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12549 /* Input mixer control */
12550 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12551 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12552 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12553 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12554 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12555 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12557 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12559 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12561 /* Capture mixer control */
12562 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12563 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12566 .name = "Capture Source",
12568 .info = alc_mux_enum_info,
12569 .get = alc_mux_enum_get,
12570 .put = alc_mux_enum_put,
12573 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12574 .name = "Channel Mode",
12575 .info = alc_ch_mode_info,
12576 .get = alc_ch_mode_get,
12577 .put = alc_ch_mode_put,
12578 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12583 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12584 /* output mixer control */
12585 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12586 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12587 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12588 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12589 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12591 /* Input mixer control */
12592 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12593 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12594 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12595 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12596 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12597 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12599 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12600 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12601 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12603 /* Capture mixer control */
12604 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12605 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12608 .name = "Capture Source",
12610 .info = alc_mux_enum_info,
12611 .get = alc_mux_enum_get,
12612 .put = alc_mux_enum_put,
12615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12616 .name = "Channel Mode",
12617 .info = alc_ch_mode_info,
12618 .get = alc_ch_mode_get,
12619 .put = alc_ch_mode_put,
12620 .private_value = ARRAY_SIZE(alc861_asus_modes),
12625 /* additional mixer */
12626 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12627 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12628 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12629 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12630 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12635 * generic initialization of ADC, input mixers and output mixers
12637 static struct hda_verb alc861_base_init_verbs[] = {
12639 * Unmute ADC0 and set the default input to mic-in
12641 /* port-A for surround (rear panel) */
12642 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12643 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12644 /* port-B for mic-in (rear panel) with vref */
12645 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12646 /* port-C for line-in (rear panel) */
12647 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12648 /* port-D for Front */
12649 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12650 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12651 /* port-E for HP out (front panel) */
12652 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12653 /* route front PCM to HP */
12654 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12655 /* port-F for mic-in (front panel) with vref */
12656 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12657 /* port-G for CLFE (rear panel) */
12658 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12659 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12660 /* port-H for side (rear panel) */
12661 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12662 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12664 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12665 /* route front mic to ADC1*/
12666 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12669 /* Unmute DAC0~3 & spdif out*/
12670 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12671 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12672 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12673 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12676 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12677 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12678 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12679 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12680 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12682 /* Unmute Stereo Mixer 15 */
12683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12688 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12689 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12690 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12691 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12696 /* hp used DAC 3 (Front) */
12697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12698 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12703 static struct hda_verb alc861_threestack_init_verbs[] = {
12705 * Unmute ADC0 and set the default input to mic-in
12707 /* port-A for surround (rear panel) */
12708 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12709 /* port-B for mic-in (rear panel) with vref */
12710 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12711 /* port-C for line-in (rear panel) */
12712 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12713 /* port-D for Front */
12714 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12715 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12716 /* port-E for HP out (front panel) */
12717 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12718 /* route front PCM to HP */
12719 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12720 /* port-F for mic-in (front panel) with vref */
12721 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12722 /* port-G for CLFE (rear panel) */
12723 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12724 /* port-H for side (rear panel) */
12725 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12727 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12728 /* route front mic to ADC1*/
12729 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12730 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12731 /* Unmute DAC0~3 & spdif out*/
12732 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12733 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12734 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12735 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12736 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12738 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12739 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12740 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12741 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12742 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12744 /* Unmute Stereo Mixer 15 */
12745 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12746 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12747 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12750 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12752 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12753 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12755 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12756 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12758 /* hp used DAC 3 (Front) */
12759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12764 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12766 * Unmute ADC0 and set the default input to mic-in
12768 /* port-A for surround (rear panel) */
12769 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12770 /* port-B for mic-in (rear panel) with vref */
12771 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12772 /* port-C for line-in (rear panel) */
12773 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12774 /* port-D for Front */
12775 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12776 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12777 /* port-E for HP out (front panel) */
12778 /* this has to be set to VREF80 */
12779 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12780 /* route front PCM to HP */
12781 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12782 /* port-F for mic-in (front panel) with vref */
12783 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12784 /* port-G for CLFE (rear panel) */
12785 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12786 /* port-H for side (rear panel) */
12787 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12789 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12790 /* route front mic to ADC1*/
12791 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12792 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12793 /* Unmute DAC0~3 & spdif out*/
12794 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12795 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12796 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12797 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12798 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12800 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12801 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12802 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12803 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12804 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12806 /* Unmute Stereo Mixer 15 */
12807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12808 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12812 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12813 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12814 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12815 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12816 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12817 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12819 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12820 /* hp used DAC 3 (Front) */
12821 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12822 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12826 static struct hda_verb alc861_asus_init_verbs[] = {
12828 * Unmute ADC0 and set the default input to mic-in
12830 /* port-A for surround (rear panel)
12831 * according to codec#0 this is the HP jack
12833 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12834 /* route front PCM to HP */
12835 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12836 /* port-B for mic-in (rear panel) with vref */
12837 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12838 /* port-C for line-in (rear panel) */
12839 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12840 /* port-D for Front */
12841 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12842 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12843 /* port-E for HP out (front panel) */
12844 /* this has to be set to VREF80 */
12845 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12846 /* route front PCM to HP */
12847 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12848 /* port-F for mic-in (front panel) with vref */
12849 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12850 /* port-G for CLFE (rear panel) */
12851 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12852 /* port-H for side (rear panel) */
12853 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12855 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12856 /* route front mic to ADC1*/
12857 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12858 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12859 /* Unmute DAC0~3 & spdif out*/
12860 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12861 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12862 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12863 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12865 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12866 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12867 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12868 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12869 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12871 /* Unmute Stereo Mixer 15 */
12872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12874 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12875 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12877 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12878 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12879 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12880 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12881 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12882 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12883 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12884 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12885 /* hp used DAC 3 (Front) */
12886 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12887 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12891 /* additional init verbs for ASUS laptops */
12892 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12893 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12894 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12899 * generic initialization of ADC, input mixers and output mixers
12901 static struct hda_verb alc861_auto_init_verbs[] = {
12903 * Unmute ADC0 and set the default input to mic-in
12905 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12906 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12908 /* Unmute DAC0~3 & spdif out*/
12909 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12910 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12911 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12912 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12915 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12916 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12917 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12918 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12919 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12921 /* Unmute Stereo Mixer 15 */
12922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12923 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12925 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12927 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12928 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12929 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12930 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12931 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12932 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12933 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12934 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12936 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12937 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12938 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12939 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12940 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12941 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12942 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12943 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12945 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
12950 static struct hda_verb alc861_toshiba_init_verbs[] = {
12951 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12956 /* toggle speaker-output according to the hp-jack state */
12957 static void alc861_toshiba_automute(struct hda_codec *codec)
12959 unsigned int present;
12961 present = snd_hda_codec_read(codec, 0x0f, 0,
12962 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12963 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12964 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12965 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12966 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12969 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12972 if ((res >> 26) == ALC880_HP_EVENT)
12973 alc861_toshiba_automute(codec);
12976 /* pcm configuration: identiacal with ALC880 */
12977 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
12978 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
12979 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
12980 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
12983 #define ALC861_DIGOUT_NID 0x07
12985 static struct hda_channel_mode alc861_8ch_modes[1] = {
12989 static hda_nid_t alc861_dac_nids[4] = {
12990 /* front, surround, clfe, side */
12991 0x03, 0x06, 0x05, 0x04
12994 static hda_nid_t alc660_dac_nids[3] = {
12995 /* front, clfe, surround */
12999 static hda_nid_t alc861_adc_nids[1] = {
13004 static struct hda_input_mux alc861_capture_source = {
13008 { "Front Mic", 0x3 },
13015 /* fill in the dac_nids table from the parsed pin configuration */
13016 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13017 const struct auto_pin_cfg *cfg)
13022 spec->multiout.dac_nids = spec->private_dac_nids;
13023 for (i = 0; i < cfg->line_outs; i++) {
13024 nid = cfg->line_out_pins[i];
13026 if (i >= ARRAY_SIZE(alc861_dac_nids))
13028 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13031 spec->multiout.num_dacs = cfg->line_outs;
13035 /* add playback controls from the parsed DAC table */
13036 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13037 const struct auto_pin_cfg *cfg)
13040 static const char *chname[4] = {
13041 "Front", "Surround", NULL /*CLFE*/, "Side"
13046 for (i = 0; i < cfg->line_outs; i++) {
13047 nid = spec->multiout.dac_nids[i];
13052 err = add_control(spec, ALC_CTL_BIND_MUTE,
13053 "Center Playback Switch",
13054 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13058 err = add_control(spec, ALC_CTL_BIND_MUTE,
13059 "LFE Playback Switch",
13060 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13065 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13067 if (nid == alc861_dac_nids[idx])
13069 sprintf(name, "%s Playback Switch", chname[idx]);
13070 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13071 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13080 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13088 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13090 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13091 "Headphone Playback Switch",
13092 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13095 spec->multiout.hp_nid = nid;
13100 /* create playback/capture controls for input pins */
13101 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13102 const struct auto_pin_cfg *cfg)
13104 struct hda_input_mux *imux = &spec->private_imux;
13105 int i, err, idx, idx1;
13107 for (i = 0; i < AUTO_PIN_LAST; i++) {
13108 switch (cfg->input_pins[i]) {
13111 idx = 2; /* Line In */
13115 idx = 2; /* Line In */
13119 idx = 1; /* Mic In */
13123 idx = 1; /* Mic In */
13133 err = new_analog_input(spec, cfg->input_pins[i],
13134 auto_pin_cfg_labels[i], idx, 0x15);
13138 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13139 imux->items[imux->num_items].index = idx1;
13145 static struct snd_kcontrol_new alc861_capture_mixer[] = {
13146 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13147 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13150 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13151 /* The multiple "Capture Source" controls confuse alsamixer
13152 * So call somewhat different..
13154 /* .name = "Capture Source", */
13155 .name = "Input Source",
13157 .info = alc_mux_enum_info,
13158 .get = alc_mux_enum_get,
13159 .put = alc_mux_enum_put,
13164 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13166 int pin_type, int dac_idx)
13168 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13170 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13174 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13176 struct alc_spec *spec = codec->spec;
13179 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13180 for (i = 0; i < spec->autocfg.line_outs; i++) {
13181 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13182 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13184 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13185 spec->multiout.dac_nids[i]);
13189 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13191 struct alc_spec *spec = codec->spec;
13194 pin = spec->autocfg.hp_pins[0];
13195 if (pin) /* connect to front */
13196 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13197 spec->multiout.dac_nids[0]);
13198 pin = spec->autocfg.speaker_pins[0];
13200 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13203 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13205 struct alc_spec *spec = codec->spec;
13208 for (i = 0; i < AUTO_PIN_LAST; i++) {
13209 hda_nid_t nid = spec->autocfg.input_pins[i];
13210 if (nid >= 0x0c && nid <= 0x11) {
13211 snd_hda_codec_write(codec, nid, 0,
13212 AC_VERB_SET_PIN_WIDGET_CONTROL,
13213 i <= AUTO_PIN_FRONT_MIC ?
13214 PIN_VREF80 : PIN_IN);
13219 /* parse the BIOS configuration and set up the alc_spec */
13220 /* return 1 if successful, 0 if the proper config is not found,
13221 * or a negative error code
13223 static int alc861_parse_auto_config(struct hda_codec *codec)
13225 struct alc_spec *spec = codec->spec;
13227 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13229 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13233 if (!spec->autocfg.line_outs)
13234 return 0; /* can't find valid BIOS pin config */
13236 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13239 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13242 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13245 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13249 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13251 if (spec->autocfg.dig_out_pin)
13252 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13254 if (spec->kctls.list)
13255 spec->mixers[spec->num_mixers++] = spec->kctls.list;
13257 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13259 spec->num_mux_defs = 1;
13260 spec->input_mux = &spec->private_imux;
13262 spec->adc_nids = alc861_adc_nids;
13263 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13264 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13265 spec->num_mixers++;
13270 /* additional initialization for auto-configuration model */
13271 static void alc861_auto_init(struct hda_codec *codec)
13273 struct alc_spec *spec = codec->spec;
13274 alc861_auto_init_multi_out(codec);
13275 alc861_auto_init_hp_out(codec);
13276 alc861_auto_init_analog_input(codec);
13277 if (spec->unsol_event)
13278 alc_sku_automute(codec);
13281 #ifdef CONFIG_SND_HDA_POWER_SAVE
13282 static struct hda_amp_list alc861_loopbacks[] = {
13283 { 0x15, HDA_INPUT, 0 },
13284 { 0x15, HDA_INPUT, 1 },
13285 { 0x15, HDA_INPUT, 2 },
13286 { 0x15, HDA_INPUT, 3 },
13293 * configuration and preset
13295 static const char *alc861_models[ALC861_MODEL_LAST] = {
13296 [ALC861_3ST] = "3stack",
13297 [ALC660_3ST] = "3stack-660",
13298 [ALC861_3ST_DIG] = "3stack-dig",
13299 [ALC861_6ST_DIG] = "6stack-dig",
13300 [ALC861_UNIWILL_M31] = "uniwill-m31",
13301 [ALC861_TOSHIBA] = "toshiba",
13302 [ALC861_ASUS] = "asus",
13303 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13304 [ALC861_AUTO] = "auto",
13307 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13308 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13309 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13310 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13311 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13312 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13313 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13314 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13315 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13316 * Any other models that need this preset?
13318 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13319 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13320 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13321 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13322 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13323 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13324 /* FIXME: the below seems conflict */
13325 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13326 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13327 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13331 static struct alc_config_preset alc861_presets[] = {
13333 .mixers = { alc861_3ST_mixer },
13334 .init_verbs = { alc861_threestack_init_verbs },
13335 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13336 .dac_nids = alc861_dac_nids,
13337 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13338 .channel_mode = alc861_threestack_modes,
13340 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13341 .adc_nids = alc861_adc_nids,
13342 .input_mux = &alc861_capture_source,
13344 [ALC861_3ST_DIG] = {
13345 .mixers = { alc861_base_mixer },
13346 .init_verbs = { alc861_threestack_init_verbs },
13347 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13348 .dac_nids = alc861_dac_nids,
13349 .dig_out_nid = ALC861_DIGOUT_NID,
13350 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13351 .channel_mode = alc861_threestack_modes,
13353 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13354 .adc_nids = alc861_adc_nids,
13355 .input_mux = &alc861_capture_source,
13357 [ALC861_6ST_DIG] = {
13358 .mixers = { alc861_base_mixer },
13359 .init_verbs = { alc861_base_init_verbs },
13360 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13361 .dac_nids = alc861_dac_nids,
13362 .dig_out_nid = ALC861_DIGOUT_NID,
13363 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13364 .channel_mode = alc861_8ch_modes,
13365 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13366 .adc_nids = alc861_adc_nids,
13367 .input_mux = &alc861_capture_source,
13370 .mixers = { alc861_3ST_mixer },
13371 .init_verbs = { alc861_threestack_init_verbs },
13372 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13373 .dac_nids = alc660_dac_nids,
13374 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13375 .channel_mode = alc861_threestack_modes,
13377 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13378 .adc_nids = alc861_adc_nids,
13379 .input_mux = &alc861_capture_source,
13381 [ALC861_UNIWILL_M31] = {
13382 .mixers = { alc861_uniwill_m31_mixer },
13383 .init_verbs = { alc861_uniwill_m31_init_verbs },
13384 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13385 .dac_nids = alc861_dac_nids,
13386 .dig_out_nid = ALC861_DIGOUT_NID,
13387 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13388 .channel_mode = alc861_uniwill_m31_modes,
13390 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13391 .adc_nids = alc861_adc_nids,
13392 .input_mux = &alc861_capture_source,
13394 [ALC861_TOSHIBA] = {
13395 .mixers = { alc861_toshiba_mixer },
13396 .init_verbs = { alc861_base_init_verbs,
13397 alc861_toshiba_init_verbs },
13398 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13399 .dac_nids = alc861_dac_nids,
13400 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13401 .channel_mode = alc883_3ST_2ch_modes,
13402 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13403 .adc_nids = alc861_adc_nids,
13404 .input_mux = &alc861_capture_source,
13405 .unsol_event = alc861_toshiba_unsol_event,
13406 .init_hook = alc861_toshiba_automute,
13409 .mixers = { alc861_asus_mixer },
13410 .init_verbs = { alc861_asus_init_verbs },
13411 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13412 .dac_nids = alc861_dac_nids,
13413 .dig_out_nid = ALC861_DIGOUT_NID,
13414 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13415 .channel_mode = alc861_asus_modes,
13418 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13419 .adc_nids = alc861_adc_nids,
13420 .input_mux = &alc861_capture_source,
13422 [ALC861_ASUS_LAPTOP] = {
13423 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13424 .init_verbs = { alc861_asus_init_verbs,
13425 alc861_asus_laptop_init_verbs },
13426 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13427 .dac_nids = alc861_dac_nids,
13428 .dig_out_nid = ALC861_DIGOUT_NID,
13429 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13430 .channel_mode = alc883_3ST_2ch_modes,
13432 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13433 .adc_nids = alc861_adc_nids,
13434 .input_mux = &alc861_capture_source,
13439 static int patch_alc861(struct hda_codec *codec)
13441 struct alc_spec *spec;
13445 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13449 codec->spec = spec;
13451 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13455 if (board_config < 0) {
13456 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13457 "trying auto-probe from BIOS...\n");
13458 board_config = ALC861_AUTO;
13461 if (board_config == ALC861_AUTO) {
13462 /* automatic parse from the BIOS config */
13463 err = alc861_parse_auto_config(codec);
13469 "hda_codec: Cannot set up configuration "
13470 "from BIOS. Using base mode...\n");
13471 board_config = ALC861_3ST_DIG;
13475 if (board_config != ALC861_AUTO)
13476 setup_preset(spec, &alc861_presets[board_config]);
13478 spec->stream_name_analog = "ALC861 Analog";
13479 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13480 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13482 spec->stream_name_digital = "ALC861 Digital";
13483 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13484 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13486 spec->vmaster_nid = 0x03;
13488 codec->patch_ops = alc_patch_ops;
13489 if (board_config == ALC861_AUTO)
13490 spec->init_hook = alc861_auto_init;
13491 #ifdef CONFIG_SND_HDA_POWER_SAVE
13492 if (!spec->loopback.amplist)
13493 spec->loopback.amplist = alc861_loopbacks;
13500 * ALC861-VD support
13504 * In addition, an independent DAC
13506 #define ALC861VD_DIGOUT_NID 0x06
13508 static hda_nid_t alc861vd_dac_nids[4] = {
13509 /* front, surr, clfe, side surr */
13510 0x02, 0x03, 0x04, 0x05
13513 /* dac_nids for ALC660vd are in a different order - according to
13514 * Realtek's driver.
13515 * This should probably tesult in a different mixer for 6stack models
13516 * of ALC660vd codecs, but for now there is only 3stack mixer
13517 * - and it is the same as in 861vd.
13518 * adc_nids in ALC660vd are (is) the same as in 861vd
13520 static hda_nid_t alc660vd_dac_nids[3] = {
13521 /* front, rear, clfe, rear_surr */
13525 static hda_nid_t alc861vd_adc_nids[1] = {
13530 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13533 /* FIXME: should be a matrix-type input source selection */
13534 static struct hda_input_mux alc861vd_capture_source = {
13538 { "Front Mic", 0x1 },
13544 static struct hda_input_mux alc861vd_dallas_capture_source = {
13547 { "Ext Mic", 0x0 },
13548 { "Int Mic", 0x1 },
13552 static struct hda_input_mux alc861vd_hp_capture_source = {
13555 { "Front Mic", 0x0 },
13556 { "ATAPI Mic", 0x1 },
13560 #define alc861vd_mux_enum_info alc_mux_enum_info
13561 #define alc861vd_mux_enum_get alc_mux_enum_get
13562 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13563 #define alc861vd_mux_enum_put alc882_mux_enum_put
13568 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13575 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13576 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13577 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13578 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13579 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13586 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13587 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13588 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13589 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13590 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13594 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13595 { 6, alc861vd_6stack_ch6_init },
13596 { 8, alc861vd_6stack_ch8_init },
13599 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13601 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13602 .name = "Channel Mode",
13603 .info = alc_ch_mode_info,
13604 .get = alc_ch_mode_get,
13605 .put = alc_ch_mode_put,
13610 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13611 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13612 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13616 /* The multiple "Capture Source" controls confuse alsamixer
13617 * So call somewhat different..
13619 /* .name = "Capture Source", */
13620 .name = "Input Source",
13622 .info = alc861vd_mux_enum_info,
13623 .get = alc861vd_mux_enum_get,
13624 .put = alc861vd_mux_enum_put,
13629 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13630 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13632 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13633 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13634 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13636 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13637 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13639 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13641 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13643 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13644 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13646 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13647 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13651 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13655 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13656 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13657 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13659 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13660 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13662 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13663 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13665 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13666 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13671 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13672 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13673 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13675 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13677 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13681 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13682 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13683 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13685 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13686 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13688 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13689 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13691 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13692 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13697 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13698 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13699 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13700 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13702 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13704 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13708 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13709 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13710 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13712 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13713 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13718 /* Pin assignment: Speaker=0x14, HP = 0x15,
13719 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13721 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13722 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13723 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13724 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13725 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13726 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13727 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13728 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13729 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13730 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13731 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13732 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13733 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13737 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13738 * Front Mic=0x18, ATAPI Mic = 0x19,
13740 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13741 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13742 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13743 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13744 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13745 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13746 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13747 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13748 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13754 * generic initialization of ADC, input mixers and output mixers
13756 static struct hda_verb alc861vd_volume_init_verbs[] = {
13758 * Unmute ADC0 and set the default input to mic-in
13760 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13761 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13763 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13764 * the analog-loopback mixer widget
13766 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13771 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13773 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13780 * Set up output mixers (0x02 - 0x05)
13782 /* set vol=0 to output mixers */
13783 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13784 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13785 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13786 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13788 /* set up input amps for analog loopback */
13789 /* Amp Indices: DAC = 0, mixer = 1 */
13790 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13791 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13792 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13793 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13794 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13795 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13796 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13797 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13803 * 3-stack pin configuration:
13804 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13806 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13808 * Set pin mode and muting
13810 /* set front pin widgets 0x14 for output */
13811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13813 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13815 /* Mic (rear) pin: input vref at 80% */
13816 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13817 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13818 /* Front Mic pin: input vref at 80% */
13819 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13820 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13821 /* Line In pin: input */
13822 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13823 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13824 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13825 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13826 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13827 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13828 /* CD pin widget for input */
13829 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13835 * 6-stack pin configuration:
13837 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13839 * Set pin mode and muting
13841 /* set front pin widgets 0x14 for output */
13842 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13843 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13844 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13846 /* Rear Pin: output 1 (0x0d) */
13847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13849 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13850 /* CLFE Pin: output 2 (0x0e) */
13851 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13852 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13853 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13854 /* Side Pin: output 3 (0x0f) */
13855 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13856 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13857 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13859 /* Mic (rear) pin: input vref at 80% */
13860 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13861 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13862 /* Front Mic pin: input vref at 80% */
13863 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13864 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13865 /* Line In pin: input */
13866 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13867 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13868 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13869 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13870 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13871 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13872 /* CD pin widget for input */
13873 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13878 static struct hda_verb alc861vd_eapd_verbs[] = {
13879 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13883 static struct hda_verb alc660vd_eapd_verbs[] = {
13884 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13885 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13889 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13890 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13893 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13894 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13898 /* toggle speaker-output according to the hp-jack state */
13899 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13901 unsigned int present;
13902 unsigned char bits;
13904 present = snd_hda_codec_read(codec, 0x1b, 0,
13905 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13906 bits = present ? HDA_AMP_MUTE : 0;
13907 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13908 HDA_AMP_MUTE, bits);
13911 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13913 unsigned int present;
13914 unsigned char bits;
13916 present = snd_hda_codec_read(codec, 0x18, 0,
13917 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13918 bits = present ? HDA_AMP_MUTE : 0;
13919 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13920 HDA_AMP_MUTE, bits);
13923 static void alc861vd_lenovo_automute(struct hda_codec *codec)
13925 alc861vd_lenovo_hp_automute(codec);
13926 alc861vd_lenovo_mic_automute(codec);
13929 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13932 switch (res >> 26) {
13933 case ALC880_HP_EVENT:
13934 alc861vd_lenovo_hp_automute(codec);
13936 case ALC880_MIC_EVENT:
13937 alc861vd_lenovo_mic_automute(codec);
13942 static struct hda_verb alc861vd_dallas_verbs[] = {
13943 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13944 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13945 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13946 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13949 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13950 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13951 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13952 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13953 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13954 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13955 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13958 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13959 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13960 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13961 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13962 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13963 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13964 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13966 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13967 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13968 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13969 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13970 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13971 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13972 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13973 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13975 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13976 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13977 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13978 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13980 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13981 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13982 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13987 /* toggle speaker-output according to the hp-jack state */
13988 static void alc861vd_dallas_automute(struct hda_codec *codec)
13990 unsigned int present;
13992 present = snd_hda_codec_read(codec, 0x15, 0,
13993 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13994 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13995 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13998 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14000 if ((res >> 26) == ALC880_HP_EVENT)
14001 alc861vd_dallas_automute(codec);
14004 #ifdef CONFIG_SND_HDA_POWER_SAVE
14005 #define alc861vd_loopbacks alc880_loopbacks
14008 /* pcm configuration: identiacal with ALC880 */
14009 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14010 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14011 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14012 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14015 * configuration and preset
14017 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14018 [ALC660VD_3ST] = "3stack-660",
14019 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14020 [ALC861VD_3ST] = "3stack",
14021 [ALC861VD_3ST_DIG] = "3stack-digout",
14022 [ALC861VD_6ST_DIG] = "6stack-digout",
14023 [ALC861VD_LENOVO] = "lenovo",
14024 [ALC861VD_DALLAS] = "dallas",
14025 [ALC861VD_HP] = "hp",
14026 [ALC861VD_AUTO] = "auto",
14029 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14030 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14031 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14032 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14033 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14034 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
14035 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14036 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14037 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14038 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14039 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14040 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14041 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14042 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14043 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14044 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14045 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14046 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14050 static struct alc_config_preset alc861vd_presets[] = {
14052 .mixers = { alc861vd_3st_mixer },
14053 .init_verbs = { alc861vd_volume_init_verbs,
14054 alc861vd_3stack_init_verbs },
14055 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14056 .dac_nids = alc660vd_dac_nids,
14057 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14058 .channel_mode = alc861vd_3stack_2ch_modes,
14059 .input_mux = &alc861vd_capture_source,
14061 [ALC660VD_3ST_DIG] = {
14062 .mixers = { alc861vd_3st_mixer },
14063 .init_verbs = { alc861vd_volume_init_verbs,
14064 alc861vd_3stack_init_verbs },
14065 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14066 .dac_nids = alc660vd_dac_nids,
14067 .dig_out_nid = ALC861VD_DIGOUT_NID,
14068 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14069 .channel_mode = alc861vd_3stack_2ch_modes,
14070 .input_mux = &alc861vd_capture_source,
14073 .mixers = { alc861vd_3st_mixer },
14074 .init_verbs = { alc861vd_volume_init_verbs,
14075 alc861vd_3stack_init_verbs },
14076 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14077 .dac_nids = alc861vd_dac_nids,
14078 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14079 .channel_mode = alc861vd_3stack_2ch_modes,
14080 .input_mux = &alc861vd_capture_source,
14082 [ALC861VD_3ST_DIG] = {
14083 .mixers = { alc861vd_3st_mixer },
14084 .init_verbs = { alc861vd_volume_init_verbs,
14085 alc861vd_3stack_init_verbs },
14086 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14087 .dac_nids = alc861vd_dac_nids,
14088 .dig_out_nid = ALC861VD_DIGOUT_NID,
14089 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14090 .channel_mode = alc861vd_3stack_2ch_modes,
14091 .input_mux = &alc861vd_capture_source,
14093 [ALC861VD_6ST_DIG] = {
14094 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14095 .init_verbs = { alc861vd_volume_init_verbs,
14096 alc861vd_6stack_init_verbs },
14097 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14098 .dac_nids = alc861vd_dac_nids,
14099 .dig_out_nid = ALC861VD_DIGOUT_NID,
14100 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14101 .channel_mode = alc861vd_6stack_modes,
14102 .input_mux = &alc861vd_capture_source,
14104 [ALC861VD_LENOVO] = {
14105 .mixers = { alc861vd_lenovo_mixer },
14106 .init_verbs = { alc861vd_volume_init_verbs,
14107 alc861vd_3stack_init_verbs,
14108 alc861vd_eapd_verbs,
14109 alc861vd_lenovo_unsol_verbs },
14110 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14111 .dac_nids = alc660vd_dac_nids,
14112 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14113 .channel_mode = alc861vd_3stack_2ch_modes,
14114 .input_mux = &alc861vd_capture_source,
14115 .unsol_event = alc861vd_lenovo_unsol_event,
14116 .init_hook = alc861vd_lenovo_automute,
14118 [ALC861VD_DALLAS] = {
14119 .mixers = { alc861vd_dallas_mixer },
14120 .init_verbs = { alc861vd_dallas_verbs },
14121 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14122 .dac_nids = alc861vd_dac_nids,
14123 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14124 .channel_mode = alc861vd_3stack_2ch_modes,
14125 .input_mux = &alc861vd_dallas_capture_source,
14126 .unsol_event = alc861vd_dallas_unsol_event,
14127 .init_hook = alc861vd_dallas_automute,
14130 .mixers = { alc861vd_hp_mixer },
14131 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14132 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14133 .dac_nids = alc861vd_dac_nids,
14134 .dig_out_nid = ALC861VD_DIGOUT_NID,
14135 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14136 .channel_mode = alc861vd_3stack_2ch_modes,
14137 .input_mux = &alc861vd_hp_capture_source,
14138 .unsol_event = alc861vd_dallas_unsol_event,
14139 .init_hook = alc861vd_dallas_automute,
14144 * BIOS auto configuration
14146 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14147 hda_nid_t nid, int pin_type, int dac_idx)
14149 alc_set_pin_output(codec, nid, pin_type);
14152 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14154 struct alc_spec *spec = codec->spec;
14157 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14158 for (i = 0; i <= HDA_SIDE; i++) {
14159 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14160 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14162 alc861vd_auto_set_output_and_unmute(codec, nid,
14168 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14170 struct alc_spec *spec = codec->spec;
14173 pin = spec->autocfg.hp_pins[0];
14174 if (pin) /* connect to front and use dac 0 */
14175 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14176 pin = spec->autocfg.speaker_pins[0];
14178 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14181 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14182 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14184 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14186 struct alc_spec *spec = codec->spec;
14189 for (i = 0; i < AUTO_PIN_LAST; i++) {
14190 hda_nid_t nid = spec->autocfg.input_pins[i];
14191 if (alc861vd_is_input_pin(nid)) {
14192 snd_hda_codec_write(codec, nid, 0,
14193 AC_VERB_SET_PIN_WIDGET_CONTROL,
14194 i <= AUTO_PIN_FRONT_MIC ?
14195 PIN_VREF80 : PIN_IN);
14196 if (nid != ALC861VD_PIN_CD_NID)
14197 snd_hda_codec_write(codec, nid, 0,
14198 AC_VERB_SET_AMP_GAIN_MUTE,
14204 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14206 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14207 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14209 /* add playback controls from the parsed DAC table */
14210 /* Based on ALC880 version. But ALC861VD has separate,
14211 * different NIDs for mute/unmute switch and volume control */
14212 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14213 const struct auto_pin_cfg *cfg)
14216 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14217 hda_nid_t nid_v, nid_s;
14220 for (i = 0; i < cfg->line_outs; i++) {
14221 if (!spec->multiout.dac_nids[i])
14223 nid_v = alc861vd_idx_to_mixer_vol(
14225 spec->multiout.dac_nids[i]));
14226 nid_s = alc861vd_idx_to_mixer_switch(
14228 spec->multiout.dac_nids[i]));
14232 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14233 "Center Playback Volume",
14234 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14238 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14239 "LFE Playback Volume",
14240 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14244 err = add_control(spec, ALC_CTL_BIND_MUTE,
14245 "Center Playback Switch",
14246 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14250 err = add_control(spec, ALC_CTL_BIND_MUTE,
14251 "LFE Playback Switch",
14252 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14257 sprintf(name, "%s Playback Volume", chname[i]);
14258 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14259 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14263 sprintf(name, "%s Playback Switch", chname[i]);
14264 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14265 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14274 /* add playback controls for speaker and HP outputs */
14275 /* Based on ALC880 version. But ALC861VD has separate,
14276 * different NIDs for mute/unmute switch and volume control */
14277 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14278 hda_nid_t pin, const char *pfx)
14280 hda_nid_t nid_v, nid_s;
14287 if (alc880_is_fixed_pin(pin)) {
14288 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14289 /* specify the DAC as the extra output */
14290 if (!spec->multiout.hp_nid)
14291 spec->multiout.hp_nid = nid_v;
14293 spec->multiout.extra_out_nid[0] = nid_v;
14294 /* control HP volume/switch on the output mixer amp */
14295 nid_v = alc861vd_idx_to_mixer_vol(
14296 alc880_fixed_pin_idx(pin));
14297 nid_s = alc861vd_idx_to_mixer_switch(
14298 alc880_fixed_pin_idx(pin));
14300 sprintf(name, "%s Playback Volume", pfx);
14301 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14302 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14305 sprintf(name, "%s Playback Switch", pfx);
14306 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14307 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14310 } else if (alc880_is_multi_pin(pin)) {
14311 /* set manual connection */
14312 /* we have only a switch on HP-out PIN */
14313 sprintf(name, "%s Playback Switch", pfx);
14314 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14315 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14322 /* parse the BIOS configuration and set up the alc_spec
14323 * return 1 if successful, 0 if the proper config is not found,
14324 * or a negative error code
14325 * Based on ALC880 version - had to change it to override
14326 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14327 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14329 struct alc_spec *spec = codec->spec;
14331 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14333 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14337 if (!spec->autocfg.line_outs)
14338 return 0; /* can't find valid BIOS pin config */
14340 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14343 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14346 err = alc861vd_auto_create_extra_out(spec,
14347 spec->autocfg.speaker_pins[0],
14351 err = alc861vd_auto_create_extra_out(spec,
14352 spec->autocfg.hp_pins[0],
14356 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14360 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14362 if (spec->autocfg.dig_out_pin)
14363 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14365 if (spec->kctls.list)
14366 spec->mixers[spec->num_mixers++] = spec->kctls.list;
14368 spec->init_verbs[spec->num_init_verbs++]
14369 = alc861vd_volume_init_verbs;
14371 spec->num_mux_defs = 1;
14372 spec->input_mux = &spec->private_imux;
14374 err = alc_auto_add_mic_boost(codec);
14381 /* additional initialization for auto-configuration model */
14382 static void alc861vd_auto_init(struct hda_codec *codec)
14384 struct alc_spec *spec = codec->spec;
14385 alc861vd_auto_init_multi_out(codec);
14386 alc861vd_auto_init_hp_out(codec);
14387 alc861vd_auto_init_analog_input(codec);
14388 alc861vd_auto_init_input_src(codec);
14389 if (spec->unsol_event)
14390 alc_sku_automute(codec);
14393 static int patch_alc861vd(struct hda_codec *codec)
14395 struct alc_spec *spec;
14396 int err, board_config;
14398 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14402 codec->spec = spec;
14404 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14408 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14409 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14410 "ALC861VD, trying auto-probe from BIOS...\n");
14411 board_config = ALC861VD_AUTO;
14414 if (board_config == ALC861VD_AUTO) {
14415 /* automatic parse from the BIOS config */
14416 err = alc861vd_parse_auto_config(codec);
14422 "hda_codec: Cannot set up configuration "
14423 "from BIOS. Using base mode...\n");
14424 board_config = ALC861VD_3ST;
14428 if (board_config != ALC861VD_AUTO)
14429 setup_preset(spec, &alc861vd_presets[board_config]);
14431 if (codec->vendor_id == 0x10ec0660) {
14432 spec->stream_name_analog = "ALC660-VD Analog";
14433 spec->stream_name_digital = "ALC660-VD Digital";
14434 /* always turn on EAPD */
14435 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
14437 spec->stream_name_analog = "ALC861VD Analog";
14438 spec->stream_name_digital = "ALC861VD Digital";
14441 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14442 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14444 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14445 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14447 spec->adc_nids = alc861vd_adc_nids;
14448 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14449 spec->capsrc_nids = alc861vd_capsrc_nids;
14451 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14452 spec->num_mixers++;
14454 spec->vmaster_nid = 0x02;
14456 codec->patch_ops = alc_patch_ops;
14458 if (board_config == ALC861VD_AUTO)
14459 spec->init_hook = alc861vd_auto_init;
14460 #ifdef CONFIG_SND_HDA_POWER_SAVE
14461 if (!spec->loopback.amplist)
14462 spec->loopback.amplist = alc861vd_loopbacks;
14471 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14472 * configuration. Each pin widget can choose any input DACs and a mixer.
14473 * Each ADC is connected from a mixer of all inputs. This makes possible
14474 * 6-channel independent captures.
14476 * In addition, an independent DAC for the multi-playback (not used in this
14479 #define ALC662_DIGOUT_NID 0x06
14480 #define ALC662_DIGIN_NID 0x0a
14482 static hda_nid_t alc662_dac_nids[4] = {
14483 /* front, rear, clfe, rear_surr */
14487 static hda_nid_t alc662_adc_nids[1] = {
14492 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14495 /* FIXME: should be a matrix-type input source selection */
14496 static struct hda_input_mux alc662_capture_source = {
14500 { "Front Mic", 0x1 },
14506 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14514 static struct hda_input_mux alc662_eeepc_capture_source = {
14522 static struct hda_input_mux alc663_capture_source = {
14526 { "Front Mic", 0x1 },
14531 static struct hda_input_mux alc663_m51va_capture_source = {
14534 { "Ext-Mic", 0x0 },
14539 #define alc662_mux_enum_info alc_mux_enum_info
14540 #define alc662_mux_enum_get alc_mux_enum_get
14541 #define alc662_mux_enum_put alc882_mux_enum_put
14546 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14553 static struct hda_verb alc662_3ST_ch2_init[] = {
14554 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14555 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14556 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14557 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14564 static struct hda_verb alc662_3ST_ch6_init[] = {
14565 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14566 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14567 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14568 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14569 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14570 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14574 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14575 { 2, alc662_3ST_ch2_init },
14576 { 6, alc662_3ST_ch6_init },
14582 static struct hda_verb alc662_sixstack_ch6_init[] = {
14583 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14584 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14585 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14592 static struct hda_verb alc662_sixstack_ch8_init[] = {
14593 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14594 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14595 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14599 static struct hda_channel_mode alc662_5stack_modes[2] = {
14600 { 2, alc662_sixstack_ch6_init },
14601 { 6, alc662_sixstack_ch8_init },
14604 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14605 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14608 static struct snd_kcontrol_new alc662_base_mixer[] = {
14609 /* output mixer control */
14610 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14611 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14612 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14613 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14614 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14615 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14616 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14617 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14618 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14620 /*Input mixer control */
14621 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14622 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14623 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14624 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14625 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14626 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14627 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14628 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14632 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14633 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14634 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14638 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14639 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14641 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14644 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14645 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14649 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14650 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14651 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14652 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14653 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14654 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14655 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14656 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14657 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14659 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14660 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14661 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14662 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14665 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14666 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14667 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14668 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14672 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14673 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14674 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14675 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14676 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14677 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14678 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14679 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14685 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14686 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14688 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14689 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14691 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14692 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14693 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14695 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14696 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14697 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14701 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14702 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14703 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14704 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14705 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14706 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14707 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14708 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14709 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14710 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14711 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14712 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14713 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14719 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14720 .ops = &snd_hda_bind_vol,
14722 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14723 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14728 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14729 .ops = &snd_hda_bind_sw,
14731 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14732 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14737 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14738 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14739 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14741 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14745 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14746 .ops = &snd_hda_bind_sw,
14748 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14749 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14750 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14755 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14756 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14757 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14759 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14760 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14761 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14766 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14767 .ops = &snd_hda_bind_sw,
14769 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14770 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14771 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14776 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14777 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14778 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14781 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14782 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14786 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14787 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14788 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14789 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14791 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14792 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14793 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14797 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14798 .ops = &snd_hda_bind_vol,
14800 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14801 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14806 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14807 .ops = &snd_hda_bind_sw,
14809 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14810 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14815 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14816 HDA_BIND_VOL("Master Playback Volume",
14817 &alc663_asus_two_bind_master_vol),
14818 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14819 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14822 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14826 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14827 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14828 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14829 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14830 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14831 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14832 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14836 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14837 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14838 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14839 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14840 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14843 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14844 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14845 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14846 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14850 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14851 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14852 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14857 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14858 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14859 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14860 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14864 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14867 .name = "Channel Mode",
14868 .info = alc_ch_mode_info,
14869 .get = alc_ch_mode_get,
14870 .put = alc_ch_mode_put,
14875 static struct hda_verb alc662_init_verbs[] = {
14876 /* ADC: mute amp left and right */
14877 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14878 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14879 /* Front mixer: unmute input/output amp left and right (volume = 0) */
14881 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14882 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14883 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14884 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14885 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14890 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14892 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14894 /* Front Pin: output 0 (0x0c) */
14895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14898 /* Rear Pin: output 1 (0x0d) */
14899 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14902 /* CLFE Pin: output 2 (0x0e) */
14903 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14904 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14906 /* Mic (rear) pin: input vref at 80% */
14907 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14908 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14909 /* Front Mic pin: input vref at 80% */
14910 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14911 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14912 /* Line In pin: input */
14913 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14915 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14918 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14919 /* CD pin widget for input */
14920 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14922 /* FIXME: use matrix-type input source selection */
14923 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14925 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14935 /* always trun on EAPD */
14936 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14937 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14942 static struct hda_verb alc662_sue_init_verbs[] = {
14943 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14944 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14948 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14949 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14950 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14954 /* Set Unsolicited Event*/
14955 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14956 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14957 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14962 * generic initialization of ADC, input mixers and output mixers
14964 static struct hda_verb alc662_auto_init_verbs[] = {
14966 * Unmute ADC and set the default input to mic-in
14968 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14971 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14973 * Note: PASD motherboards uses the Line In 2 as the input for front
14974 * panel mic (mic 2)
14976 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14977 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14978 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14979 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14980 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14981 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14984 * Set up output mixers (0x0c - 0x0f)
14986 /* set vol=0 to output mixers */
14987 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14988 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14989 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14991 /* set up input amps for analog loopback */
14992 /* Amp Indices: DAC = 0, mixer = 1 */
14993 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14994 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14995 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14996 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14997 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14998 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15001 /* FIXME: use matrix-type input source selection */
15002 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15005 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15009 /* additional verbs for ALC663 */
15010 static struct hda_verb alc663_auto_init_verbs[] = {
15011 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15012 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15016 static struct hda_verb alc663_m51va_init_verbs[] = {
15017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15018 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15019 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15020 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15021 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15022 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15024 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15025 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15029 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15030 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15031 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15032 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15035 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15036 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15040 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15041 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15042 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15043 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15044 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15047 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15048 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15052 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15054 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15055 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15058 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15059 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15063 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15064 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15065 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15066 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15067 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15068 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15069 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15070 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15073 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15074 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15075 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15079 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15080 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15081 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15082 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15083 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15084 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15085 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15086 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15089 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15090 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15091 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15095 static struct hda_verb alc663_g71v_init_verbs[] = {
15096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15097 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15098 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15100 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15101 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15102 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15104 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15105 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15106 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15110 static struct hda_verb alc663_g50v_init_verbs[] = {
15111 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15112 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15113 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15115 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15116 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15120 static struct hda_verb alc662_ecs_init_verbs[] = {
15121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15124 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15128 /* capture mixer elements */
15129 static struct snd_kcontrol_new alc662_capture_mixer[] = {
15130 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15131 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15133 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15134 /* The multiple "Capture Source" controls confuse alsamixer
15135 * So call somewhat different..
15137 /* .name = "Capture Source", */
15138 .name = "Input Source",
15140 .info = alc662_mux_enum_info,
15141 .get = alc662_mux_enum_get,
15142 .put = alc662_mux_enum_put,
15147 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15148 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15149 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15153 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15155 unsigned int present;
15156 unsigned char bits;
15158 present = snd_hda_codec_read(codec, 0x14, 0,
15159 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15160 bits = present ? HDA_AMP_MUTE : 0;
15161 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15162 HDA_AMP_MUTE, bits);
15165 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15167 unsigned int present;
15168 unsigned char bits;
15170 present = snd_hda_codec_read(codec, 0x1b, 0,
15171 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15172 bits = present ? HDA_AMP_MUTE : 0;
15173 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15174 HDA_AMP_MUTE, bits);
15175 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15176 HDA_AMP_MUTE, bits);
15179 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15182 if ((res >> 26) == ALC880_HP_EVENT)
15183 alc662_lenovo_101e_all_automute(codec);
15184 if ((res >> 26) == ALC880_FRONT_EVENT)
15185 alc662_lenovo_101e_ispeaker_automute(codec);
15188 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15190 unsigned int present;
15192 present = snd_hda_codec_read(codec, 0x18, 0,
15193 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15194 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15195 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15196 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15197 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15198 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15199 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15200 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15201 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15204 /* unsolicited event for HP jack sensing */
15205 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15208 if ((res >> 26) == ALC880_HP_EVENT)
15209 alc262_hippo1_automute( codec );
15211 if ((res >> 26) == ALC880_MIC_EVENT)
15212 alc662_eeepc_mic_automute(codec);
15215 static void alc662_eeepc_inithook(struct hda_codec *codec)
15217 alc262_hippo1_automute( codec );
15218 alc662_eeepc_mic_automute(codec);
15221 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15224 unsigned int present;
15226 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15227 present = snd_hda_codec_read(codec, 0x14, 0,
15228 AC_VERB_GET_PIN_SENSE, 0);
15229 present = (present & 0x80000000) != 0;
15231 /* mute internal speaker */
15232 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15233 HDA_AMP_MUTE, HDA_AMP_MUTE);
15235 /* unmute internal speaker if necessary */
15236 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15237 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15238 HDA_AMP_MUTE, mute);
15242 /* unsolicited event for HP jack sensing */
15243 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15246 if ((res >> 26) == ALC880_HP_EVENT)
15247 alc662_eeepc_ep20_automute(codec);
15250 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15252 alc662_eeepc_ep20_automute(codec);
15255 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15257 unsigned int present;
15258 unsigned char bits;
15260 present = snd_hda_codec_read(codec, 0x21, 0,
15261 AC_VERB_GET_PIN_SENSE, 0)
15262 & AC_PINSENSE_PRESENCE;
15263 bits = present ? HDA_AMP_MUTE : 0;
15264 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15265 AMP_IN_MUTE(0), bits);
15266 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15267 AMP_IN_MUTE(0), bits);
15270 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15272 unsigned int present;
15273 unsigned char bits;
15275 present = snd_hda_codec_read(codec, 0x21, 0,
15276 AC_VERB_GET_PIN_SENSE, 0)
15277 & AC_PINSENSE_PRESENCE;
15278 bits = present ? HDA_AMP_MUTE : 0;
15279 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15280 AMP_IN_MUTE(0), bits);
15281 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15282 AMP_IN_MUTE(0), bits);
15283 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15284 AMP_IN_MUTE(0), bits);
15285 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15286 AMP_IN_MUTE(0), bits);
15289 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15291 unsigned int present;
15292 unsigned char bits;
15294 present = snd_hda_codec_read(codec, 0x15, 0,
15295 AC_VERB_GET_PIN_SENSE, 0)
15296 & AC_PINSENSE_PRESENCE;
15297 bits = present ? HDA_AMP_MUTE : 0;
15298 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15299 AMP_IN_MUTE(0), bits);
15300 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15301 AMP_IN_MUTE(0), bits);
15302 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15303 AMP_IN_MUTE(0), bits);
15304 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15305 AMP_IN_MUTE(0), bits);
15308 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15310 unsigned int present;
15311 unsigned char bits;
15313 present = snd_hda_codec_read(codec, 0x1b, 0,
15314 AC_VERB_GET_PIN_SENSE, 0)
15315 & AC_PINSENSE_PRESENCE;
15316 bits = present ? 0 : PIN_OUT;
15317 snd_hda_codec_write(codec, 0x14, 0,
15318 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15321 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15323 unsigned int present1, present2;
15325 present1 = snd_hda_codec_read(codec, 0x21, 0,
15326 AC_VERB_GET_PIN_SENSE, 0)
15327 & AC_PINSENSE_PRESENCE;
15328 present2 = snd_hda_codec_read(codec, 0x15, 0,
15329 AC_VERB_GET_PIN_SENSE, 0)
15330 & AC_PINSENSE_PRESENCE;
15332 if (present1 || present2) {
15333 snd_hda_codec_write_cache(codec, 0x14, 0,
15334 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15336 snd_hda_codec_write_cache(codec, 0x14, 0,
15337 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15341 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15343 unsigned int present1, present2;
15345 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15346 AC_VERB_GET_PIN_SENSE, 0)
15347 & AC_PINSENSE_PRESENCE;
15348 present2 = snd_hda_codec_read(codec, 0x15, 0,
15349 AC_VERB_GET_PIN_SENSE, 0)
15350 & AC_PINSENSE_PRESENCE;
15352 if (present1 || present2) {
15353 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15354 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15355 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15356 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15358 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15359 AMP_IN_MUTE(0), 0);
15360 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15361 AMP_IN_MUTE(0), 0);
15365 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15367 unsigned int present;
15369 present = snd_hda_codec_read(codec, 0x18, 0,
15370 AC_VERB_GET_PIN_SENSE, 0)
15371 & AC_PINSENSE_PRESENCE;
15372 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15373 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15374 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15375 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15376 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15377 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15378 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15379 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15382 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15385 switch (res >> 26) {
15386 case ALC880_HP_EVENT:
15387 alc663_m51va_speaker_automute(codec);
15389 case ALC880_MIC_EVENT:
15390 alc663_m51va_mic_automute(codec);
15395 static void alc663_m51va_inithook(struct hda_codec *codec)
15397 alc663_m51va_speaker_automute(codec);
15398 alc663_m51va_mic_automute(codec);
15401 /* ***************** Mode1 ******************************/
15402 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15405 switch (res >> 26) {
15406 case ALC880_HP_EVENT:
15407 alc663_m51va_speaker_automute(codec);
15409 case ALC880_MIC_EVENT:
15410 alc662_eeepc_mic_automute(codec);
15415 static void alc663_mode1_inithook(struct hda_codec *codec)
15417 alc663_m51va_speaker_automute(codec);
15418 alc662_eeepc_mic_automute(codec);
15420 /* ***************** Mode2 ******************************/
15421 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15424 switch (res >> 26) {
15425 case ALC880_HP_EVENT:
15426 alc662_f5z_speaker_automute(codec);
15428 case ALC880_MIC_EVENT:
15429 alc662_eeepc_mic_automute(codec);
15434 static void alc662_mode2_inithook(struct hda_codec *codec)
15436 alc662_f5z_speaker_automute(codec);
15437 alc662_eeepc_mic_automute(codec);
15439 /* ***************** Mode3 ******************************/
15440 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15443 switch (res >> 26) {
15444 case ALC880_HP_EVENT:
15445 alc663_two_hp_m1_speaker_automute(codec);
15447 case ALC880_MIC_EVENT:
15448 alc662_eeepc_mic_automute(codec);
15453 static void alc663_mode3_inithook(struct hda_codec *codec)
15455 alc663_two_hp_m1_speaker_automute(codec);
15456 alc662_eeepc_mic_automute(codec);
15458 /* ***************** Mode4 ******************************/
15459 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15462 switch (res >> 26) {
15463 case ALC880_HP_EVENT:
15464 alc663_21jd_two_speaker_automute(codec);
15466 case ALC880_MIC_EVENT:
15467 alc662_eeepc_mic_automute(codec);
15472 static void alc663_mode4_inithook(struct hda_codec *codec)
15474 alc663_21jd_two_speaker_automute(codec);
15475 alc662_eeepc_mic_automute(codec);
15477 /* ***************** Mode5 ******************************/
15478 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15481 switch (res >> 26) {
15482 case ALC880_HP_EVENT:
15483 alc663_15jd_two_speaker_automute(codec);
15485 case ALC880_MIC_EVENT:
15486 alc662_eeepc_mic_automute(codec);
15491 static void alc663_mode5_inithook(struct hda_codec *codec)
15493 alc663_15jd_two_speaker_automute(codec);
15494 alc662_eeepc_mic_automute(codec);
15496 /* ***************** Mode6 ******************************/
15497 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15500 switch (res >> 26) {
15501 case ALC880_HP_EVENT:
15502 alc663_two_hp_m2_speaker_automute(codec);
15504 case ALC880_MIC_EVENT:
15505 alc662_eeepc_mic_automute(codec);
15510 static void alc663_mode6_inithook(struct hda_codec *codec)
15512 alc663_two_hp_m2_speaker_automute(codec);
15513 alc662_eeepc_mic_automute(codec);
15516 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15518 unsigned int present;
15519 unsigned char bits;
15521 present = snd_hda_codec_read(codec, 0x21, 0,
15522 AC_VERB_GET_PIN_SENSE, 0)
15523 & AC_PINSENSE_PRESENCE;
15524 bits = present ? HDA_AMP_MUTE : 0;
15525 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15526 HDA_AMP_MUTE, bits);
15527 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15528 HDA_AMP_MUTE, bits);
15531 static void alc663_g71v_front_automute(struct hda_codec *codec)
15533 unsigned int present;
15534 unsigned char bits;
15536 present = snd_hda_codec_read(codec, 0x15, 0,
15537 AC_VERB_GET_PIN_SENSE, 0)
15538 & AC_PINSENSE_PRESENCE;
15539 bits = present ? HDA_AMP_MUTE : 0;
15540 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15541 HDA_AMP_MUTE, bits);
15544 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15547 switch (res >> 26) {
15548 case ALC880_HP_EVENT:
15549 alc663_g71v_hp_automute(codec);
15551 case ALC880_FRONT_EVENT:
15552 alc663_g71v_front_automute(codec);
15554 case ALC880_MIC_EVENT:
15555 alc662_eeepc_mic_automute(codec);
15560 static void alc663_g71v_inithook(struct hda_codec *codec)
15562 alc663_g71v_front_automute(codec);
15563 alc663_g71v_hp_automute(codec);
15564 alc662_eeepc_mic_automute(codec);
15567 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15570 switch (res >> 26) {
15571 case ALC880_HP_EVENT:
15572 alc663_m51va_speaker_automute(codec);
15574 case ALC880_MIC_EVENT:
15575 alc662_eeepc_mic_automute(codec);
15580 static void alc663_g50v_inithook(struct hda_codec *codec)
15582 alc663_m51va_speaker_automute(codec);
15583 alc662_eeepc_mic_automute(codec);
15586 /* bind hp and internal speaker mute (with plug check) */
15587 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15588 struct snd_ctl_elem_value *ucontrol)
15590 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15591 long *valp = ucontrol->value.integer.value;
15594 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15596 valp[0] ? 0 : HDA_AMP_MUTE);
15597 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15599 valp[1] ? 0 : HDA_AMP_MUTE);
15601 alc262_hippo1_automute(codec);
15605 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15606 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15608 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15609 .name = "Master Playback Switch",
15610 .info = snd_hda_mixer_amp_switch_info,
15611 .get = snd_hda_mixer_amp_switch_get,
15612 .put = alc662_ecs_master_sw_put,
15613 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15616 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15617 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15618 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15620 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15621 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15622 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15626 #ifdef CONFIG_SND_HDA_POWER_SAVE
15627 #define alc662_loopbacks alc880_loopbacks
15631 /* pcm configuration: identiacal with ALC880 */
15632 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15633 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15634 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15635 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15638 * configuration and preset
15640 static const char *alc662_models[ALC662_MODEL_LAST] = {
15641 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15642 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15643 [ALC662_3ST_6ch] = "3stack-6ch",
15644 [ALC662_5ST_DIG] = "6stack-dig",
15645 [ALC662_LENOVO_101E] = "lenovo-101e",
15646 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15647 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15648 [ALC662_ECS] = "ecs",
15649 [ALC663_ASUS_M51VA] = "m51va",
15650 [ALC663_ASUS_G71V] = "g71v",
15651 [ALC663_ASUS_H13] = "h13",
15652 [ALC663_ASUS_G50V] = "g50v",
15653 [ALC663_ASUS_MODE1] = "asus-mode1",
15654 [ALC662_ASUS_MODE2] = "asus-mode2",
15655 [ALC663_ASUS_MODE3] = "asus-mode3",
15656 [ALC663_ASUS_MODE4] = "asus-mode4",
15657 [ALC663_ASUS_MODE5] = "asus-mode5",
15658 [ALC663_ASUS_MODE6] = "asus-mode6",
15659 [ALC662_AUTO] = "auto",
15662 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15663 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15664 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
15665 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15666 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15667 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15668 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15669 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15670 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15671 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15672 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15673 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15674 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15675 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15676 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15677 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15678 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15679 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15680 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15681 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15682 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15683 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15684 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15685 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15686 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15687 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15688 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15689 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15690 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15691 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15692 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15693 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15694 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15695 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15696 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15697 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15698 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15699 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15700 ALC662_3ST_6ch_DIG),
15701 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15702 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15703 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15704 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15705 ALC662_3ST_6ch_DIG),
15706 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15707 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15708 ALC662_3ST_6ch_DIG),
15709 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15710 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15711 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15715 static struct alc_config_preset alc662_presets[] = {
15716 [ALC662_3ST_2ch_DIG] = {
15717 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15718 .init_verbs = { alc662_init_verbs },
15719 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15720 .dac_nids = alc662_dac_nids,
15721 .dig_out_nid = ALC662_DIGOUT_NID,
15722 .dig_in_nid = ALC662_DIGIN_NID,
15723 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15724 .channel_mode = alc662_3ST_2ch_modes,
15725 .input_mux = &alc662_capture_source,
15727 [ALC662_3ST_6ch_DIG] = {
15728 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15729 alc662_capture_mixer },
15730 .init_verbs = { alc662_init_verbs },
15731 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15732 .dac_nids = alc662_dac_nids,
15733 .dig_out_nid = ALC662_DIGOUT_NID,
15734 .dig_in_nid = ALC662_DIGIN_NID,
15735 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15736 .channel_mode = alc662_3ST_6ch_modes,
15738 .input_mux = &alc662_capture_source,
15740 [ALC662_3ST_6ch] = {
15741 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15742 alc662_capture_mixer },
15743 .init_verbs = { alc662_init_verbs },
15744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15745 .dac_nids = alc662_dac_nids,
15746 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15747 .channel_mode = alc662_3ST_6ch_modes,
15749 .input_mux = &alc662_capture_source,
15751 [ALC662_5ST_DIG] = {
15752 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15753 alc662_capture_mixer },
15754 .init_verbs = { alc662_init_verbs },
15755 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15756 .dac_nids = alc662_dac_nids,
15757 .dig_out_nid = ALC662_DIGOUT_NID,
15758 .dig_in_nid = ALC662_DIGIN_NID,
15759 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15760 .channel_mode = alc662_5stack_modes,
15761 .input_mux = &alc662_capture_source,
15763 [ALC662_LENOVO_101E] = {
15764 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15765 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15766 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15767 .dac_nids = alc662_dac_nids,
15768 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15769 .channel_mode = alc662_3ST_2ch_modes,
15770 .input_mux = &alc662_lenovo_101e_capture_source,
15771 .unsol_event = alc662_lenovo_101e_unsol_event,
15772 .init_hook = alc662_lenovo_101e_all_automute,
15774 [ALC662_ASUS_EEEPC_P701] = {
15775 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15776 .init_verbs = { alc662_init_verbs,
15777 alc662_eeepc_sue_init_verbs },
15778 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15779 .dac_nids = alc662_dac_nids,
15780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15781 .channel_mode = alc662_3ST_2ch_modes,
15782 .input_mux = &alc662_eeepc_capture_source,
15783 .unsol_event = alc662_eeepc_unsol_event,
15784 .init_hook = alc662_eeepc_inithook,
15786 [ALC662_ASUS_EEEPC_EP20] = {
15787 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15788 alc662_chmode_mixer },
15789 .init_verbs = { alc662_init_verbs,
15790 alc662_eeepc_ep20_sue_init_verbs },
15791 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15792 .dac_nids = alc662_dac_nids,
15793 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15794 .channel_mode = alc662_3ST_6ch_modes,
15795 .input_mux = &alc662_lenovo_101e_capture_source,
15796 .unsol_event = alc662_eeepc_ep20_unsol_event,
15797 .init_hook = alc662_eeepc_ep20_inithook,
15800 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15801 .init_verbs = { alc662_init_verbs,
15802 alc662_ecs_init_verbs },
15803 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15804 .dac_nids = alc662_dac_nids,
15805 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15806 .channel_mode = alc662_3ST_2ch_modes,
15807 .input_mux = &alc662_eeepc_capture_source,
15808 .unsol_event = alc662_eeepc_unsol_event,
15809 .init_hook = alc662_eeepc_inithook,
15811 [ALC663_ASUS_M51VA] = {
15812 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15813 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15814 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15815 .dac_nids = alc662_dac_nids,
15816 .dig_out_nid = ALC662_DIGOUT_NID,
15817 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15818 .channel_mode = alc662_3ST_2ch_modes,
15819 .input_mux = &alc663_m51va_capture_source,
15820 .unsol_event = alc663_m51va_unsol_event,
15821 .init_hook = alc663_m51va_inithook,
15823 [ALC663_ASUS_G71V] = {
15824 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15825 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15826 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15827 .dac_nids = alc662_dac_nids,
15828 .dig_out_nid = ALC662_DIGOUT_NID,
15829 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15830 .channel_mode = alc662_3ST_2ch_modes,
15831 .input_mux = &alc662_eeepc_capture_source,
15832 .unsol_event = alc663_g71v_unsol_event,
15833 .init_hook = alc663_g71v_inithook,
15835 [ALC663_ASUS_H13] = {
15836 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15837 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15838 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15839 .dac_nids = alc662_dac_nids,
15840 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15841 .channel_mode = alc662_3ST_2ch_modes,
15842 .input_mux = &alc663_m51va_capture_source,
15843 .unsol_event = alc663_m51va_unsol_event,
15844 .init_hook = alc663_m51va_inithook,
15846 [ALC663_ASUS_G50V] = {
15847 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15848 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15849 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15850 .dac_nids = alc662_dac_nids,
15851 .dig_out_nid = ALC662_DIGOUT_NID,
15852 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15853 .channel_mode = alc662_3ST_6ch_modes,
15854 .input_mux = &alc663_capture_source,
15855 .unsol_event = alc663_g50v_unsol_event,
15856 .init_hook = alc663_g50v_inithook,
15858 [ALC663_ASUS_MODE1] = {
15859 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
15860 .init_verbs = { alc662_init_verbs,
15861 alc663_21jd_amic_init_verbs },
15862 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15864 .dac_nids = alc662_dac_nids,
15865 .dig_out_nid = ALC662_DIGOUT_NID,
15866 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15867 .channel_mode = alc662_3ST_2ch_modes,
15868 .input_mux = &alc662_eeepc_capture_source,
15869 .unsol_event = alc663_mode1_unsol_event,
15870 .init_hook = alc663_mode1_inithook,
15872 [ALC662_ASUS_MODE2] = {
15873 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
15874 .init_verbs = { alc662_init_verbs,
15875 alc662_1bjd_amic_init_verbs },
15876 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15877 .dac_nids = alc662_dac_nids,
15878 .dig_out_nid = ALC662_DIGOUT_NID,
15879 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15880 .channel_mode = alc662_3ST_2ch_modes,
15881 .input_mux = &alc662_eeepc_capture_source,
15882 .unsol_event = alc662_mode2_unsol_event,
15883 .init_hook = alc662_mode2_inithook,
15885 [ALC663_ASUS_MODE3] = {
15886 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
15887 .init_verbs = { alc662_init_verbs,
15888 alc663_two_hp_amic_m1_init_verbs },
15889 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15891 .dac_nids = alc662_dac_nids,
15892 .dig_out_nid = ALC662_DIGOUT_NID,
15893 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15894 .channel_mode = alc662_3ST_2ch_modes,
15895 .input_mux = &alc662_eeepc_capture_source,
15896 .unsol_event = alc663_mode3_unsol_event,
15897 .init_hook = alc663_mode3_inithook,
15899 [ALC663_ASUS_MODE4] = {
15900 .mixers = { alc663_asus_21jd_clfe_mixer,
15901 alc662_auto_capture_mixer},
15902 .init_verbs = { alc662_init_verbs,
15903 alc663_21jd_amic_init_verbs},
15904 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15906 .dac_nids = alc662_dac_nids,
15907 .dig_out_nid = ALC662_DIGOUT_NID,
15908 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15909 .channel_mode = alc662_3ST_2ch_modes,
15910 .input_mux = &alc662_eeepc_capture_source,
15911 .unsol_event = alc663_mode4_unsol_event,
15912 .init_hook = alc663_mode4_inithook,
15914 [ALC663_ASUS_MODE5] = {
15915 .mixers = { alc663_asus_15jd_clfe_mixer,
15916 alc662_auto_capture_mixer },
15917 .init_verbs = { alc662_init_verbs,
15918 alc663_15jd_amic_init_verbs },
15919 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15921 .dac_nids = alc662_dac_nids,
15922 .dig_out_nid = ALC662_DIGOUT_NID,
15923 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15924 .channel_mode = alc662_3ST_2ch_modes,
15925 .input_mux = &alc662_eeepc_capture_source,
15926 .unsol_event = alc663_mode5_unsol_event,
15927 .init_hook = alc663_mode5_inithook,
15929 [ALC663_ASUS_MODE6] = {
15930 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
15931 .init_verbs = { alc662_init_verbs,
15932 alc663_two_hp_amic_m2_init_verbs },
15933 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15935 .dac_nids = alc662_dac_nids,
15936 .dig_out_nid = ALC662_DIGOUT_NID,
15937 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15938 .channel_mode = alc662_3ST_2ch_modes,
15939 .input_mux = &alc662_eeepc_capture_source,
15940 .unsol_event = alc663_mode6_unsol_event,
15941 .init_hook = alc663_mode6_inithook,
15947 * BIOS auto configuration
15950 /* add playback controls from the parsed DAC table */
15951 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15952 const struct auto_pin_cfg *cfg)
15955 static const char *chname[4] = {
15956 "Front", "Surround", NULL /*CLFE*/, "Side"
15961 for (i = 0; i < cfg->line_outs; i++) {
15962 if (!spec->multiout.dac_nids[i])
15964 nid = alc880_idx_to_dac(i);
15967 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15968 "Center Playback Volume",
15969 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15973 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15974 "LFE Playback Volume",
15975 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15979 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15980 "Center Playback Switch",
15981 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
15985 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15986 "LFE Playback Switch",
15987 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
15992 sprintf(name, "%s Playback Volume", chname[i]);
15993 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15994 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
15998 sprintf(name, "%s Playback Switch", chname[i]);
15999 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16000 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16009 /* add playback controls for speaker and HP outputs */
16010 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16021 /* ALC663 has a mono output pin on 0x17 */
16022 sprintf(name, "%s Playback Switch", pfx);
16023 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16024 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16028 if (alc880_is_fixed_pin(pin)) {
16029 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16030 /* printk("DAC nid=%x\n",nid); */
16031 /* specify the DAC as the extra output */
16032 if (!spec->multiout.hp_nid)
16033 spec->multiout.hp_nid = nid;
16035 spec->multiout.extra_out_nid[0] = nid;
16036 /* control HP volume/switch on the output mixer amp */
16037 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16038 sprintf(name, "%s Playback Volume", pfx);
16039 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16040 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16043 sprintf(name, "%s Playback Switch", pfx);
16044 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16045 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16048 } else if (alc880_is_multi_pin(pin)) {
16049 /* set manual connection */
16050 /* we have only a switch on HP-out PIN */
16051 sprintf(name, "%s Playback Switch", pfx);
16052 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16053 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16060 /* create playback/capture controls for input pins */
16061 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16062 const struct auto_pin_cfg *cfg)
16064 struct hda_input_mux *imux = &spec->private_imux;
16067 for (i = 0; i < AUTO_PIN_LAST; i++) {
16068 if (alc880_is_input_pin(cfg->input_pins[i])) {
16069 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16070 err = new_analog_input(spec, cfg->input_pins[i],
16071 auto_pin_cfg_labels[i],
16075 imux->items[imux->num_items].label =
16076 auto_pin_cfg_labels[i];
16077 imux->items[imux->num_items].index =
16078 alc880_input_pin_idx(cfg->input_pins[i]);
16085 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16086 hda_nid_t nid, int pin_type,
16089 alc_set_pin_output(codec, nid, pin_type);
16090 /* need the manual connection? */
16091 if (alc880_is_multi_pin(nid)) {
16092 struct alc_spec *spec = codec->spec;
16093 int idx = alc880_multi_pin_idx(nid);
16094 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16095 AC_VERB_SET_CONNECT_SEL,
16096 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16100 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16102 struct alc_spec *spec = codec->spec;
16105 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16106 for (i = 0; i <= HDA_SIDE; i++) {
16107 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16108 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16110 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16115 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16117 struct alc_spec *spec = codec->spec;
16120 pin = spec->autocfg.hp_pins[0];
16121 if (pin) /* connect to front */
16123 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16124 pin = spec->autocfg.speaker_pins[0];
16126 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16129 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16130 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16132 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16134 struct alc_spec *spec = codec->spec;
16137 for (i = 0; i < AUTO_PIN_LAST; i++) {
16138 hda_nid_t nid = spec->autocfg.input_pins[i];
16139 if (alc662_is_input_pin(nid)) {
16140 snd_hda_codec_write(codec, nid, 0,
16141 AC_VERB_SET_PIN_WIDGET_CONTROL,
16142 (i <= AUTO_PIN_FRONT_MIC ?
16143 PIN_VREF80 : PIN_IN));
16144 if (nid != ALC662_PIN_CD_NID)
16145 snd_hda_codec_write(codec, nid, 0,
16146 AC_VERB_SET_AMP_GAIN_MUTE,
16152 #define alc662_auto_init_input_src alc882_auto_init_input_src
16154 static int alc662_parse_auto_config(struct hda_codec *codec)
16156 struct alc_spec *spec = codec->spec;
16158 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16160 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16164 if (!spec->autocfg.line_outs)
16165 return 0; /* can't find valid BIOS pin config */
16167 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16170 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16173 err = alc662_auto_create_extra_out(spec,
16174 spec->autocfg.speaker_pins[0],
16178 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16182 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16186 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16188 if (spec->autocfg.dig_out_pin)
16189 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16191 if (spec->kctls.list)
16192 spec->mixers[spec->num_mixers++] = spec->kctls.list;
16194 spec->num_mux_defs = 1;
16195 spec->input_mux = &spec->private_imux;
16197 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
16198 if (codec->vendor_id == 0x10ec0663)
16199 spec->init_verbs[spec->num_init_verbs++] =
16200 alc663_auto_init_verbs;
16202 err = alc_auto_add_mic_boost(codec);
16206 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16207 spec->num_mixers++;
16211 /* additional initialization for auto-configuration model */
16212 static void alc662_auto_init(struct hda_codec *codec)
16214 struct alc_spec *spec = codec->spec;
16215 alc662_auto_init_multi_out(codec);
16216 alc662_auto_init_hp_out(codec);
16217 alc662_auto_init_analog_input(codec);
16218 alc662_auto_init_input_src(codec);
16219 if (spec->unsol_event)
16220 alc_sku_automute(codec);
16223 static int patch_alc662(struct hda_codec *codec)
16225 struct alc_spec *spec;
16226 int err, board_config;
16228 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16232 codec->spec = spec;
16234 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16236 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16239 if (board_config < 0) {
16240 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16241 "trying auto-probe from BIOS...\n");
16242 board_config = ALC662_AUTO;
16245 if (board_config == ALC662_AUTO) {
16246 /* automatic parse from the BIOS config */
16247 err = alc662_parse_auto_config(codec);
16253 "hda_codec: Cannot set up configuration "
16254 "from BIOS. Using base mode...\n");
16255 board_config = ALC662_3ST_2ch_DIG;
16259 if (board_config != ALC662_AUTO)
16260 setup_preset(spec, &alc662_presets[board_config]);
16262 if (codec->vendor_id == 0x10ec0663) {
16263 spec->stream_name_analog = "ALC663 Analog";
16264 spec->stream_name_digital = "ALC663 Digital";
16266 spec->stream_name_analog = "ALC662 Analog";
16267 spec->stream_name_digital = "ALC662 Digital";
16270 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16271 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16273 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16274 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16276 spec->adc_nids = alc662_adc_nids;
16277 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16278 spec->capsrc_nids = alc662_capsrc_nids;
16280 spec->vmaster_nid = 0x02;
16282 codec->patch_ops = alc_patch_ops;
16283 if (board_config == ALC662_AUTO)
16284 spec->init_hook = alc662_auto_init;
16285 #ifdef CONFIG_SND_HDA_POWER_SAVE
16286 if (!spec->loopback.amplist)
16287 spec->loopback.amplist = alc662_loopbacks;
16296 struct hda_codec_preset snd_hda_preset_realtek[] = {
16297 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16298 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16299 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16300 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16301 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16302 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16303 .patch = patch_alc861 },
16304 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16305 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16306 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16307 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16308 .patch = patch_alc883 },
16309 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16310 .patch = patch_alc662 },
16311 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16312 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16313 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16314 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16315 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16316 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16317 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16318 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16319 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16320 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16321 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16322 {} /* terminator */