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,
107 ALC262_MODEL_LAST /* last tag */
116 ALC268_ACER_ASPIRE_ONE,
119 #ifdef CONFIG_SND_DEBUG
123 ALC268_MODEL_LAST /* last tag */
130 ALC269_ASUS_EEEPC_P703,
131 ALC269_ASUS_EEEPC_P901,
133 ALC269_MODEL_LAST /* last tag */
150 /* ALC861-VD models */
171 ALC662_ASUS_EEEPC_P701,
172 ALC662_ASUS_EEEPC_EP20,
211 ALC883_TARGA_2ch_DIG,
217 ALC883_LENOVO_101E_2ch,
218 ALC883_LENOVO_NB0763,
219 ALC888_LENOVO_MS7195_DIG,
226 ALC883_FUJITSU_PI2515,
227 ALC883_3ST_6ch_INTEL,
235 #define GPIO_MASK 0x03
238 /* codec parameterization */
239 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
240 unsigned int num_mixers;
242 const struct hda_verb *init_verbs[5]; /* initialization verbs
246 unsigned int num_init_verbs;
248 char *stream_name_analog; /* analog PCM stream */
249 struct hda_pcm_stream *stream_analog_playback;
250 struct hda_pcm_stream *stream_analog_capture;
251 struct hda_pcm_stream *stream_analog_alt_playback;
252 struct hda_pcm_stream *stream_analog_alt_capture;
254 char *stream_name_digital; /* digital PCM stream */
255 struct hda_pcm_stream *stream_digital_playback;
256 struct hda_pcm_stream *stream_digital_capture;
259 struct hda_multi_out multiout; /* playback set-up
260 * max_channels, dacs must be set
261 * dig_out_nid and hp_nid are optional
263 hda_nid_t alt_dac_nid;
266 unsigned int num_adc_nids;
268 hda_nid_t *capsrc_nids;
269 hda_nid_t dig_in_nid; /* digital-in NID; optional */
272 unsigned int num_mux_defs;
273 const struct hda_input_mux *input_mux;
274 unsigned int cur_mux[3];
277 const struct hda_channel_mode *channel_mode;
278 int num_channel_mode;
281 /* PCM information */
282 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
284 /* dynamic controls, init_verbs and input_mux */
285 struct auto_pin_cfg autocfg;
286 unsigned int num_kctl_alloc, num_kctl_used;
287 struct snd_kcontrol_new *kctl_alloc;
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
1592 static int alc_build_controls(struct hda_codec *codec)
1594 struct alc_spec *spec = codec->spec;
1598 for (i = 0; i < spec->num_mixers; i++) {
1599 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1604 if (spec->multiout.dig_out_nid) {
1605 err = snd_hda_create_spdif_out_ctls(codec,
1606 spec->multiout.dig_out_nid);
1609 err = snd_hda_create_spdif_share_sw(codec,
1613 spec->multiout.share_spdif = 1;
1615 if (spec->dig_in_nid) {
1616 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1621 /* if we have no master control, let's create it */
1622 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1623 unsigned int vmaster_tlv[4];
1624 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1625 HDA_OUTPUT, vmaster_tlv);
1626 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1627 vmaster_tlv, alc_slave_vols);
1631 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1632 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1633 NULL, alc_slave_sws);
1643 * initialize the codec volumes, etc
1647 * generic initialization of ADC, input mixers and output mixers
1649 static struct hda_verb alc880_volume_init_verbs[] = {
1651 * Unmute ADC0-2 and set the default input to mic-in
1653 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1655 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1657 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1660 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1662 * Note: PASD motherboards uses the Line In 2 as the input for front
1665 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1666 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1667 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1668 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1669 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1670 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1671 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1672 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1675 * Set up output mixers (0x0c - 0x0f)
1677 /* set vol=0 to output mixers */
1678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1680 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1681 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1682 /* set up input amps for analog loopback */
1683 /* Amp Indices: DAC = 0, mixer = 1 */
1684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1690 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1691 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1697 * 3-stack pin configuration:
1698 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1700 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1702 * preset connection lists of input pins
1703 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1705 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1706 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1707 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1710 * Set pin mode and muting
1712 /* set front pin widgets 0x14 for output */
1713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1714 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1715 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1716 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1717 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1718 /* Mic2 (as headphone out) for HP output */
1719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1720 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1721 /* Line In pin widget for input */
1722 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1723 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1724 /* Line2 (as front mic) pin widget for input and vref at 80% */
1725 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1726 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1727 /* CD pin widget for input */
1728 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1734 * 5-stack pin configuration:
1735 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1736 * line-in/side = 0x1a, f-mic = 0x1b
1738 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1740 * preset connection lists of input pins
1741 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1743 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1744 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1747 * Set pin mode and muting
1749 /* set pin widgets 0x14-0x17 for output */
1750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1751 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1752 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1753 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1754 /* unmute pins for output (no gain on this amp) */
1755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1757 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1758 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1760 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1761 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1762 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1763 /* Mic2 (as headphone out) for HP output */
1764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1765 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1766 /* Line In pin widget for input */
1767 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1768 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1769 /* Line2 (as front mic) pin widget for input and vref at 80% */
1770 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1771 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1772 /* CD pin widget for input */
1773 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1779 * W810 pin configuration:
1780 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1782 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1783 /* hphone/speaker input selector: front DAC */
1784 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1786 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1787 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1788 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1789 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1790 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1791 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1793 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1794 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1800 * Z71V pin configuration:
1801 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1803 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1804 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1809 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1810 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1811 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1812 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1818 * 6-stack pin configuration:
1819 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1820 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1822 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1823 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1826 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1827 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1829 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1831 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1834 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1836 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1838 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1840 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1841 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1842 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1848 * Uniwill pin configuration:
1849 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1852 static struct hda_verb alc880_uniwill_init_verbs[] = {
1853 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1860 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1861 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1862 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1865 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1866 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1867 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1870 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1871 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1872 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1873 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1874 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1875 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1876 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1877 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1878 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1880 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1881 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1888 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1890 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1891 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1894 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1896 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1897 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1899 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1900 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1901 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1902 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1903 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1906 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1907 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1908 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1909 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1911 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1913 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1914 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1919 static struct hda_verb alc880_beep_init_verbs[] = {
1920 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1924 /* toggle speaker-output according to the hp-jack state */
1925 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1927 unsigned int present;
1930 present = snd_hda_codec_read(codec, 0x14, 0,
1931 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1932 bits = present ? HDA_AMP_MUTE : 0;
1933 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1934 HDA_AMP_MUTE, bits);
1935 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1936 HDA_AMP_MUTE, bits);
1939 /* auto-toggle front mic */
1940 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1942 unsigned int present;
1945 present = snd_hda_codec_read(codec, 0x18, 0,
1946 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1947 bits = present ? HDA_AMP_MUTE : 0;
1948 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1951 static void alc880_uniwill_automute(struct hda_codec *codec)
1953 alc880_uniwill_hp_automute(codec);
1954 alc880_uniwill_mic_automute(codec);
1957 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1960 /* Looks like the unsol event is incompatible with the standard
1961 * definition. 4bit tag is placed at 28 bit!
1963 switch (res >> 28) {
1964 case ALC880_HP_EVENT:
1965 alc880_uniwill_hp_automute(codec);
1967 case ALC880_MIC_EVENT:
1968 alc880_uniwill_mic_automute(codec);
1973 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1975 unsigned int present;
1978 present = snd_hda_codec_read(codec, 0x14, 0,
1979 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1980 bits = present ? HDA_AMP_MUTE : 0;
1981 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
1984 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1986 unsigned int present;
1988 present = snd_hda_codec_read(codec, 0x21, 0,
1989 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1990 present &= HDA_AMP_VOLMASK;
1991 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1992 HDA_AMP_VOLMASK, present);
1993 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1994 HDA_AMP_VOLMASK, present);
1997 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2000 /* Looks like the unsol event is incompatible with the standard
2001 * definition. 4bit tag is placed at 28 bit!
2003 if ((res >> 28) == ALC880_HP_EVENT)
2004 alc880_uniwill_p53_hp_automute(codec);
2005 if ((res >> 28) == ALC880_DCVOL_EVENT)
2006 alc880_uniwill_p53_dcvol_automute(codec);
2010 * F1734 pin configuration:
2011 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2013 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2014 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2015 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2016 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2017 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2018 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2020 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2021 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2022 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2023 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2025 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2026 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2027 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2028 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2029 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2030 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2031 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2032 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2033 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2035 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2036 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2042 * ASUS pin configuration:
2043 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2045 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2046 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2047 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2048 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2049 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2051 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2052 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2054 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2055 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2057 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2060 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2061 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2062 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2063 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2064 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2065 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2067 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2068 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2073 /* Enable GPIO mask and set output */
2074 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2075 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2077 /* Clevo m520g init */
2078 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2079 /* headphone output */
2080 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2082 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2083 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2086 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2088 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2089 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2090 /* Mic1 (rear panel) */
2091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2093 /* Mic2 (front panel) */
2094 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2095 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2097 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2098 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2099 /* change to EAPD mode */
2100 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2101 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2106 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2107 /* change to EAPD mode */
2108 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2109 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2111 /* Headphone output */
2112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2114 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2115 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2117 /* Line In pin widget for input */
2118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2119 /* CD pin widget for input */
2120 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2121 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2122 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2124 /* change to EAPD mode */
2125 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2126 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2132 * LG m1 express dual
2135 * Rear Line-In/Out (blue): 0x14
2136 * Build-in Mic-In: 0x15
2138 * HP-Out (green): 0x1b
2139 * Mic-In/Out (red): 0x19
2143 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2144 static hda_nid_t alc880_lg_dac_nids[3] = {
2148 /* seems analog CD is not working */
2149 static struct hda_input_mux alc880_lg_capture_source = {
2154 { "Internal Mic", 0x6 },
2158 /* 2,4,6 channel modes */
2159 static struct hda_verb alc880_lg_ch2_init[] = {
2160 /* set line-in and mic-in to input */
2161 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2162 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2166 static struct hda_verb alc880_lg_ch4_init[] = {
2167 /* set line-in to out and mic-in to input */
2168 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2169 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2173 static struct hda_verb alc880_lg_ch6_init[] = {
2174 /* set line-in and mic-in to output */
2175 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2176 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2180 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2181 { 2, alc880_lg_ch2_init },
2182 { 4, alc880_lg_ch4_init },
2183 { 6, alc880_lg_ch6_init },
2186 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2187 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2188 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2189 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2190 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2191 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2192 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2193 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2194 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2196 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2197 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2198 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2199 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2200 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2202 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2203 .name = "Channel Mode",
2204 .info = alc_ch_mode_info,
2205 .get = alc_ch_mode_get,
2206 .put = alc_ch_mode_put,
2211 static struct hda_verb alc880_lg_init_verbs[] = {
2212 /* set capture source to mic-in */
2213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2214 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2216 /* mute all amp mixer inputs */
2217 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2218 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2219 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2220 /* line-in to input */
2221 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2222 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2228 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 /* mic-in to input */
2230 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2231 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2232 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2234 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2235 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2236 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2242 /* toggle speaker-output according to the hp-jack state */
2243 static void alc880_lg_automute(struct hda_codec *codec)
2245 unsigned int present;
2248 present = snd_hda_codec_read(codec, 0x1b, 0,
2249 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2250 bits = present ? HDA_AMP_MUTE : 0;
2251 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2252 HDA_AMP_MUTE, bits);
2255 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2257 /* Looks like the unsol event is incompatible with the standard
2258 * definition. 4bit tag is placed at 28 bit!
2260 if ((res >> 28) == 0x01)
2261 alc880_lg_automute(codec);
2270 * Built-in Mic-In: 0x19
2276 static struct hda_input_mux alc880_lg_lw_capture_source = {
2280 { "Internal Mic", 0x1 },
2285 #define alc880_lg_lw_modes alc880_threestack_modes
2287 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2289 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2290 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2291 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2292 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2293 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2294 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2295 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2296 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2297 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2299 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2300 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2301 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2304 .name = "Channel Mode",
2305 .info = alc_ch_mode_info,
2306 .get = alc_ch_mode_get,
2307 .put = alc_ch_mode_put,
2312 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2313 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2314 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2315 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2317 /* set capture source to mic-in */
2318 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2321 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2326 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2327 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 /* mic-in to input */
2329 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2330 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2335 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2339 /* toggle speaker-output according to the hp-jack state */
2340 static void alc880_lg_lw_automute(struct hda_codec *codec)
2342 unsigned int present;
2345 present = snd_hda_codec_read(codec, 0x1b, 0,
2346 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2347 bits = present ? HDA_AMP_MUTE : 0;
2348 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2349 HDA_AMP_MUTE, bits);
2352 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2354 /* Looks like the unsol event is incompatible with the standard
2355 * definition. 4bit tag is placed at 28 bit!
2357 if ((res >> 28) == 0x01)
2358 alc880_lg_lw_automute(codec);
2361 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2362 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2363 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2366 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2367 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2371 static struct hda_input_mux alc880_medion_rim_capture_source = {
2375 { "Internal Mic", 0x1 },
2379 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2380 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2383 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2385 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2386 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2388 /* Mic2 (as headphone out) for HP output */
2389 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2390 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2391 /* Internal Speaker */
2392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2393 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2395 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2396 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2398 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2402 /* toggle speaker-output according to the hp-jack state */
2403 static void alc880_medion_rim_automute(struct hda_codec *codec)
2405 unsigned int present;
2408 present = snd_hda_codec_read(codec, 0x14, 0,
2409 AC_VERB_GET_PIN_SENSE, 0)
2410 & AC_PINSENSE_PRESENCE;
2411 bits = present ? HDA_AMP_MUTE : 0;
2412 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2413 HDA_AMP_MUTE, bits);
2415 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2417 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2420 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2423 /* Looks like the unsol event is incompatible with the standard
2424 * definition. 4bit tag is placed at 28 bit!
2426 if ((res >> 28) == ALC880_HP_EVENT)
2427 alc880_medion_rim_automute(codec);
2430 #ifdef CONFIG_SND_HDA_POWER_SAVE
2431 static struct hda_amp_list alc880_loopbacks[] = {
2432 { 0x0b, HDA_INPUT, 0 },
2433 { 0x0b, HDA_INPUT, 1 },
2434 { 0x0b, HDA_INPUT, 2 },
2435 { 0x0b, HDA_INPUT, 3 },
2436 { 0x0b, HDA_INPUT, 4 },
2440 static struct hda_amp_list alc880_lg_loopbacks[] = {
2441 { 0x0b, HDA_INPUT, 1 },
2442 { 0x0b, HDA_INPUT, 6 },
2443 { 0x0b, HDA_INPUT, 7 },
2452 static int alc_init(struct hda_codec *codec)
2454 struct alc_spec *spec = codec->spec;
2458 if (codec->vendor_id == 0x10ec0888)
2459 alc888_coef_init(codec);
2461 for (i = 0; i < spec->num_init_verbs; i++)
2462 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2464 if (spec->init_hook)
2465 spec->init_hook(codec);
2470 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2472 struct alc_spec *spec = codec->spec;
2474 if (spec->unsol_event)
2475 spec->unsol_event(codec, res);
2478 #ifdef CONFIG_SND_HDA_POWER_SAVE
2479 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2481 struct alc_spec *spec = codec->spec;
2482 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2487 * Analog playback callbacks
2489 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2490 struct hda_codec *codec,
2491 struct snd_pcm_substream *substream)
2493 struct alc_spec *spec = codec->spec;
2494 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2498 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2499 struct hda_codec *codec,
2500 unsigned int stream_tag,
2501 unsigned int format,
2502 struct snd_pcm_substream *substream)
2504 struct alc_spec *spec = codec->spec;
2505 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2506 stream_tag, format, substream);
2509 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2510 struct hda_codec *codec,
2511 struct snd_pcm_substream *substream)
2513 struct alc_spec *spec = codec->spec;
2514 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2520 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2521 struct hda_codec *codec,
2522 struct snd_pcm_substream *substream)
2524 struct alc_spec *spec = codec->spec;
2525 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2528 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2529 struct hda_codec *codec,
2530 unsigned int stream_tag,
2531 unsigned int format,
2532 struct snd_pcm_substream *substream)
2534 struct alc_spec *spec = codec->spec;
2535 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2536 stream_tag, format, substream);
2539 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2540 struct hda_codec *codec,
2541 struct snd_pcm_substream *substream)
2543 struct alc_spec *spec = codec->spec;
2544 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2550 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2551 struct hda_codec *codec,
2552 unsigned int stream_tag,
2553 unsigned int format,
2554 struct snd_pcm_substream *substream)
2556 struct alc_spec *spec = codec->spec;
2558 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2559 stream_tag, 0, format);
2563 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2564 struct hda_codec *codec,
2565 struct snd_pcm_substream *substream)
2567 struct alc_spec *spec = codec->spec;
2569 snd_hda_codec_cleanup_stream(codec,
2570 spec->adc_nids[substream->number + 1]);
2577 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2581 /* NID is set in alc_build_pcms */
2583 .open = alc880_playback_pcm_open,
2584 .prepare = alc880_playback_pcm_prepare,
2585 .cleanup = alc880_playback_pcm_cleanup
2589 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2593 /* NID is set in alc_build_pcms */
2596 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2600 /* NID is set in alc_build_pcms */
2603 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2604 .substreams = 2, /* can be overridden */
2607 /* NID is set in alc_build_pcms */
2609 .prepare = alc880_alt_capture_pcm_prepare,
2610 .cleanup = alc880_alt_capture_pcm_cleanup
2614 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2618 /* NID is set in alc_build_pcms */
2620 .open = alc880_dig_playback_pcm_open,
2621 .close = alc880_dig_playback_pcm_close,
2622 .prepare = alc880_dig_playback_pcm_prepare
2626 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2630 /* NID is set in alc_build_pcms */
2633 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2634 static struct hda_pcm_stream alc_pcm_null_stream = {
2640 static int alc_build_pcms(struct hda_codec *codec)
2642 struct alc_spec *spec = codec->spec;
2643 struct hda_pcm *info = spec->pcm_rec;
2646 codec->num_pcms = 1;
2647 codec->pcm_info = info;
2649 info->name = spec->stream_name_analog;
2650 if (spec->stream_analog_playback) {
2651 if (snd_BUG_ON(!spec->multiout.dac_nids))
2653 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2654 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2656 if (spec->stream_analog_capture) {
2657 if (snd_BUG_ON(!spec->adc_nids))
2659 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2660 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2663 if (spec->channel_mode) {
2664 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2665 for (i = 0; i < spec->num_channel_mode; i++) {
2666 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2667 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2672 /* SPDIF for stream index #1 */
2673 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2674 codec->num_pcms = 2;
2675 info = spec->pcm_rec + 1;
2676 info->name = spec->stream_name_digital;
2677 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2678 if (spec->multiout.dig_out_nid &&
2679 spec->stream_digital_playback) {
2680 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2681 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2683 if (spec->dig_in_nid &&
2684 spec->stream_digital_capture) {
2685 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2686 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2688 /* FIXME: do we need this for all Realtek codec models? */
2689 codec->spdif_status_reset = 1;
2692 /* If the use of more than one ADC is requested for the current
2693 * model, configure a second analog capture-only PCM.
2695 /* Additional Analaog capture for index #2 */
2696 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2697 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2698 codec->num_pcms = 3;
2699 info = spec->pcm_rec + 2;
2700 info->name = spec->stream_name_analog;
2701 if (spec->alt_dac_nid) {
2702 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2703 *spec->stream_analog_alt_playback;
2704 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2707 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2708 alc_pcm_null_stream;
2709 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2711 if (spec->num_adc_nids > 1) {
2712 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2713 *spec->stream_analog_alt_capture;
2714 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2716 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2717 spec->num_adc_nids - 1;
2719 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2720 alc_pcm_null_stream;
2721 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2728 static void alc_free(struct hda_codec *codec)
2730 struct alc_spec *spec = codec->spec;
2736 if (spec->kctl_alloc) {
2737 for (i = 0; i < spec->num_kctl_used; i++)
2738 kfree(spec->kctl_alloc[i].name);
2739 kfree(spec->kctl_alloc);
2742 codec->spec = NULL; /* to be sure */
2747 static struct hda_codec_ops alc_patch_ops = {
2748 .build_controls = alc_build_controls,
2749 .build_pcms = alc_build_pcms,
2752 .unsol_event = alc_unsol_event,
2753 #ifdef CONFIG_SND_HDA_POWER_SAVE
2754 .check_power_status = alc_check_power_status,
2760 * Test configuration for debugging
2762 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2765 #ifdef CONFIG_SND_DEBUG
2766 static hda_nid_t alc880_test_dac_nids[4] = {
2767 0x02, 0x03, 0x04, 0x05
2770 static struct hda_input_mux alc880_test_capture_source = {
2779 { "Surround", 0x6 },
2783 static struct hda_channel_mode alc880_test_modes[4] = {
2790 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2791 struct snd_ctl_elem_info *uinfo)
2793 static char *texts[] = {
2794 "N/A", "Line Out", "HP Out",
2795 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2797 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2799 uinfo->value.enumerated.items = 8;
2800 if (uinfo->value.enumerated.item >= 8)
2801 uinfo->value.enumerated.item = 7;
2802 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2806 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2807 struct snd_ctl_elem_value *ucontrol)
2809 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2810 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2811 unsigned int pin_ctl, item = 0;
2813 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2814 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2815 if (pin_ctl & AC_PINCTL_OUT_EN) {
2816 if (pin_ctl & AC_PINCTL_HP_EN)
2820 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2821 switch (pin_ctl & AC_PINCTL_VREFEN) {
2822 case AC_PINCTL_VREF_HIZ: item = 3; break;
2823 case AC_PINCTL_VREF_50: item = 4; break;
2824 case AC_PINCTL_VREF_GRD: item = 5; break;
2825 case AC_PINCTL_VREF_80: item = 6; break;
2826 case AC_PINCTL_VREF_100: item = 7; break;
2829 ucontrol->value.enumerated.item[0] = item;
2833 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2834 struct snd_ctl_elem_value *ucontrol)
2836 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2837 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2838 static unsigned int ctls[] = {
2839 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2840 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2841 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2842 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2843 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2844 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2846 unsigned int old_ctl, new_ctl;
2848 old_ctl = snd_hda_codec_read(codec, nid, 0,
2849 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2850 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2851 if (old_ctl != new_ctl) {
2853 snd_hda_codec_write_cache(codec, nid, 0,
2854 AC_VERB_SET_PIN_WIDGET_CONTROL,
2856 val = ucontrol->value.enumerated.item[0] >= 3 ?
2858 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2865 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2866 struct snd_ctl_elem_info *uinfo)
2868 static char *texts[] = {
2869 "Front", "Surround", "CLFE", "Side"
2871 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2873 uinfo->value.enumerated.items = 4;
2874 if (uinfo->value.enumerated.item >= 4)
2875 uinfo->value.enumerated.item = 3;
2876 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2880 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2881 struct snd_ctl_elem_value *ucontrol)
2883 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2884 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2887 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2888 ucontrol->value.enumerated.item[0] = sel & 3;
2892 static int alc_test_pin_src_put(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) & 3;
2900 if (ucontrol->value.enumerated.item[0] != sel) {
2901 sel = ucontrol->value.enumerated.item[0] & 3;
2902 snd_hda_codec_write_cache(codec, nid, 0,
2903 AC_VERB_SET_CONNECT_SEL, sel);
2909 #define PIN_CTL_TEST(xname,nid) { \
2910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2912 .info = alc_test_pin_ctl_info, \
2913 .get = alc_test_pin_ctl_get, \
2914 .put = alc_test_pin_ctl_put, \
2915 .private_value = nid \
2918 #define PIN_SRC_TEST(xname,nid) { \
2919 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2921 .info = alc_test_pin_src_info, \
2922 .get = alc_test_pin_src_get, \
2923 .put = alc_test_pin_src_put, \
2924 .private_value = nid \
2927 static struct snd_kcontrol_new alc880_test_mixer[] = {
2928 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2929 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2930 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2931 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2932 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2933 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2934 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2935 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2936 PIN_CTL_TEST("Front Pin Mode", 0x14),
2937 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2938 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2939 PIN_CTL_TEST("Side Pin Mode", 0x17),
2940 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2941 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2942 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2943 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2944 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2945 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2946 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2947 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2948 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2949 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2950 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2951 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2952 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2953 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2954 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2955 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2956 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2957 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2959 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2960 .name = "Channel Mode",
2961 .info = alc_ch_mode_info,
2962 .get = alc_ch_mode_get,
2963 .put = alc_ch_mode_put,
2968 static struct hda_verb alc880_test_init_verbs[] = {
2969 /* Unmute inputs of 0x0c - 0x0f */
2970 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2972 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2974 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2975 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2976 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2977 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2978 /* Vol output for 0x0c-0x0f */
2979 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2980 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2981 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2982 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2983 /* Set output pins 0x14-0x17 */
2984 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2986 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2987 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2988 /* Unmute output pins 0x14-0x17 */
2989 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2990 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2991 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2992 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2993 /* Set input pins 0x18-0x1c */
2994 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2995 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2996 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2998 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2999 /* Mute input pins 0x18-0x1b */
3000 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3001 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3003 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3006 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3007 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3008 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3010 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3011 /* Analog input/passthru */
3012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3024 static const char *alc880_models[ALC880_MODEL_LAST] = {
3025 [ALC880_3ST] = "3stack",
3026 [ALC880_TCL_S700] = "tcl",
3027 [ALC880_3ST_DIG] = "3stack-digout",
3028 [ALC880_CLEVO] = "clevo",
3029 [ALC880_5ST] = "5stack",
3030 [ALC880_5ST_DIG] = "5stack-digout",
3031 [ALC880_W810] = "w810",
3032 [ALC880_Z71V] = "z71v",
3033 [ALC880_6ST] = "6stack",
3034 [ALC880_6ST_DIG] = "6stack-digout",
3035 [ALC880_ASUS] = "asus",
3036 [ALC880_ASUS_W1V] = "asus-w1v",
3037 [ALC880_ASUS_DIG] = "asus-dig",
3038 [ALC880_ASUS_DIG2] = "asus-dig2",
3039 [ALC880_UNIWILL_DIG] = "uniwill",
3040 [ALC880_UNIWILL_P53] = "uniwill-p53",
3041 [ALC880_FUJITSU] = "fujitsu",
3042 [ALC880_F1734] = "F1734",
3044 [ALC880_LG_LW] = "lg-lw",
3045 [ALC880_MEDION_RIM] = "medion",
3046 #ifdef CONFIG_SND_DEBUG
3047 [ALC880_TEST] = "test",
3049 [ALC880_AUTO] = "auto",
3052 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3053 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3054 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3055 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3056 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3057 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3058 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3059 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3060 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3061 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3062 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3063 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3064 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3065 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3066 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3067 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3068 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3069 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3070 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3071 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3072 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3073 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3074 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3075 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3076 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3077 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3078 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3079 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3080 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3081 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3082 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3083 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3084 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3085 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3086 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3087 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3088 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3089 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3090 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3091 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3092 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3093 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3094 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3095 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3096 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3097 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3098 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3099 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3100 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3101 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3102 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3103 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3104 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3105 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3106 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3107 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3108 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3109 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3110 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3111 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3112 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3113 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3114 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3115 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3116 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3117 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3118 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3119 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3120 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3121 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3122 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3123 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3128 * ALC880 codec presets
3130 static struct alc_config_preset alc880_presets[] = {
3132 .mixers = { alc880_three_stack_mixer },
3133 .init_verbs = { alc880_volume_init_verbs,
3134 alc880_pin_3stack_init_verbs },
3135 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3136 .dac_nids = alc880_dac_nids,
3137 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3138 .channel_mode = alc880_threestack_modes,
3140 .input_mux = &alc880_capture_source,
3142 [ALC880_3ST_DIG] = {
3143 .mixers = { alc880_three_stack_mixer },
3144 .init_verbs = { alc880_volume_init_verbs,
3145 alc880_pin_3stack_init_verbs },
3146 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3147 .dac_nids = alc880_dac_nids,
3148 .dig_out_nid = ALC880_DIGOUT_NID,
3149 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3150 .channel_mode = alc880_threestack_modes,
3152 .input_mux = &alc880_capture_source,
3154 [ALC880_TCL_S700] = {
3155 .mixers = { alc880_tcl_s700_mixer },
3156 .init_verbs = { alc880_volume_init_verbs,
3157 alc880_pin_tcl_S700_init_verbs,
3158 alc880_gpio2_init_verbs },
3159 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3160 .dac_nids = alc880_dac_nids,
3162 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3163 .channel_mode = alc880_2_jack_modes,
3164 .input_mux = &alc880_capture_source,
3167 .mixers = { alc880_three_stack_mixer,
3168 alc880_five_stack_mixer},
3169 .init_verbs = { alc880_volume_init_verbs,
3170 alc880_pin_5stack_init_verbs },
3171 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3172 .dac_nids = alc880_dac_nids,
3173 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3174 .channel_mode = alc880_fivestack_modes,
3175 .input_mux = &alc880_capture_source,
3177 [ALC880_5ST_DIG] = {
3178 .mixers = { alc880_three_stack_mixer,
3179 alc880_five_stack_mixer },
3180 .init_verbs = { alc880_volume_init_verbs,
3181 alc880_pin_5stack_init_verbs },
3182 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3183 .dac_nids = alc880_dac_nids,
3184 .dig_out_nid = ALC880_DIGOUT_NID,
3185 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3186 .channel_mode = alc880_fivestack_modes,
3187 .input_mux = &alc880_capture_source,
3190 .mixers = { alc880_six_stack_mixer },
3191 .init_verbs = { alc880_volume_init_verbs,
3192 alc880_pin_6stack_init_verbs },
3193 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3194 .dac_nids = alc880_6st_dac_nids,
3195 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3196 .channel_mode = alc880_sixstack_modes,
3197 .input_mux = &alc880_6stack_capture_source,
3199 [ALC880_6ST_DIG] = {
3200 .mixers = { alc880_six_stack_mixer },
3201 .init_verbs = { alc880_volume_init_verbs,
3202 alc880_pin_6stack_init_verbs },
3203 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3204 .dac_nids = alc880_6st_dac_nids,
3205 .dig_out_nid = ALC880_DIGOUT_NID,
3206 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3207 .channel_mode = alc880_sixstack_modes,
3208 .input_mux = &alc880_6stack_capture_source,
3211 .mixers = { alc880_w810_base_mixer },
3212 .init_verbs = { alc880_volume_init_verbs,
3213 alc880_pin_w810_init_verbs,
3214 alc880_gpio2_init_verbs },
3215 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3216 .dac_nids = alc880_w810_dac_nids,
3217 .dig_out_nid = ALC880_DIGOUT_NID,
3218 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3219 .channel_mode = alc880_w810_modes,
3220 .input_mux = &alc880_capture_source,
3223 .mixers = { alc880_z71v_mixer },
3224 .init_verbs = { alc880_volume_init_verbs,
3225 alc880_pin_z71v_init_verbs },
3226 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3227 .dac_nids = alc880_z71v_dac_nids,
3228 .dig_out_nid = ALC880_DIGOUT_NID,
3230 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3231 .channel_mode = alc880_2_jack_modes,
3232 .input_mux = &alc880_capture_source,
3235 .mixers = { alc880_f1734_mixer },
3236 .init_verbs = { alc880_volume_init_verbs,
3237 alc880_pin_f1734_init_verbs },
3238 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3239 .dac_nids = alc880_f1734_dac_nids,
3241 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3242 .channel_mode = alc880_2_jack_modes,
3243 .input_mux = &alc880_f1734_capture_source,
3244 .unsol_event = alc880_uniwill_p53_unsol_event,
3245 .init_hook = alc880_uniwill_p53_hp_automute,
3248 .mixers = { alc880_asus_mixer },
3249 .init_verbs = { alc880_volume_init_verbs,
3250 alc880_pin_asus_init_verbs,
3251 alc880_gpio1_init_verbs },
3252 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3253 .dac_nids = alc880_asus_dac_nids,
3254 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3255 .channel_mode = alc880_asus_modes,
3257 .input_mux = &alc880_capture_source,
3259 [ALC880_ASUS_DIG] = {
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 .dig_out_nid = ALC880_DIGOUT_NID,
3267 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3268 .channel_mode = alc880_asus_modes,
3270 .input_mux = &alc880_capture_source,
3272 [ALC880_ASUS_DIG2] = {
3273 .mixers = { alc880_asus_mixer },
3274 .init_verbs = { alc880_volume_init_verbs,
3275 alc880_pin_asus_init_verbs,
3276 alc880_gpio2_init_verbs }, /* use GPIO2 */
3277 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3278 .dac_nids = alc880_asus_dac_nids,
3279 .dig_out_nid = ALC880_DIGOUT_NID,
3280 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3281 .channel_mode = alc880_asus_modes,
3283 .input_mux = &alc880_capture_source,
3285 [ALC880_ASUS_W1V] = {
3286 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3287 .init_verbs = { alc880_volume_init_verbs,
3288 alc880_pin_asus_init_verbs,
3289 alc880_gpio1_init_verbs },
3290 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3291 .dac_nids = alc880_asus_dac_nids,
3292 .dig_out_nid = ALC880_DIGOUT_NID,
3293 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3294 .channel_mode = alc880_asus_modes,
3296 .input_mux = &alc880_capture_source,
3298 [ALC880_UNIWILL_DIG] = {
3299 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3300 .init_verbs = { alc880_volume_init_verbs,
3301 alc880_pin_asus_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] = {
3311 .mixers = { alc880_uniwill_mixer },
3312 .init_verbs = { alc880_volume_init_verbs,
3313 alc880_uniwill_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_threestack_modes),
3318 .channel_mode = alc880_threestack_modes,
3320 .input_mux = &alc880_capture_source,
3321 .unsol_event = alc880_uniwill_unsol_event,
3322 .init_hook = alc880_uniwill_automute,
3324 [ALC880_UNIWILL_P53] = {
3325 .mixers = { alc880_uniwill_p53_mixer },
3326 .init_verbs = { alc880_volume_init_verbs,
3327 alc880_uniwill_p53_init_verbs },
3328 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3329 .dac_nids = alc880_asus_dac_nids,
3330 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3331 .channel_mode = alc880_threestack_modes,
3332 .input_mux = &alc880_capture_source,
3333 .unsol_event = alc880_uniwill_p53_unsol_event,
3334 .init_hook = alc880_uniwill_p53_hp_automute,
3336 [ALC880_FUJITSU] = {
3337 .mixers = { alc880_fujitsu_mixer,
3338 alc880_pcbeep_mixer, },
3339 .init_verbs = { alc880_volume_init_verbs,
3340 alc880_uniwill_p53_init_verbs,
3341 alc880_beep_init_verbs },
3342 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3343 .dac_nids = alc880_dac_nids,
3344 .dig_out_nid = ALC880_DIGOUT_NID,
3345 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3346 .channel_mode = alc880_2_jack_modes,
3347 .input_mux = &alc880_capture_source,
3348 .unsol_event = alc880_uniwill_p53_unsol_event,
3349 .init_hook = alc880_uniwill_p53_hp_automute,
3352 .mixers = { alc880_three_stack_mixer },
3353 .init_verbs = { alc880_volume_init_verbs,
3354 alc880_pin_clevo_init_verbs },
3355 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3356 .dac_nids = alc880_dac_nids,
3358 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3359 .channel_mode = alc880_threestack_modes,
3361 .input_mux = &alc880_capture_source,
3364 .mixers = { alc880_lg_mixer },
3365 .init_verbs = { alc880_volume_init_verbs,
3366 alc880_lg_init_verbs },
3367 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3368 .dac_nids = alc880_lg_dac_nids,
3369 .dig_out_nid = ALC880_DIGOUT_NID,
3370 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3371 .channel_mode = alc880_lg_ch_modes,
3373 .input_mux = &alc880_lg_capture_source,
3374 .unsol_event = alc880_lg_unsol_event,
3375 .init_hook = alc880_lg_automute,
3376 #ifdef CONFIG_SND_HDA_POWER_SAVE
3377 .loopbacks = alc880_lg_loopbacks,
3381 .mixers = { alc880_lg_lw_mixer },
3382 .init_verbs = { alc880_volume_init_verbs,
3383 alc880_lg_lw_init_verbs },
3384 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3385 .dac_nids = alc880_dac_nids,
3386 .dig_out_nid = ALC880_DIGOUT_NID,
3387 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3388 .channel_mode = alc880_lg_lw_modes,
3389 .input_mux = &alc880_lg_lw_capture_source,
3390 .unsol_event = alc880_lg_lw_unsol_event,
3391 .init_hook = alc880_lg_lw_automute,
3393 [ALC880_MEDION_RIM] = {
3394 .mixers = { alc880_medion_rim_mixer },
3395 .init_verbs = { alc880_volume_init_verbs,
3396 alc880_medion_rim_init_verbs,
3397 alc_gpio2_init_verbs },
3398 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3399 .dac_nids = alc880_dac_nids,
3400 .dig_out_nid = ALC880_DIGOUT_NID,
3401 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3402 .channel_mode = alc880_2_jack_modes,
3403 .input_mux = &alc880_medion_rim_capture_source,
3404 .unsol_event = alc880_medion_rim_unsol_event,
3405 .init_hook = alc880_medion_rim_automute,
3407 #ifdef CONFIG_SND_DEBUG
3409 .mixers = { alc880_test_mixer },
3410 .init_verbs = { alc880_test_init_verbs },
3411 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3412 .dac_nids = alc880_test_dac_nids,
3413 .dig_out_nid = ALC880_DIGOUT_NID,
3414 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3415 .channel_mode = alc880_test_modes,
3416 .input_mux = &alc880_test_capture_source,
3422 * Automatic parse of I/O pins from the BIOS configuration
3425 #define NUM_CONTROL_ALLOC 32
3426 #define NUM_VERB_ALLOC 32
3430 ALC_CTL_WIDGET_MUTE,
3433 static struct snd_kcontrol_new alc880_control_templates[] = {
3434 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3435 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3436 HDA_BIND_MUTE(NULL, 0, 0, 0),
3439 /* add dynamic controls */
3440 static int add_control(struct alc_spec *spec, int type, const char *name,
3443 struct snd_kcontrol_new *knew;
3445 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3446 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3448 /* array + terminator */
3449 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3452 if (spec->kctl_alloc) {
3453 memcpy(knew, spec->kctl_alloc,
3454 sizeof(*knew) * spec->num_kctl_alloc);
3455 kfree(spec->kctl_alloc);
3457 spec->kctl_alloc = knew;
3458 spec->num_kctl_alloc = num;
3461 knew = &spec->kctl_alloc[spec->num_kctl_used];
3462 *knew = alc880_control_templates[type];
3463 knew->name = kstrdup(name, GFP_KERNEL);
3466 knew->private_value = val;
3467 spec->num_kctl_used++;
3471 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3472 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3473 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3474 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3475 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3476 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3477 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3478 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3479 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3480 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3481 #define ALC880_PIN_CD_NID 0x1c
3483 /* fill in the dac_nids table from the parsed pin configuration */
3484 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3485 const struct auto_pin_cfg *cfg)
3491 memset(assigned, 0, sizeof(assigned));
3492 spec->multiout.dac_nids = spec->private_dac_nids;
3494 /* check the pins hardwired to audio widget */
3495 for (i = 0; i < cfg->line_outs; i++) {
3496 nid = cfg->line_out_pins[i];
3497 if (alc880_is_fixed_pin(nid)) {
3498 int idx = alc880_fixed_pin_idx(nid);
3499 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3503 /* left pins can be connect to any audio widget */
3504 for (i = 0; i < cfg->line_outs; i++) {
3505 nid = cfg->line_out_pins[i];
3506 if (alc880_is_fixed_pin(nid))
3508 /* search for an empty channel */
3509 for (j = 0; j < cfg->line_outs; j++) {
3511 spec->multiout.dac_nids[i] =
3512 alc880_idx_to_dac(j);
3518 spec->multiout.num_dacs = cfg->line_outs;
3522 /* add playback controls from the parsed DAC table */
3523 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3524 const struct auto_pin_cfg *cfg)
3527 static const char *chname[4] = {
3528 "Front", "Surround", NULL /*CLFE*/, "Side"
3533 for (i = 0; i < cfg->line_outs; i++) {
3534 if (!spec->multiout.dac_nids[i])
3536 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3539 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3540 "Center Playback Volume",
3541 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3545 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3546 "LFE Playback Volume",
3547 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3551 err = add_control(spec, ALC_CTL_BIND_MUTE,
3552 "Center Playback Switch",
3553 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3557 err = add_control(spec, ALC_CTL_BIND_MUTE,
3558 "LFE Playback Switch",
3559 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3564 sprintf(name, "%s Playback Volume", chname[i]);
3565 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3566 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3570 sprintf(name, "%s Playback Switch", chname[i]);
3571 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3572 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3581 /* add playback controls for speaker and HP outputs */
3582 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3592 if (alc880_is_fixed_pin(pin)) {
3593 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3594 /* specify the DAC as the extra output */
3595 if (!spec->multiout.hp_nid)
3596 spec->multiout.hp_nid = nid;
3598 spec->multiout.extra_out_nid[0] = nid;
3599 /* control HP volume/switch on the output mixer amp */
3600 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3601 sprintf(name, "%s Playback Volume", pfx);
3602 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3603 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3606 sprintf(name, "%s Playback Switch", pfx);
3607 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3608 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3611 } else if (alc880_is_multi_pin(pin)) {
3612 /* set manual connection */
3613 /* we have only a switch on HP-out PIN */
3614 sprintf(name, "%s Playback Switch", pfx);
3615 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3616 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3623 /* create input playback/capture controls for the given pin */
3624 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3625 const char *ctlname,
3626 int idx, hda_nid_t mix_nid)
3631 sprintf(name, "%s Playback Volume", ctlname);
3632 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3633 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3636 sprintf(name, "%s Playback Switch", ctlname);
3637 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3638 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3644 /* create playback/capture controls for input pins */
3645 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3646 const struct auto_pin_cfg *cfg)
3648 struct hda_input_mux *imux = &spec->private_imux;
3651 for (i = 0; i < AUTO_PIN_LAST; i++) {
3652 if (alc880_is_input_pin(cfg->input_pins[i])) {
3653 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3654 err = new_analog_input(spec, cfg->input_pins[i],
3655 auto_pin_cfg_labels[i],
3659 imux->items[imux->num_items].label =
3660 auto_pin_cfg_labels[i];
3661 imux->items[imux->num_items].index =
3662 alc880_input_pin_idx(cfg->input_pins[i]);
3669 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3670 unsigned int pin_type)
3672 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3675 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3679 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3680 hda_nid_t nid, int pin_type,
3683 alc_set_pin_output(codec, nid, pin_type);
3684 /* need the manual connection? */
3685 if (alc880_is_multi_pin(nid)) {
3686 struct alc_spec *spec = codec->spec;
3687 int idx = alc880_multi_pin_idx(nid);
3688 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3689 AC_VERB_SET_CONNECT_SEL,
3690 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3694 static int get_pin_type(int line_out_type)
3696 if (line_out_type == AUTO_PIN_HP_OUT)
3702 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3704 struct alc_spec *spec = codec->spec;
3707 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3708 for (i = 0; i < spec->autocfg.line_outs; i++) {
3709 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3710 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3711 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3715 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3717 struct alc_spec *spec = codec->spec;
3720 pin = spec->autocfg.speaker_pins[0];
3721 if (pin) /* connect to front */
3722 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3723 pin = spec->autocfg.hp_pins[0];
3724 if (pin) /* connect to front */
3725 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3728 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3730 struct alc_spec *spec = codec->spec;
3733 for (i = 0; i < AUTO_PIN_LAST; i++) {
3734 hda_nid_t nid = spec->autocfg.input_pins[i];
3735 if (alc880_is_input_pin(nid)) {
3736 snd_hda_codec_write(codec, nid, 0,
3737 AC_VERB_SET_PIN_WIDGET_CONTROL,
3738 i <= AUTO_PIN_FRONT_MIC ?
3739 PIN_VREF80 : PIN_IN);
3740 if (nid != ALC880_PIN_CD_NID)
3741 snd_hda_codec_write(codec, nid, 0,
3742 AC_VERB_SET_AMP_GAIN_MUTE,
3748 /* parse the BIOS configuration and set up the alc_spec */
3749 /* return 1 if successful, 0 if the proper config is not found,
3750 * or a negative error code
3752 static int alc880_parse_auto_config(struct hda_codec *codec)
3754 struct alc_spec *spec = codec->spec;
3756 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3758 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3762 if (!spec->autocfg.line_outs)
3763 return 0; /* can't find valid BIOS pin config */
3765 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3768 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3771 err = alc880_auto_create_extra_out(spec,
3772 spec->autocfg.speaker_pins[0],
3776 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3780 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3784 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3786 if (spec->autocfg.dig_out_pin)
3787 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3788 if (spec->autocfg.dig_in_pin)
3789 spec->dig_in_nid = ALC880_DIGIN_NID;
3791 if (spec->kctl_alloc)
3792 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3794 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3796 spec->num_mux_defs = 1;
3797 spec->input_mux = &spec->private_imux;
3802 /* additional initialization for auto-configuration model */
3803 static void alc880_auto_init(struct hda_codec *codec)
3805 struct alc_spec *spec = codec->spec;
3806 alc880_auto_init_multi_out(codec);
3807 alc880_auto_init_extra_out(codec);
3808 alc880_auto_init_analog_input(codec);
3809 if (spec->unsol_event)
3810 alc_sku_automute(codec);
3814 * OK, here we have finally the patch for ALC880
3817 static int patch_alc880(struct hda_codec *codec)
3819 struct alc_spec *spec;
3823 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3829 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3832 if (board_config < 0) {
3833 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3834 "trying auto-probe from BIOS...\n");
3835 board_config = ALC880_AUTO;
3838 if (board_config == ALC880_AUTO) {
3839 /* automatic parse from the BIOS config */
3840 err = alc880_parse_auto_config(codec);
3846 "hda_codec: Cannot set up configuration "
3847 "from BIOS. Using 3-stack mode...\n");
3848 board_config = ALC880_3ST;
3852 if (board_config != ALC880_AUTO)
3853 setup_preset(spec, &alc880_presets[board_config]);
3855 spec->stream_name_analog = "ALC880 Analog";
3856 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3857 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3858 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3860 spec->stream_name_digital = "ALC880 Digital";
3861 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3862 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3864 if (!spec->adc_nids && spec->input_mux) {
3865 /* check whether NID 0x07 is valid */
3866 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3868 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3869 if (wcap != AC_WID_AUD_IN) {
3870 spec->adc_nids = alc880_adc_nids_alt;
3871 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3872 spec->mixers[spec->num_mixers] =
3873 alc880_capture_alt_mixer;
3876 spec->adc_nids = alc880_adc_nids;
3877 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3878 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3883 spec->vmaster_nid = 0x0c;
3885 codec->patch_ops = alc_patch_ops;
3886 if (board_config == ALC880_AUTO)
3887 spec->init_hook = alc880_auto_init;
3888 #ifdef CONFIG_SND_HDA_POWER_SAVE
3889 if (!spec->loopback.amplist)
3890 spec->loopback.amplist = alc880_loopbacks;
3901 static hda_nid_t alc260_dac_nids[1] = {
3906 static hda_nid_t alc260_adc_nids[1] = {
3911 static hda_nid_t alc260_adc_nids_alt[1] = {
3916 static hda_nid_t alc260_hp_adc_nids[2] = {
3921 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3922 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3924 static hda_nid_t alc260_dual_adc_nids[2] = {
3929 #define ALC260_DIGOUT_NID 0x03
3930 #define ALC260_DIGIN_NID 0x06
3932 static struct hda_input_mux alc260_capture_source = {
3936 { "Front Mic", 0x1 },
3942 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3943 * headphone jack and the internal CD lines since these are the only pins at
3944 * which audio can appear. For flexibility, also allow the option of
3945 * recording the mixer output on the second ADC (ADC0 doesn't have a
3946 * connection to the mixer output).
3948 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3952 { "Mic/Line", 0x0 },
3954 { "Headphone", 0x2 },
3960 { "Mic/Line", 0x0 },
3962 { "Headphone", 0x2 },
3969 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3970 * the Fujitsu S702x, but jacks are marked differently.
3972 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3979 { "Headphone", 0x5 },
3988 { "Headphone", 0x6 },
3994 * This is just place-holder, so there's something for alc_build_pcms to look
3995 * at when it calculates the maximum number of channels. ALC260 has no mixer
3996 * element which allows changing the channel mode, so the verb list is
3999 static struct hda_channel_mode alc260_modes[1] = {
4004 /* Mixer combinations
4006 * basic: base_output + input + pc_beep + capture
4007 * HP: base_output + input + capture_alt
4008 * HP_3013: hp_3013 + input + capture
4009 * fujitsu: fujitsu + capture
4010 * acer: acer + capture
4013 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4014 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4015 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4016 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4017 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4018 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4019 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4023 static struct snd_kcontrol_new alc260_input_mixer[] = {
4024 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4025 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4026 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4027 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4028 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4029 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4031 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4035 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4036 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4037 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4041 /* update HP, line and mono out pins according to the master switch */
4042 static void alc260_hp_master_update(struct hda_codec *codec,
4043 hda_nid_t hp, hda_nid_t line,
4046 struct alc_spec *spec = codec->spec;
4047 unsigned int val = spec->master_sw ? PIN_HP : 0;
4048 /* change HP and line-out pins */
4049 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4051 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4053 /* mono (speaker) depending on the HP jack sense */
4054 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4055 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4059 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4060 struct snd_ctl_elem_value *ucontrol)
4062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4063 struct alc_spec *spec = codec->spec;
4064 *ucontrol->value.integer.value = spec->master_sw;
4068 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4069 struct snd_ctl_elem_value *ucontrol)
4071 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4072 struct alc_spec *spec = codec->spec;
4073 int val = !!*ucontrol->value.integer.value;
4074 hda_nid_t hp, line, mono;
4076 if (val == spec->master_sw)
4078 spec->master_sw = val;
4079 hp = (kcontrol->private_value >> 16) & 0xff;
4080 line = (kcontrol->private_value >> 8) & 0xff;
4081 mono = kcontrol->private_value & 0xff;
4082 alc260_hp_master_update(codec, hp, line, mono);
4086 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4089 .name = "Master Playback Switch",
4090 .info = snd_ctl_boolean_mono_info,
4091 .get = alc260_hp_master_sw_get,
4092 .put = alc260_hp_master_sw_put,
4093 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4095 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4096 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4098 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4099 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4101 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4105 static struct hda_verb alc260_hp_unsol_verbs[] = {
4106 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4110 static void alc260_hp_automute(struct hda_codec *codec)
4112 struct alc_spec *spec = codec->spec;
4113 unsigned int present;
4115 present = snd_hda_codec_read(codec, 0x10, 0,
4116 AC_VERB_GET_PIN_SENSE, 0);
4117 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4118 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4121 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4123 if ((res >> 26) == ALC880_HP_EVENT)
4124 alc260_hp_automute(codec);
4127 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4129 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4130 .name = "Master Playback Switch",
4131 .info = snd_ctl_boolean_mono_info,
4132 .get = alc260_hp_master_sw_get,
4133 .put = alc260_hp_master_sw_put,
4134 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4136 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4137 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4138 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4139 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4140 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4141 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4142 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4143 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4147 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4148 .ops = &snd_hda_bind_vol,
4150 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4151 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4152 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4157 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4158 .ops = &snd_hda_bind_sw,
4160 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4161 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4166 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4167 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4168 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4169 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4170 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4174 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4175 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4179 static void alc260_hp_3013_automute(struct hda_codec *codec)
4181 struct alc_spec *spec = codec->spec;
4182 unsigned int present;
4184 present = snd_hda_codec_read(codec, 0x15, 0,
4185 AC_VERB_GET_PIN_SENSE, 0);
4186 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4187 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4190 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4193 if ((res >> 26) == ALC880_HP_EVENT)
4194 alc260_hp_3013_automute(codec);
4197 static void alc260_hp_3012_automute(struct hda_codec *codec)
4199 unsigned int present, bits;
4201 present = snd_hda_codec_read(codec, 0x10, 0,
4202 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4204 bits = present ? 0 : PIN_OUT;
4205 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4207 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4209 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4213 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4216 if ((res >> 26) == ALC880_HP_EVENT)
4217 alc260_hp_3012_automute(codec);
4220 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4221 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4223 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4224 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4225 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4226 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4227 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4228 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4229 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4230 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4231 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4232 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4233 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4234 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4235 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4239 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4240 * versions of the ALC260 don't act on requests to enable mic bias from NID
4241 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4242 * datasheet doesn't mention this restriction. At this stage it's not clear
4243 * whether this behaviour is intentional or is a hardware bug in chip
4244 * revisions available in early 2006. Therefore for now allow the
4245 * "Headphone Jack Mode" control to span all choices, but if it turns out
4246 * that the lack of mic bias for this NID is intentional we could change the
4247 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4249 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4250 * don't appear to make the mic bias available from the "line" jack, even
4251 * though the NID used for this jack (0x14) can supply it. The theory is
4252 * that perhaps Acer have included blocking capacitors between the ALC260
4253 * and the output jack. If this turns out to be the case for all such
4254 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4255 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4257 * The C20x Tablet series have a mono internal speaker which is controlled
4258 * via the chip's Mono sum widget and pin complex, so include the necessary
4259 * controls for such models. On models without a "mono speaker" the control
4260 * won't do anything.
4262 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4263 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4264 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4265 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4266 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4268 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4270 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4271 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4272 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4273 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4274 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4275 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4276 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4277 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4278 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4279 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4283 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4284 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4286 static struct snd_kcontrol_new alc260_will_mixer[] = {
4287 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4288 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4289 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4290 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4291 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4292 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4293 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4294 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4295 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4296 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4297 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4298 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4302 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4303 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4305 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4306 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4307 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4309 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4310 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4311 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4312 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4313 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4314 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4315 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4319 /* capture mixer elements */
4320 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4321 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4322 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4323 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4324 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4326 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4327 /* The multiple "Capture Source" controls confuse alsamixer
4328 * So call somewhat different..
4330 /* .name = "Capture Source", */
4331 .name = "Input Source",
4333 .info = alc_mux_enum_info,
4334 .get = alc_mux_enum_get,
4335 .put = alc_mux_enum_put,
4340 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4341 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4342 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4345 /* The multiple "Capture Source" controls confuse alsamixer
4346 * So call somewhat different..
4348 /* .name = "Capture Source", */
4349 .name = "Input Source",
4351 .info = alc_mux_enum_info,
4352 .get = alc_mux_enum_get,
4353 .put = alc_mux_enum_put,
4359 * initialization verbs
4361 static struct hda_verb alc260_init_verbs[] = {
4362 /* Line In pin widget for input */
4363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4364 /* CD pin widget for input */
4365 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4366 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4367 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4368 /* Mic2 (front panel) pin widget for input and vref at 80% */
4369 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4370 /* LINE-2 is used for line-out in rear */
4371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4372 /* select line-out */
4373 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4375 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4377 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4379 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4380 /* mute capture amp left and right */
4381 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4382 /* set connection select to line in (default select for this ADC) */
4383 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4384 /* mute capture amp left and right */
4385 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4386 /* set connection select to line in (default select for this ADC) */
4387 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4388 /* set vol=0 Line-Out mixer amp left and right */
4389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4390 /* unmute pin widget amp left and right (no gain on this amp) */
4391 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4392 /* set vol=0 HP mixer amp left and right */
4393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4394 /* unmute pin widget amp left and right (no gain on this amp) */
4395 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4396 /* set vol=0 Mono mixer amp left and right */
4397 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4398 /* unmute pin widget amp left and right (no gain on this amp) */
4399 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4400 /* unmute LINE-2 out pin */
4401 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4402 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4405 /* mute analog inputs */
4406 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4408 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4411 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4412 /* mute Front out path */
4413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4415 /* mute Headphone out path */
4416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4417 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4418 /* mute Mono out path */
4419 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4420 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4424 #if 0 /* should be identical with alc260_init_verbs? */
4425 static struct hda_verb alc260_hp_init_verbs[] = {
4426 /* Headphone and output */
4427 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4429 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4430 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4431 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4432 /* Mic2 (front panel) pin widget for input and vref at 80% */
4433 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4434 /* Line In pin widget for input */
4435 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4436 /* Line-2 pin widget for output */
4437 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4438 /* CD pin widget for input */
4439 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4440 /* unmute amp left and right */
4441 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4442 /* set connection select to line in (default select for this ADC) */
4443 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4444 /* unmute Line-Out mixer amp left and right (volume = 0) */
4445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4446 /* mute pin widget amp left and right (no gain on this amp) */
4447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4448 /* unmute HP mixer amp left and right (volume = 0) */
4449 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4450 /* mute pin widget amp left and right (no gain on this amp) */
4451 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4452 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4455 /* mute analog inputs */
4456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4458 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4459 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4460 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4461 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4462 /* Unmute Front out path */
4463 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4465 /* Unmute Headphone out path */
4466 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4468 /* Unmute Mono out path */
4469 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4470 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4475 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4476 /* Line out and output */
4477 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4479 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4480 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4481 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4482 /* Mic2 (front panel) pin widget for input and vref at 80% */
4483 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4484 /* Line In pin widget for input */
4485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4486 /* Headphone pin widget for output */
4487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4488 /* CD pin widget for input */
4489 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4490 /* unmute amp left and right */
4491 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4492 /* set connection select to line in (default select for this ADC) */
4493 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4494 /* unmute Line-Out mixer amp left and right (volume = 0) */
4495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4496 /* mute pin widget amp left and right (no gain on this amp) */
4497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4498 /* unmute HP mixer amp left and right (volume = 0) */
4499 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4500 /* mute pin widget amp left and right (no gain on this amp) */
4501 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4502 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4505 /* mute analog inputs */
4506 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4510 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4511 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4512 /* Unmute Front out path */
4513 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4514 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4515 /* Unmute Headphone out path */
4516 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4517 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4518 /* Unmute Mono out path */
4519 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4520 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4524 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4525 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4526 * audio = 0x16, internal speaker = 0x10.
4528 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4529 /* Disable all GPIOs */
4530 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4531 /* Internal speaker is connected to headphone pin */
4532 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4533 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4535 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4536 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4537 /* Ensure all other unused pins are disabled and muted. */
4538 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4540 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4541 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4542 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4543 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4547 /* Disable digital (SPDIF) pins */
4548 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4549 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4551 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4552 * when acting as an output.
4554 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4556 /* Start with output sum widgets muted and their output gains at min */
4557 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4559 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4560 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4561 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4562 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4563 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4564 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4565 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4567 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4568 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4569 /* Unmute Line1 pin widget output buffer since it starts as an output.
4570 * If the pin mode is changed by the user the pin mode control will
4571 * take care of enabling the pin's input/output buffers as needed.
4572 * Therefore there's no need to enable the input buffer at this
4575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4576 /* Unmute input buffer of pin widget used for Line-in (no equiv
4579 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4581 /* Mute capture amp left and right */
4582 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4583 /* Set ADC connection select to match default mixer setting - line
4586 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4588 /* Do the same for the second ADC: mute capture input amp and
4589 * set ADC connection to line in (on mic1 pin)
4591 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4592 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4594 /* Mute all inputs to mixer widget (even unconnected ones) */
4595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4596 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4597 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4607 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4608 * similar laptops (adapted from Fujitsu init verbs).
4610 static struct hda_verb alc260_acer_init_verbs[] = {
4611 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4612 * the headphone jack. Turn this on and rely on the standard mute
4613 * methods whenever the user wants to turn these outputs off.
4615 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4616 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4617 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4618 /* Internal speaker/Headphone jack is connected to Line-out pin */
4619 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4620 /* Internal microphone/Mic jack is connected to Mic1 pin */
4621 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4622 /* Line In jack is connected to Line1 pin */
4623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4624 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4625 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4626 /* Ensure all other unused pins are disabled and muted. */
4627 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4628 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4629 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4630 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4631 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4633 /* Disable digital (SPDIF) pins */
4634 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4635 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4637 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4638 * bus when acting as outputs.
4640 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4641 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4643 /* Start with output sum widgets muted and their output gains at min */
4644 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4645 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4646 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4647 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4648 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4649 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4650 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4651 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4652 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4654 /* Unmute Line-out pin widget amp left and right
4655 * (no equiv mixer ctrl)
4657 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4658 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4659 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4660 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4661 * inputs. If the pin mode is changed by the user the pin mode control
4662 * will take care of enabling the pin's input/output buffers as needed.
4663 * Therefore there's no need to enable the input buffer at this
4666 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4667 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4669 /* Mute capture amp left and right */
4670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4671 /* Set ADC connection select to match default mixer setting - mic
4674 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4676 /* Do similar with the second ADC: mute capture input amp and
4677 * set ADC connection to mic to match ALSA's default state.
4679 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4680 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4682 /* Mute all inputs to mixer widget (even unconnected ones) */
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4686 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4687 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4695 static struct hda_verb alc260_will_verbs[] = {
4696 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4697 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4698 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4699 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4700 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4701 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4705 static struct hda_verb alc260_replacer_672v_verbs[] = {
4706 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4707 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4708 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4710 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4711 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4712 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4714 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4718 /* toggle speaker-output according to the hp-jack state */
4719 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4721 unsigned int present;
4723 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4724 present = snd_hda_codec_read(codec, 0x0f, 0,
4725 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4727 snd_hda_codec_write_cache(codec, 0x01, 0,
4728 AC_VERB_SET_GPIO_DATA, 1);
4729 snd_hda_codec_write_cache(codec, 0x0f, 0,
4730 AC_VERB_SET_PIN_WIDGET_CONTROL,
4733 snd_hda_codec_write_cache(codec, 0x01, 0,
4734 AC_VERB_SET_GPIO_DATA, 0);
4735 snd_hda_codec_write_cache(codec, 0x0f, 0,
4736 AC_VERB_SET_PIN_WIDGET_CONTROL,
4741 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4744 if ((res >> 26) == ALC880_HP_EVENT)
4745 alc260_replacer_672v_automute(codec);
4748 static struct hda_verb alc260_hp_dc7600_verbs[] = {
4749 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4750 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4751 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4752 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4753 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4754 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4755 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4756 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4757 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4758 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4762 /* Test configuration for debugging, modelled after the ALC880 test
4765 #ifdef CONFIG_SND_DEBUG
4766 static hda_nid_t alc260_test_dac_nids[1] = {
4769 static hda_nid_t alc260_test_adc_nids[2] = {
4772 /* For testing the ALC260, each input MUX needs its own definition since
4773 * the signal assignments are different. This assumes that the first ADC
4776 static struct hda_input_mux alc260_test_capture_sources[2] = {
4780 { "MIC1 pin", 0x0 },
4781 { "MIC2 pin", 0x1 },
4782 { "LINE1 pin", 0x2 },
4783 { "LINE2 pin", 0x3 },
4785 { "LINE-OUT pin", 0x5 },
4786 { "HP-OUT pin", 0x6 },
4792 { "MIC1 pin", 0x0 },
4793 { "MIC2 pin", 0x1 },
4794 { "LINE1 pin", 0x2 },
4795 { "LINE2 pin", 0x3 },
4798 { "LINE-OUT pin", 0x6 },
4799 { "HP-OUT pin", 0x7 },
4803 static struct snd_kcontrol_new alc260_test_mixer[] = {
4804 /* Output driver widgets */
4805 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4806 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4807 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4808 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4809 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4810 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4812 /* Modes for retasking pin widgets
4813 * Note: the ALC260 doesn't seem to act on requests to enable mic
4814 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4815 * mention this restriction. At this stage it's not clear whether
4816 * this behaviour is intentional or is a hardware bug in chip
4817 * revisions available at least up until early 2006. Therefore for
4818 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4819 * choices, but if it turns out that the lack of mic bias for these
4820 * NIDs is intentional we could change their modes from
4821 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4823 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4824 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4825 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4826 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4827 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4828 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4830 /* Loopback mixer controls */
4831 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4832 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4833 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4834 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4835 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4836 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4837 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4838 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4839 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4840 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4841 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4842 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4843 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4844 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4845 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4846 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4848 /* Controls for GPIO pins, assuming they are configured as outputs */
4849 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4850 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4851 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4852 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4854 /* Switches to allow the digital IO pins to be enabled. The datasheet
4855 * is ambigious as to which NID is which; testing on laptops which
4856 * make this output available should provide clarification.
4858 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4859 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4861 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4862 * this output to turn on an external amplifier.
4864 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4865 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4869 static struct hda_verb alc260_test_init_verbs[] = {
4870 /* Enable all GPIOs as outputs with an initial value of 0 */
4871 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4872 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4873 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4875 /* Enable retasking pins as output, initially without power amp */
4876 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4877 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4878 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4879 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4880 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4881 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4883 /* Disable digital (SPDIF) pins initially, but users can enable
4884 * them via a mixer switch. In the case of SPDIF-out, this initverb
4885 * payload also sets the generation to 0, output to be in "consumer"
4886 * PCM format, copyright asserted, no pre-emphasis and no validity
4889 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4890 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4892 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4893 * OUT1 sum bus when acting as an output.
4895 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4896 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4897 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4898 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4900 /* Start with output sum widgets muted and their output gains at min */
4901 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4902 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4903 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4905 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4906 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4908 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4909 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4911 /* Unmute retasking pin widget output buffers since the default
4912 * state appears to be output. As the pin mode is changed by the
4913 * user the pin mode control will take care of enabling the pin's
4914 * input/output buffers as needed.
4916 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4917 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4918 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4919 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4920 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4921 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4922 /* Also unmute the mono-out pin widget */
4923 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4925 /* Mute capture amp left and right */
4926 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4927 /* Set ADC connection select to match default mixer setting (mic1
4930 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4932 /* Do the same for the second ADC: mute capture input amp and
4933 * set ADC connection to mic1 pin
4935 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4936 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4938 /* Mute all inputs to mixer widget (even unconnected ones) */
4939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4942 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4943 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4944 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4945 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4952 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4953 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
4955 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4956 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4959 * for BIOS auto-configuration
4962 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4966 unsigned long vol_val, sw_val;
4970 if (nid >= 0x0f && nid < 0x11) {
4971 nid_vol = nid - 0x7;
4972 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4973 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4974 } else if (nid == 0x11) {
4975 nid_vol = nid - 0x7;
4976 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4977 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4978 } else if (nid >= 0x12 && nid <= 0x15) {
4980 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4981 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4985 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4986 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4989 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4990 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4996 /* add playback controls from the parsed DAC table */
4997 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4998 const struct auto_pin_cfg *cfg)
5003 spec->multiout.num_dacs = 1;
5004 spec->multiout.dac_nids = spec->private_dac_nids;
5005 spec->multiout.dac_nids[0] = 0x02;
5007 nid = cfg->line_out_pins[0];
5009 err = alc260_add_playback_controls(spec, nid, "Front");
5014 nid = cfg->speaker_pins[0];
5016 err = alc260_add_playback_controls(spec, nid, "Speaker");
5021 nid = cfg->hp_pins[0];
5023 err = alc260_add_playback_controls(spec, nid, "Headphone");
5030 /* create playback/capture controls for input pins */
5031 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5032 const struct auto_pin_cfg *cfg)
5034 struct hda_input_mux *imux = &spec->private_imux;
5037 for (i = 0; i < AUTO_PIN_LAST; i++) {
5038 if (cfg->input_pins[i] >= 0x12) {
5039 idx = cfg->input_pins[i] - 0x12;
5040 err = new_analog_input(spec, cfg->input_pins[i],
5041 auto_pin_cfg_labels[i], idx,
5045 imux->items[imux->num_items].label =
5046 auto_pin_cfg_labels[i];
5047 imux->items[imux->num_items].index = idx;
5050 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5051 idx = cfg->input_pins[i] - 0x09;
5052 err = new_analog_input(spec, cfg->input_pins[i],
5053 auto_pin_cfg_labels[i], idx,
5057 imux->items[imux->num_items].label =
5058 auto_pin_cfg_labels[i];
5059 imux->items[imux->num_items].index = idx;
5066 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5067 hda_nid_t nid, int pin_type,
5070 alc_set_pin_output(codec, nid, pin_type);
5071 /* need the manual connection? */
5073 int idx = nid - 0x12;
5074 snd_hda_codec_write(codec, idx + 0x0b, 0,
5075 AC_VERB_SET_CONNECT_SEL, sel_idx);
5079 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5081 struct alc_spec *spec = codec->spec;
5084 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5085 nid = spec->autocfg.line_out_pins[0];
5087 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5088 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5091 nid = spec->autocfg.speaker_pins[0];
5093 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5095 nid = spec->autocfg.hp_pins[0];
5097 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5100 #define ALC260_PIN_CD_NID 0x16
5101 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5103 struct alc_spec *spec = codec->spec;
5106 for (i = 0; i < AUTO_PIN_LAST; i++) {
5107 hda_nid_t nid = spec->autocfg.input_pins[i];
5109 snd_hda_codec_write(codec, nid, 0,
5110 AC_VERB_SET_PIN_WIDGET_CONTROL,
5111 i <= AUTO_PIN_FRONT_MIC ?
5112 PIN_VREF80 : PIN_IN);
5113 if (nid != ALC260_PIN_CD_NID)
5114 snd_hda_codec_write(codec, nid, 0,
5115 AC_VERB_SET_AMP_GAIN_MUTE,
5122 * generic initialization of ADC, input mixers and output mixers
5124 static struct hda_verb alc260_volume_init_verbs[] = {
5126 * Unmute ADC0-1 and set the default input to mic-in
5128 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5129 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5130 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5131 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5133 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5135 * Note: PASD motherboards uses the Line In 2 as the input for
5136 * front panel mic (mic 2)
5138 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5139 /* mute analog inputs */
5140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5147 * Set up output mixers (0x08 - 0x0a)
5149 /* set vol=0 to output mixers */
5150 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5152 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5153 /* set up input amps for analog loopback */
5154 /* Amp Indices: DAC = 0, mixer = 1 */
5155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5159 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5160 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5165 static int alc260_parse_auto_config(struct hda_codec *codec)
5167 struct alc_spec *spec = codec->spec;
5170 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5172 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5176 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5179 if (!spec->kctl_alloc)
5180 return 0; /* can't find valid BIOS pin config */
5181 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5185 spec->multiout.max_channels = 2;
5187 if (spec->autocfg.dig_out_pin)
5188 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5189 if (spec->kctl_alloc)
5190 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5192 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5194 spec->num_mux_defs = 1;
5195 spec->input_mux = &spec->private_imux;
5197 /* check whether NID 0x04 is valid */
5198 wcap = get_wcaps(codec, 0x04);
5199 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5200 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5201 spec->adc_nids = alc260_adc_nids_alt;
5202 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5203 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5205 spec->adc_nids = alc260_adc_nids;
5206 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5207 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5214 /* additional initialization for auto-configuration model */
5215 static void alc260_auto_init(struct hda_codec *codec)
5217 struct alc_spec *spec = codec->spec;
5218 alc260_auto_init_multi_out(codec);
5219 alc260_auto_init_analog_input(codec);
5220 if (spec->unsol_event)
5221 alc_sku_automute(codec);
5224 #ifdef CONFIG_SND_HDA_POWER_SAVE
5225 static struct hda_amp_list alc260_loopbacks[] = {
5226 { 0x07, HDA_INPUT, 0 },
5227 { 0x07, HDA_INPUT, 1 },
5228 { 0x07, HDA_INPUT, 2 },
5229 { 0x07, HDA_INPUT, 3 },
5230 { 0x07, HDA_INPUT, 4 },
5236 * ALC260 configurations
5238 static const char *alc260_models[ALC260_MODEL_LAST] = {
5239 [ALC260_BASIC] = "basic",
5241 [ALC260_HP_3013] = "hp-3013",
5242 [ALC260_FUJITSU_S702X] = "fujitsu",
5243 [ALC260_ACER] = "acer",
5244 [ALC260_WILL] = "will",
5245 [ALC260_REPLACER_672V] = "replacer",
5246 #ifdef CONFIG_SND_DEBUG
5247 [ALC260_TEST] = "test",
5249 [ALC260_AUTO] = "auto",
5252 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5253 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5254 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5255 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5256 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5257 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5258 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5259 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5260 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5261 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5262 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5263 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5264 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5265 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5266 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5267 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5268 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5269 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5270 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5274 static struct alc_config_preset alc260_presets[] = {
5276 .mixers = { alc260_base_output_mixer,
5278 alc260_pc_beep_mixer,
5279 alc260_capture_mixer },
5280 .init_verbs = { alc260_init_verbs },
5281 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5282 .dac_nids = alc260_dac_nids,
5283 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5284 .adc_nids = alc260_adc_nids,
5285 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5286 .channel_mode = alc260_modes,
5287 .input_mux = &alc260_capture_source,
5290 .mixers = { alc260_hp_output_mixer,
5292 alc260_capture_alt_mixer },
5293 .init_verbs = { alc260_init_verbs,
5294 alc260_hp_unsol_verbs },
5295 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5296 .dac_nids = alc260_dac_nids,
5297 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5298 .adc_nids = alc260_hp_adc_nids,
5299 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5300 .channel_mode = alc260_modes,
5301 .input_mux = &alc260_capture_source,
5302 .unsol_event = alc260_hp_unsol_event,
5303 .init_hook = alc260_hp_automute,
5305 [ALC260_HP_DC7600] = {
5306 .mixers = { alc260_hp_dc7600_mixer,
5308 alc260_capture_alt_mixer },
5309 .init_verbs = { alc260_init_verbs,
5310 alc260_hp_dc7600_verbs },
5311 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5312 .dac_nids = alc260_dac_nids,
5313 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5314 .adc_nids = alc260_hp_adc_nids,
5315 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5316 .channel_mode = alc260_modes,
5317 .input_mux = &alc260_capture_source,
5318 .unsol_event = alc260_hp_3012_unsol_event,
5319 .init_hook = alc260_hp_3012_automute,
5321 [ALC260_HP_3013] = {
5322 .mixers = { alc260_hp_3013_mixer,
5324 alc260_capture_alt_mixer },
5325 .init_verbs = { alc260_hp_3013_init_verbs,
5326 alc260_hp_3013_unsol_verbs },
5327 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5328 .dac_nids = alc260_dac_nids,
5329 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5330 .adc_nids = alc260_hp_adc_nids,
5331 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5332 .channel_mode = alc260_modes,
5333 .input_mux = &alc260_capture_source,
5334 .unsol_event = alc260_hp_3013_unsol_event,
5335 .init_hook = alc260_hp_3013_automute,
5337 [ALC260_FUJITSU_S702X] = {
5338 .mixers = { alc260_fujitsu_mixer,
5339 alc260_capture_mixer },
5340 .init_verbs = { alc260_fujitsu_init_verbs },
5341 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5342 .dac_nids = alc260_dac_nids,
5343 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5344 .adc_nids = alc260_dual_adc_nids,
5345 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5346 .channel_mode = alc260_modes,
5347 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5348 .input_mux = alc260_fujitsu_capture_sources,
5351 .mixers = { alc260_acer_mixer,
5352 alc260_capture_mixer },
5353 .init_verbs = { alc260_acer_init_verbs },
5354 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5355 .dac_nids = alc260_dac_nids,
5356 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5357 .adc_nids = alc260_dual_adc_nids,
5358 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5359 .channel_mode = alc260_modes,
5360 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5361 .input_mux = alc260_acer_capture_sources,
5364 .mixers = { alc260_will_mixer,
5365 alc260_capture_mixer },
5366 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5367 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5368 .dac_nids = alc260_dac_nids,
5369 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5370 .adc_nids = alc260_adc_nids,
5371 .dig_out_nid = ALC260_DIGOUT_NID,
5372 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5373 .channel_mode = alc260_modes,
5374 .input_mux = &alc260_capture_source,
5376 [ALC260_REPLACER_672V] = {
5377 .mixers = { alc260_replacer_672v_mixer,
5378 alc260_capture_mixer },
5379 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5380 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5381 .dac_nids = alc260_dac_nids,
5382 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5383 .adc_nids = alc260_adc_nids,
5384 .dig_out_nid = ALC260_DIGOUT_NID,
5385 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5386 .channel_mode = alc260_modes,
5387 .input_mux = &alc260_capture_source,
5388 .unsol_event = alc260_replacer_672v_unsol_event,
5389 .init_hook = alc260_replacer_672v_automute,
5391 #ifdef CONFIG_SND_DEBUG
5393 .mixers = { alc260_test_mixer,
5394 alc260_capture_mixer },
5395 .init_verbs = { alc260_test_init_verbs },
5396 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5397 .dac_nids = alc260_test_dac_nids,
5398 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5399 .adc_nids = alc260_test_adc_nids,
5400 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5401 .channel_mode = alc260_modes,
5402 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5403 .input_mux = alc260_test_capture_sources,
5408 static int patch_alc260(struct hda_codec *codec)
5410 struct alc_spec *spec;
5411 int err, board_config;
5413 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5419 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5422 if (board_config < 0) {
5423 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5424 "trying auto-probe from BIOS...\n");
5425 board_config = ALC260_AUTO;
5428 if (board_config == ALC260_AUTO) {
5429 /* automatic parse from the BIOS config */
5430 err = alc260_parse_auto_config(codec);
5436 "hda_codec: Cannot set up configuration "
5437 "from BIOS. Using base mode...\n");
5438 board_config = ALC260_BASIC;
5442 if (board_config != ALC260_AUTO)
5443 setup_preset(spec, &alc260_presets[board_config]);
5445 spec->stream_name_analog = "ALC260 Analog";
5446 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5447 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5449 spec->stream_name_digital = "ALC260 Digital";
5450 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5451 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5453 spec->vmaster_nid = 0x08;
5455 codec->patch_ops = alc_patch_ops;
5456 if (board_config == ALC260_AUTO)
5457 spec->init_hook = alc260_auto_init;
5458 #ifdef CONFIG_SND_HDA_POWER_SAVE
5459 if (!spec->loopback.amplist)
5460 spec->loopback.amplist = alc260_loopbacks;
5470 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5471 * configuration. Each pin widget can choose any input DACs and a mixer.
5472 * Each ADC is connected from a mixer of all inputs. This makes possible
5473 * 6-channel independent captures.
5475 * In addition, an independent DAC for the multi-playback (not used in this
5478 #define ALC882_DIGOUT_NID 0x06
5479 #define ALC882_DIGIN_NID 0x0a
5481 static struct hda_channel_mode alc882_ch_modes[1] = {
5485 static hda_nid_t alc882_dac_nids[4] = {
5486 /* front, rear, clfe, rear_surr */
5487 0x02, 0x03, 0x04, 0x05
5490 /* identical with ALC880 */
5491 #define alc882_adc_nids alc880_adc_nids
5492 #define alc882_adc_nids_alt alc880_adc_nids_alt
5494 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5495 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5498 /* FIXME: should be a matrix-type input source selection */
5500 static struct hda_input_mux alc882_capture_source = {
5504 { "Front Mic", 0x1 },
5509 #define alc882_mux_enum_info alc_mux_enum_info
5510 #define alc882_mux_enum_get alc_mux_enum_get
5512 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5513 struct snd_ctl_elem_value *ucontrol)
5515 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5516 struct alc_spec *spec = codec->spec;
5517 const struct hda_input_mux *imux = spec->input_mux;
5518 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5519 hda_nid_t nid = spec->capsrc_nids ?
5520 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5521 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5522 unsigned int i, idx;
5524 idx = ucontrol->value.enumerated.item[0];
5525 if (idx >= imux->num_items)
5526 idx = imux->num_items - 1;
5527 if (*cur_val == idx)
5529 for (i = 0; i < imux->num_items; i++) {
5530 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5531 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5532 imux->items[i].index,
5542 static struct hda_verb alc882_3ST_ch2_init[] = {
5543 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5544 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5545 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5546 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5553 static struct hda_verb alc882_3ST_ch6_init[] = {
5554 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5555 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5556 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5557 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5558 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5559 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5563 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5564 { 2, alc882_3ST_ch2_init },
5565 { 6, alc882_3ST_ch6_init },
5571 static struct hda_verb alc882_sixstack_ch6_init[] = {
5572 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5573 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5574 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5575 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5582 static struct hda_verb alc882_sixstack_ch8_init[] = {
5583 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5584 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5585 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5586 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5590 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5591 { 6, alc882_sixstack_ch6_init },
5592 { 8, alc882_sixstack_ch8_init },
5596 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5602 static struct hda_verb alc885_mbp_ch2_init[] = {
5603 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5604 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5605 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5612 static struct hda_verb alc885_mbp_ch6_init[] = {
5613 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5614 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5615 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5616 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5617 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5621 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5622 { 2, alc885_mbp_ch2_init },
5623 { 6, alc885_mbp_ch6_init },
5627 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5628 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5630 static struct snd_kcontrol_new alc882_base_mixer[] = {
5631 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5632 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5633 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5634 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5635 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5636 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5637 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5638 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5639 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5640 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5642 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5643 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5647 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5649 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5650 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5652 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5653 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5657 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5658 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5659 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5660 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5661 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5662 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5663 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5665 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5666 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5670 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5671 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5672 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5678 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5680 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5681 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5685 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5686 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5687 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5689 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5690 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5691 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5692 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5695 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5696 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5698 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5702 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5703 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5705 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5706 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5707 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5708 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5709 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5710 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5711 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5712 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5713 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5714 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5715 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5718 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5722 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5723 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5724 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5725 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5726 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5727 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5728 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5729 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5731 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5733 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5734 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5738 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5741 .name = "Channel Mode",
5742 .info = alc_ch_mode_info,
5743 .get = alc_ch_mode_get,
5744 .put = alc_ch_mode_put,
5749 static struct hda_verb alc882_init_verbs[] = {
5750 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5757 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5760 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5761 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5763 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5765 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5767 /* Front Pin: output 0 (0x0c) */
5768 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5770 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5771 /* Rear Pin: output 1 (0x0d) */
5772 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5773 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5774 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5775 /* CLFE Pin: output 2 (0x0e) */
5776 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5777 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5778 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5779 /* Side Pin: output 3 (0x0f) */
5780 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5781 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5782 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5783 /* Mic (rear) pin: input vref at 80% */
5784 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5785 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5786 /* Front Mic pin: input vref at 80% */
5787 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5788 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5789 /* Line In pin: input */
5790 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5791 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5792 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5793 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5794 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5795 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5796 /* CD pin widget for input */
5797 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5799 /* FIXME: use matrix-type input source selection */
5800 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5801 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5802 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5803 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5804 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5807 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5808 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5809 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5810 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5812 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5813 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5814 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5816 /* ADC1: mute amp left and right */
5817 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5818 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5819 /* ADC2: mute amp left and right */
5820 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5821 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5822 /* ADC3: mute amp left and right */
5823 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5824 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5829 static struct hda_verb alc882_eapd_verbs[] = {
5830 /* change to EAPD mode */
5831 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5832 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5837 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5838 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5839 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5841 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5842 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5843 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5844 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5848 static struct hda_verb alc882_macpro_init_verbs[] = {
5849 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5852 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5853 /* Front Pin: output 0 (0x0c) */
5854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5857 /* Front Mic pin: input vref at 80% */
5858 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5860 /* Speaker: output */
5861 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5863 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5864 /* Headphone output (output 0 - 0x0c) */
5865 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5866 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5867 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5869 /* FIXME: use matrix-type input source selection */
5870 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5871 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5872 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5873 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5874 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5875 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5877 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5878 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5879 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5880 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5882 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5883 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5884 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5885 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5886 /* ADC1: mute amp left and right */
5887 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5888 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5889 /* ADC2: mute amp left and right */
5890 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5891 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5892 /* ADC3: mute amp left and right */
5893 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5894 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5899 /* Macbook Pro rev3 */
5900 static struct hda_verb alc885_mbp3_init_verbs[] = {
5901 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5906 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5909 /* Front Pin: output 0 (0x0c) */
5910 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5911 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5912 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5913 /* HP Pin: output 0 (0x0d) */
5914 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5915 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5916 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5917 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5918 /* Mic (rear) pin: input vref at 80% */
5919 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5920 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5921 /* Front Mic pin: input vref at 80% */
5922 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5923 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5924 /* Line In pin: use output 1 when in LineOut mode */
5925 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5926 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5927 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5929 /* FIXME: use matrix-type input source selection */
5930 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5931 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5932 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5933 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5934 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5935 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5937 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5938 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5939 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5940 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5943 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5944 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5945 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5946 /* ADC1: mute amp left and right */
5947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5948 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5949 /* ADC2: mute amp left and right */
5950 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5951 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5952 /* ADC3: mute amp left and right */
5953 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5954 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5959 /* iMac 24 mixer. */
5960 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5961 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5962 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5966 /* iMac 24 init verbs. */
5967 static struct hda_verb alc885_imac24_init_verbs[] = {
5968 /* Internal speakers: output 0 (0x0c) */
5969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5970 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5971 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5972 /* Internal speakers: output 0 (0x0c) */
5973 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5974 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5975 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5976 /* Headphone: output 0 (0x0c) */
5977 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5978 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5979 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5980 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5981 /* Front Mic: input vref at 80% */
5982 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5983 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5987 /* Toggle speaker-output according to the hp-jack state */
5988 static void alc885_imac24_automute(struct hda_codec *codec)
5990 unsigned int present;
5992 present = snd_hda_codec_read(codec, 0x14, 0,
5993 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5994 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5995 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5996 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5997 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6000 /* Processes unsolicited events. */
6001 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6004 /* Headphone insertion or removal. */
6005 if ((res >> 26) == ALC880_HP_EVENT)
6006 alc885_imac24_automute(codec);
6009 static void alc885_mbp3_automute(struct hda_codec *codec)
6011 unsigned int present;
6013 present = snd_hda_codec_read(codec, 0x15, 0,
6014 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6015 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6016 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6017 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6018 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6021 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6024 /* Headphone insertion or removal. */
6025 if ((res >> 26) == ALC880_HP_EVENT)
6026 alc885_mbp3_automute(codec);
6030 static struct hda_verb alc882_targa_verbs[] = {
6031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6034 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6035 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6037 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6038 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6039 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6042 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6043 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6044 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6048 /* toggle speaker-output according to the hp-jack state */
6049 static void alc882_targa_automute(struct hda_codec *codec)
6051 unsigned int present;
6053 present = snd_hda_codec_read(codec, 0x14, 0,
6054 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6055 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6056 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6057 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6061 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6063 /* Looks like the unsol event is incompatible with the standard
6064 * definition. 4bit tag is placed at 26 bit!
6066 if (((res >> 26) == ALC880_HP_EVENT)) {
6067 alc882_targa_automute(codec);
6071 static struct hda_verb alc882_asus_a7j_verbs[] = {
6072 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6076 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6077 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6079 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6080 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6081 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6083 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6084 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6085 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6089 static struct hda_verb alc882_asus_a7m_verbs[] = {
6090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6093 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6094 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6095 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6097 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6098 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6099 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6101 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6102 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6103 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6107 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6109 unsigned int gpiostate, gpiomask, gpiodir;
6111 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6112 AC_VERB_GET_GPIO_DATA, 0);
6115 gpiostate |= (1 << pin);
6117 gpiostate &= ~(1 << pin);
6119 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6120 AC_VERB_GET_GPIO_MASK, 0);
6121 gpiomask |= (1 << pin);
6123 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6124 AC_VERB_GET_GPIO_DIRECTION, 0);
6125 gpiodir |= (1 << pin);
6128 snd_hda_codec_write(codec, codec->afg, 0,
6129 AC_VERB_SET_GPIO_MASK, gpiomask);
6130 snd_hda_codec_write(codec, codec->afg, 0,
6131 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6135 snd_hda_codec_write(codec, codec->afg, 0,
6136 AC_VERB_SET_GPIO_DATA, gpiostate);
6139 /* set up GPIO at initialization */
6140 static void alc885_macpro_init_hook(struct hda_codec *codec)
6142 alc882_gpio_mute(codec, 0, 0);
6143 alc882_gpio_mute(codec, 1, 0);
6146 /* set up GPIO and update auto-muting at initialization */
6147 static void alc885_imac24_init_hook(struct hda_codec *codec)
6149 alc885_macpro_init_hook(codec);
6150 alc885_imac24_automute(codec);
6154 * generic initialization of ADC, input mixers and output mixers
6156 static struct hda_verb alc882_auto_init_verbs[] = {
6158 * Unmute ADC0-2 and set the default input to mic-in
6160 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6162 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6163 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6164 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6165 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6167 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6169 * Note: PASD motherboards uses the Line In 2 as the input for
6170 * front panel mic (mic 2)
6172 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6174 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6175 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6176 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6177 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6180 * Set up output mixers (0x0c - 0x0f)
6182 /* set vol=0 to output mixers */
6183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6185 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6186 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6187 /* set up input amps for analog loopback */
6188 /* Amp Indices: DAC = 0, mixer = 1 */
6189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6190 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6191 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6192 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6193 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6194 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6195 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6196 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6197 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6198 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6200 /* FIXME: use matrix-type input source selection */
6201 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6202 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6203 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6213 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6221 /* capture mixer elements */
6222 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6223 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6224 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6225 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6226 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6228 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6229 /* The multiple "Capture Source" controls confuse alsamixer
6230 * So call somewhat different..
6232 /* .name = "Capture Source", */
6233 .name = "Input Source",
6235 .info = alc882_mux_enum_info,
6236 .get = alc882_mux_enum_get,
6237 .put = alc882_mux_enum_put,
6242 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6243 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6244 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6245 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6246 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6247 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6248 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6250 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6251 /* The multiple "Capture Source" controls confuse alsamixer
6252 * So call somewhat different..
6254 /* .name = "Capture Source", */
6255 .name = "Input Source",
6257 .info = alc882_mux_enum_info,
6258 .get = alc882_mux_enum_get,
6259 .put = alc882_mux_enum_put,
6264 #ifdef CONFIG_SND_HDA_POWER_SAVE
6265 #define alc882_loopbacks alc880_loopbacks
6268 /* pcm configuration: identiacal with ALC880 */
6269 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6270 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6271 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6272 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6275 * configuration and preset
6277 static const char *alc882_models[ALC882_MODEL_LAST] = {
6278 [ALC882_3ST_DIG] = "3stack-dig",
6279 [ALC882_6ST_DIG] = "6stack-dig",
6280 [ALC882_ARIMA] = "arima",
6281 [ALC882_W2JC] = "w2jc",
6282 [ALC882_TARGA] = "targa",
6283 [ALC882_ASUS_A7J] = "asus-a7j",
6284 [ALC882_ASUS_A7M] = "asus-a7m",
6285 [ALC885_MACPRO] = "macpro",
6286 [ALC885_MBP3] = "mbp3",
6287 [ALC885_IMAC24] = "imac24",
6288 [ALC882_AUTO] = "auto",
6291 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6292 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6293 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6294 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6295 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6296 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6297 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6298 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6299 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6300 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6301 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6302 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6303 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6307 static struct alc_config_preset alc882_presets[] = {
6308 [ALC882_3ST_DIG] = {
6309 .mixers = { alc882_base_mixer },
6310 .init_verbs = { alc882_init_verbs },
6311 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6312 .dac_nids = alc882_dac_nids,
6313 .dig_out_nid = ALC882_DIGOUT_NID,
6314 .dig_in_nid = ALC882_DIGIN_NID,
6315 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6316 .channel_mode = alc882_ch_modes,
6318 .input_mux = &alc882_capture_source,
6320 [ALC882_6ST_DIG] = {
6321 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6322 .init_verbs = { alc882_init_verbs },
6323 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6324 .dac_nids = alc882_dac_nids,
6325 .dig_out_nid = ALC882_DIGOUT_NID,
6326 .dig_in_nid = ALC882_DIGIN_NID,
6327 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6328 .channel_mode = alc882_sixstack_modes,
6329 .input_mux = &alc882_capture_source,
6332 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6333 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6334 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6335 .dac_nids = alc882_dac_nids,
6336 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6337 .channel_mode = alc882_sixstack_modes,
6338 .input_mux = &alc882_capture_source,
6341 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6342 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6343 alc880_gpio1_init_verbs },
6344 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6345 .dac_nids = alc882_dac_nids,
6346 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6347 .channel_mode = alc880_threestack_modes,
6349 .input_mux = &alc882_capture_source,
6350 .dig_out_nid = ALC882_DIGOUT_NID,
6353 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6354 .init_verbs = { alc885_mbp3_init_verbs,
6355 alc880_gpio1_init_verbs },
6356 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6357 .dac_nids = alc882_dac_nids,
6358 .channel_mode = alc885_mbp_6ch_modes,
6359 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6360 .input_mux = &alc882_capture_source,
6361 .dig_out_nid = ALC882_DIGOUT_NID,
6362 .dig_in_nid = ALC882_DIGIN_NID,
6363 .unsol_event = alc885_mbp3_unsol_event,
6364 .init_hook = alc885_mbp3_automute,
6367 .mixers = { alc882_macpro_mixer },
6368 .init_verbs = { alc882_macpro_init_verbs },
6369 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6370 .dac_nids = alc882_dac_nids,
6371 .dig_out_nid = ALC882_DIGOUT_NID,
6372 .dig_in_nid = ALC882_DIGIN_NID,
6373 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6374 .channel_mode = alc882_ch_modes,
6375 .input_mux = &alc882_capture_source,
6376 .init_hook = alc885_macpro_init_hook,
6379 .mixers = { alc885_imac24_mixer },
6380 .init_verbs = { alc885_imac24_init_verbs },
6381 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6382 .dac_nids = alc882_dac_nids,
6383 .dig_out_nid = ALC882_DIGOUT_NID,
6384 .dig_in_nid = ALC882_DIGIN_NID,
6385 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6386 .channel_mode = alc882_ch_modes,
6387 .input_mux = &alc882_capture_source,
6388 .unsol_event = alc885_imac24_unsol_event,
6389 .init_hook = alc885_imac24_init_hook,
6392 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6393 alc882_capture_mixer },
6394 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6395 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6396 .dac_nids = alc882_dac_nids,
6397 .dig_out_nid = ALC882_DIGOUT_NID,
6398 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6399 .adc_nids = alc882_adc_nids,
6400 .capsrc_nids = alc882_capsrc_nids,
6401 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6402 .channel_mode = alc882_3ST_6ch_modes,
6404 .input_mux = &alc882_capture_source,
6405 .unsol_event = alc882_targa_unsol_event,
6406 .init_hook = alc882_targa_automute,
6408 [ALC882_ASUS_A7J] = {
6409 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6410 alc882_capture_mixer },
6411 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6412 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6413 .dac_nids = alc882_dac_nids,
6414 .dig_out_nid = ALC882_DIGOUT_NID,
6415 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6416 .adc_nids = alc882_adc_nids,
6417 .capsrc_nids = alc882_capsrc_nids,
6418 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6419 .channel_mode = alc882_3ST_6ch_modes,
6421 .input_mux = &alc882_capture_source,
6423 [ALC882_ASUS_A7M] = {
6424 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6425 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6426 alc880_gpio1_init_verbs,
6427 alc882_asus_a7m_verbs },
6428 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6429 .dac_nids = alc882_dac_nids,
6430 .dig_out_nid = ALC882_DIGOUT_NID,
6431 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6432 .channel_mode = alc880_threestack_modes,
6434 .input_mux = &alc882_capture_source,
6443 PINFIX_ABIT_AW9D_MAX
6446 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6447 { 0x15, 0x01080104 }, /* side */
6448 { 0x16, 0x01011012 }, /* rear */
6449 { 0x17, 0x01016011 }, /* clfe */
6453 static const struct alc_pincfg *alc882_pin_fixes[] = {
6454 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6457 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6458 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6463 * BIOS auto configuration
6465 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6466 hda_nid_t nid, int pin_type,
6470 struct alc_spec *spec = codec->spec;
6473 alc_set_pin_output(codec, nid, pin_type);
6474 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6477 idx = spec->multiout.dac_nids[dac_idx] - 2;
6478 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6482 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6484 struct alc_spec *spec = codec->spec;
6487 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6488 for (i = 0; i <= HDA_SIDE; i++) {
6489 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6490 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6492 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6497 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6499 struct alc_spec *spec = codec->spec;
6502 pin = spec->autocfg.hp_pins[0];
6503 if (pin) /* connect to front */
6505 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6506 pin = spec->autocfg.speaker_pins[0];
6508 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6511 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6512 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6514 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6516 struct alc_spec *spec = codec->spec;
6519 for (i = 0; i < AUTO_PIN_LAST; i++) {
6520 hda_nid_t nid = spec->autocfg.input_pins[i];
6525 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6526 unsigned int pincap;
6527 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6528 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6532 snd_hda_codec_write(codec, nid, 0,
6533 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6534 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6535 snd_hda_codec_write(codec, nid, 0,
6536 AC_VERB_SET_AMP_GAIN_MUTE,
6541 static void alc882_auto_init_input_src(struct hda_codec *codec)
6543 struct alc_spec *spec = codec->spec;
6544 const struct hda_input_mux *imux = spec->input_mux;
6547 for (c = 0; c < spec->num_adc_nids; c++) {
6548 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6549 hda_nid_t nid = spec->capsrc_nids[c];
6550 int conns, mute, idx, item;
6552 conns = snd_hda_get_connections(codec, nid, conn_list,
6553 ARRAY_SIZE(conn_list));
6556 for (idx = 0; idx < conns; idx++) {
6557 /* if the current connection is the selected one,
6558 * unmute it as default - otherwise mute it
6560 mute = AMP_IN_MUTE(idx);
6561 for (item = 0; item < imux->num_items; item++) {
6562 if (imux->items[item].index == idx) {
6563 if (spec->cur_mux[c] == item)
6564 mute = AMP_IN_UNMUTE(idx);
6568 snd_hda_codec_write(codec, nid, 0,
6569 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6574 /* add mic boosts if needed */
6575 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6577 struct alc_spec *spec = codec->spec;
6581 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6582 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6583 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6585 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6589 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6590 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6591 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6593 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6600 /* almost identical with ALC880 parser... */
6601 static int alc882_parse_auto_config(struct hda_codec *codec)
6603 struct alc_spec *spec = codec->spec;
6604 int err = alc880_parse_auto_config(codec);
6609 return 0; /* no config found */
6611 err = alc_auto_add_mic_boost(codec);
6615 /* hack - override the init verbs */
6616 spec->init_verbs[0] = alc882_auto_init_verbs;
6618 return 1; /* config found */
6621 /* additional initialization for auto-configuration model */
6622 static void alc882_auto_init(struct hda_codec *codec)
6624 struct alc_spec *spec = codec->spec;
6625 alc882_auto_init_multi_out(codec);
6626 alc882_auto_init_hp_out(codec);
6627 alc882_auto_init_analog_input(codec);
6628 alc882_auto_init_input_src(codec);
6629 if (spec->unsol_event)
6630 alc_sku_automute(codec);
6633 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6635 static int patch_alc882(struct hda_codec *codec)
6637 struct alc_spec *spec;
6638 int err, board_config;
6640 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6646 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6650 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6651 /* Pick up systems that don't supply PCI SSID */
6652 switch (codec->subsystem_id) {
6653 case 0x106b0c00: /* Mac Pro */
6654 board_config = ALC885_MACPRO;
6656 case 0x106b1000: /* iMac 24 */
6657 board_config = ALC885_IMAC24;
6659 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6660 case 0x106b2c00: /* Macbook Pro rev3 */
6661 case 0x106b3600: /* Macbook 3.1 */
6662 board_config = ALC885_MBP3;
6665 /* ALC889A is handled better as ALC888-compatible */
6666 if (codec->revision_id == 0x100103) {
6668 return patch_alc883(codec);
6670 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6671 "trying auto-probe from BIOS...\n");
6672 board_config = ALC882_AUTO;
6676 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6678 if (board_config == ALC882_AUTO) {
6679 /* automatic parse from the BIOS config */
6680 err = alc882_parse_auto_config(codec);
6686 "hda_codec: Cannot set up configuration "
6687 "from BIOS. Using base mode...\n");
6688 board_config = ALC882_3ST_DIG;
6692 if (board_config != ALC882_AUTO)
6693 setup_preset(spec, &alc882_presets[board_config]);
6695 if (codec->vendor_id == 0x10ec0885) {
6696 spec->stream_name_analog = "ALC885 Analog";
6697 spec->stream_name_digital = "ALC885 Digital";
6699 spec->stream_name_analog = "ALC882 Analog";
6700 spec->stream_name_digital = "ALC882 Digital";
6703 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6704 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6705 /* FIXME: setup DAC5 */
6706 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6707 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6709 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6710 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6712 if (!spec->adc_nids && spec->input_mux) {
6713 /* check whether NID 0x07 is valid */
6714 unsigned int wcap = get_wcaps(codec, 0x07);
6716 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6717 if (wcap != AC_WID_AUD_IN) {
6718 spec->adc_nids = alc882_adc_nids_alt;
6719 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6720 spec->capsrc_nids = alc882_capsrc_nids_alt;
6721 spec->mixers[spec->num_mixers] =
6722 alc882_capture_alt_mixer;
6725 spec->adc_nids = alc882_adc_nids;
6726 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6727 spec->capsrc_nids = alc882_capsrc_nids;
6728 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6733 spec->vmaster_nid = 0x0c;
6735 codec->patch_ops = alc_patch_ops;
6736 if (board_config == ALC882_AUTO)
6737 spec->init_hook = alc882_auto_init;
6738 #ifdef CONFIG_SND_HDA_POWER_SAVE
6739 if (!spec->loopback.amplist)
6740 spec->loopback.amplist = alc882_loopbacks;
6749 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6750 * configuration. Each pin widget can choose any input DACs and a mixer.
6751 * Each ADC is connected from a mixer of all inputs. This makes possible
6752 * 6-channel independent captures.
6754 * In addition, an independent DAC for the multi-playback (not used in this
6757 #define ALC883_DIGOUT_NID 0x06
6758 #define ALC883_DIGIN_NID 0x0a
6760 static hda_nid_t alc883_dac_nids[4] = {
6761 /* front, rear, clfe, rear_surr */
6762 0x02, 0x03, 0x04, 0x05
6765 static hda_nid_t alc883_adc_nids[2] = {
6770 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6773 /* FIXME: should be a matrix-type input source selection */
6775 static struct hda_input_mux alc883_capture_source = {
6779 { "Front Mic", 0x1 },
6785 static struct hda_input_mux alc883_3stack_6ch_intel = {
6789 { "Front Mic", 0x0 },
6795 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6803 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6813 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6821 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6825 { "Front Mic", 0x1 },
6830 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6838 #define alc883_mux_enum_info alc_mux_enum_info
6839 #define alc883_mux_enum_get alc_mux_enum_get
6840 /* ALC883 has the ALC882-type input selection */
6841 #define alc883_mux_enum_put alc882_mux_enum_put
6846 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6853 static struct hda_verb alc883_3ST_ch2_init[] = {
6854 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6855 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6856 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6857 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6864 static struct hda_verb alc883_3ST_ch4_init[] = {
6865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6867 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6868 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6869 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6876 static struct hda_verb alc883_3ST_ch6_init[] = {
6877 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6878 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6879 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6880 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6881 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6882 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6886 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6887 { 2, alc883_3ST_ch2_init },
6888 { 4, alc883_3ST_ch4_init },
6889 { 6, alc883_3ST_ch6_init },
6895 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6896 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6897 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6898 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6899 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6906 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6907 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6908 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6909 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6910 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6911 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6918 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6919 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6920 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6921 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6922 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6923 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6924 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6928 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6929 { 2, alc883_3ST_ch2_intel_init },
6930 { 4, alc883_3ST_ch4_intel_init },
6931 { 6, alc883_3ST_ch6_intel_init },
6937 static struct hda_verb alc883_sixstack_ch6_init[] = {
6938 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6939 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6940 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6948 static struct hda_verb alc883_sixstack_ch8_init[] = {
6949 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6950 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6951 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6952 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6956 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6957 { 6, alc883_sixstack_ch6_init },
6958 { 8, alc883_sixstack_ch8_init },
6961 static struct hda_verb alc883_medion_eapd_verbs[] = {
6962 /* eanable EAPD on medion laptop */
6963 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6964 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6968 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6969 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6972 static struct snd_kcontrol_new alc883_base_mixer[] = {
6973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6974 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6975 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6976 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6977 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6978 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6979 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6980 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6981 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6982 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6984 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6985 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6986 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6987 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6989 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6991 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6992 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6993 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6994 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6995 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6996 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6997 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6998 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6999 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7001 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7002 /* .name = "Capture Source", */
7003 .name = "Input Source",
7005 .info = alc883_mux_enum_info,
7006 .get = alc883_mux_enum_get,
7007 .put = alc883_mux_enum_put,
7012 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7013 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7014 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7015 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7016 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7017 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7018 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7019 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7021 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7023 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7024 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7025 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7026 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7027 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7028 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7029 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7032 /* .name = "Capture Source", */
7033 .name = "Input Source",
7035 .info = alc883_mux_enum_info,
7036 .get = alc883_mux_enum_get,
7037 .put = alc883_mux_enum_put,
7042 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7044 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7045 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7046 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7048 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7050 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7051 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7052 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7053 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7054 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7055 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7056 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7059 /* .name = "Capture Source", */
7060 .name = "Input Source",
7062 .info = alc883_mux_enum_info,
7063 .get = alc883_mux_enum_get,
7064 .put = alc883_mux_enum_put,
7069 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7071 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7072 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7073 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7075 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7077 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7078 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7079 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7080 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7081 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7082 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7083 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7086 /* .name = "Capture Source", */
7087 .name = "Input Source",
7089 .info = alc883_mux_enum_info,
7090 .get = alc883_mux_enum_get,
7091 .put = alc883_mux_enum_put,
7096 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7097 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7098 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7100 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7101 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7102 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7103 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7104 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7105 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7106 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7107 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7108 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7109 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7110 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7111 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7112 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7113 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7114 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7115 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7118 /* .name = "Capture Source", */
7119 .name = "Input Source",
7121 .info = alc883_mux_enum_info,
7122 .get = alc883_mux_enum_get,
7123 .put = alc883_mux_enum_put,
7128 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7129 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7130 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7131 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7132 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7133 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7134 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7135 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7136 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7137 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7138 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7139 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7140 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7141 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7143 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7145 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7146 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7148 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7149 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7150 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7151 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7154 /* .name = "Capture Source", */
7155 .name = "Input Source",
7157 .info = alc883_mux_enum_info,
7158 .get = alc883_mux_enum_get,
7159 .put = alc883_mux_enum_put,
7164 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7165 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7166 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7167 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7168 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7169 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7171 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7172 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7173 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7175 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7176 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7180 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7181 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7182 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7183 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7184 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7185 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7186 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7187 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7188 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7189 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7190 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7193 /* .name = "Capture Source", */
7194 .name = "Input Source",
7196 .info = alc883_mux_enum_info,
7197 .get = alc883_mux_enum_get,
7198 .put = alc883_mux_enum_put,
7203 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7204 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7205 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7206 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7208 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7209 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7210 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7211 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7213 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7214 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7215 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7216 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7218 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7219 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7220 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7221 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7222 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7223 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7224 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7225 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7226 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7230 /* .name = "Capture Source", */
7231 .name = "Input Source",
7233 .info = alc883_mux_enum_info,
7234 .get = alc883_mux_enum_get,
7235 .put = alc883_mux_enum_put,
7240 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7241 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7243 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7244 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7245 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7246 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7247 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7248 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7249 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7250 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7251 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7252 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7253 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7254 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7255 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7256 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7257 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7258 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7259 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7260 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7262 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7263 /* .name = "Capture Source", */
7264 .name = "Input Source",
7266 .info = alc883_mux_enum_info,
7267 .get = alc883_mux_enum_get,
7268 .put = alc883_mux_enum_put,
7273 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7274 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7276 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7277 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7278 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7279 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7280 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7281 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7282 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7283 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7284 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7285 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7286 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7287 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7288 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7290 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7291 /* .name = "Capture Source", */
7292 .name = "Input Source",
7294 .info = alc883_mux_enum_info,
7295 .get = alc883_mux_enum_get,
7296 .put = alc883_mux_enum_put,
7301 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7302 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7303 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7304 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7305 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7306 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7307 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7308 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7309 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7310 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7311 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7314 /* .name = "Capture Source", */
7315 .name = "Input Source",
7317 .info = alc883_mux_enum_info,
7318 .get = alc883_mux_enum_get,
7319 .put = alc883_mux_enum_put,
7324 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7325 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7326 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7327 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7328 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7329 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7330 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7331 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7332 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7333 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7334 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7335 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7336 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7337 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7340 /* .name = "Capture Source", */
7341 .name = "Input Source",
7343 .info = alc883_mux_enum_info,
7344 .get = alc883_mux_enum_get,
7345 .put = alc883_mux_enum_put,
7350 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7351 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7353 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7354 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7355 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7360 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7361 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7362 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7363 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7366 /* .name = "Capture Source", */
7367 .name = "Input Source",
7369 .info = alc883_mux_enum_info,
7370 .get = alc883_mux_enum_get,
7371 .put = alc883_mux_enum_put,
7376 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7377 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7378 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7379 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7385 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7386 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7387 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7388 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7390 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7391 /* .name = "Capture Source", */
7392 .name = "Input Source",
7394 .info = alc883_mux_enum_info,
7395 .get = alc883_mux_enum_get,
7396 .put = alc883_mux_enum_put,
7401 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7402 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7403 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7404 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7405 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7406 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7407 0x0d, 1, 0x0, HDA_OUTPUT),
7408 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7409 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7410 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7411 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7412 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7414 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7415 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7416 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7417 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7418 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7421 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7422 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7423 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7424 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7425 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7426 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7427 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7428 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7431 /* .name = "Capture Source", */
7432 .name = "Input Source",
7434 .info = alc883_mux_enum_info,
7435 .get = alc883_mux_enum_get,
7436 .put = alc883_mux_enum_put,
7441 static struct hda_bind_ctls alc883_bind_cap_vol = {
7442 .ops = &snd_hda_bind_vol,
7444 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7445 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7450 static struct hda_bind_ctls alc883_bind_cap_switch = {
7451 .ops = &snd_hda_bind_sw,
7453 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7454 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7459 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7460 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7461 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7463 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7464 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7466 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7467 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7468 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7469 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7472 /* .name = "Capture Source", */
7473 .name = "Input Source",
7475 .info = alc883_mux_enum_info,
7476 .get = alc883_mux_enum_get,
7477 .put = alc883_mux_enum_put,
7482 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7484 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7485 .name = "Channel Mode",
7486 .info = alc_ch_mode_info,
7487 .get = alc_ch_mode_get,
7488 .put = alc_ch_mode_put,
7493 static struct hda_verb alc883_init_verbs[] = {
7494 /* ADC1: mute amp left and right */
7495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7496 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7497 /* ADC2: mute amp left and right */
7498 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7499 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7500 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7511 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7513 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7517 /* mute analog input loopbacks */
7518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7524 /* Front Pin: output 0 (0x0c) */
7525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7527 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7528 /* Rear Pin: output 1 (0x0d) */
7529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7530 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7531 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7532 /* CLFE Pin: output 2 (0x0e) */
7533 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7534 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7535 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7536 /* Side Pin: output 3 (0x0f) */
7537 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7538 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7539 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7540 /* Mic (rear) pin: input vref at 80% */
7541 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7542 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7543 /* Front Mic pin: input vref at 80% */
7544 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7545 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7546 /* Line In pin: input */
7547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7548 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7549 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7550 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7551 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7552 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7553 /* CD pin widget for input */
7554 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7556 /* FIXME: use matrix-type input source selection */
7557 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7565 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7571 /* toggle speaker-output according to the hp-jack state */
7572 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7574 unsigned int present;
7576 present = snd_hda_codec_read(codec, 0x15, 0,
7577 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7578 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7579 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7580 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7581 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7584 /* auto-toggle front mic */
7586 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7588 unsigned int present;
7591 present = snd_hda_codec_read(codec, 0x18, 0,
7592 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7593 bits = present ? HDA_AMP_MUTE : 0;
7594 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7598 static void alc883_mitac_automute(struct hda_codec *codec)
7600 alc883_mitac_hp_automute(codec);
7601 /* alc883_mitac_mic_automute(codec); */
7604 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7607 switch (res >> 26) {
7608 case ALC880_HP_EVENT:
7609 alc883_mitac_hp_automute(codec);
7611 case ALC880_MIC_EVENT:
7612 /* alc883_mitac_mic_automute(codec); */
7617 static struct hda_verb alc883_mitac_verbs[] = {
7619 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7620 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7622 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7623 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7625 /* enable unsolicited event */
7626 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7627 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7632 static struct hda_verb alc883_clevo_m720_verbs[] = {
7634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7635 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7640 /* enable unsolicited event */
7641 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7642 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7647 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7649 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7655 /* enable unsolicited event */
7656 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7661 static struct hda_verb alc883_tagra_verbs[] = {
7662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7665 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7666 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7668 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7669 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7670 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7672 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7673 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7674 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7675 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7680 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7681 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7682 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7683 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7687 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7688 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7690 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7695 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7698 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7700 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7704 static struct hda_verb alc883_haier_w66_verbs[] = {
7705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7708 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7710 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7711 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7712 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7713 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7717 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7721 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7722 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7724 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7725 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7729 static struct hda_verb alc888_3st_hp_verbs[] = {
7730 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7731 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7732 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7736 static struct hda_verb alc888_6st_dell_verbs[] = {
7737 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7741 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7742 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7743 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7744 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7745 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7749 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7750 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7752 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7753 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7757 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7758 { 2, alc888_3st_hp_2ch_init },
7759 { 6, alc888_3st_hp_6ch_init },
7762 /* toggle front-jack and RCA according to the hp-jack state */
7763 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7765 unsigned int present;
7767 present = snd_hda_codec_read(codec, 0x1b, 0,
7768 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7769 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7770 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7771 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7772 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7775 /* toggle RCA according to the front-jack state */
7776 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7778 unsigned int present;
7780 present = snd_hda_codec_read(codec, 0x14, 0,
7781 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7782 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7783 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7786 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7789 if ((res >> 26) == ALC880_HP_EVENT)
7790 alc888_lenovo_ms7195_front_automute(codec);
7791 if ((res >> 26) == ALC880_FRONT_EVENT)
7792 alc888_lenovo_ms7195_rca_automute(codec);
7795 static struct hda_verb alc883_medion_md2_verbs[] = {
7796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7801 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7805 /* toggle speaker-output according to the hp-jack state */
7806 static void alc883_medion_md2_automute(struct hda_codec *codec)
7808 unsigned int present;
7810 present = snd_hda_codec_read(codec, 0x14, 0,
7811 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7812 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7813 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7816 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7819 if ((res >> 26) == ALC880_HP_EVENT)
7820 alc883_medion_md2_automute(codec);
7823 /* toggle speaker-output according to the hp-jack state */
7824 static void alc883_tagra_automute(struct hda_codec *codec)
7826 unsigned int present;
7829 present = snd_hda_codec_read(codec, 0x14, 0,
7830 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7831 bits = present ? HDA_AMP_MUTE : 0;
7832 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7833 HDA_AMP_MUTE, bits);
7834 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7838 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7840 if ((res >> 26) == ALC880_HP_EVENT)
7841 alc883_tagra_automute(codec);
7844 /* toggle speaker-output according to the hp-jack state */
7845 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7847 unsigned int present;
7850 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7851 & AC_PINSENSE_PRESENCE;
7852 bits = present ? HDA_AMP_MUTE : 0;
7853 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7854 HDA_AMP_MUTE, bits);
7857 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7859 unsigned int present;
7861 present = snd_hda_codec_read(codec, 0x18, 0,
7862 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7863 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7864 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7867 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7869 alc883_clevo_m720_hp_automute(codec);
7870 alc883_clevo_m720_mic_automute(codec);
7873 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7876 switch (res >> 26) {
7877 case ALC880_HP_EVENT:
7878 alc883_clevo_m720_hp_automute(codec);
7880 case ALC880_MIC_EVENT:
7881 alc883_clevo_m720_mic_automute(codec);
7886 /* toggle speaker-output according to the hp-jack state */
7887 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7889 unsigned int present;
7892 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7893 & AC_PINSENSE_PRESENCE;
7894 bits = present ? HDA_AMP_MUTE : 0;
7895 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7896 HDA_AMP_MUTE, bits);
7899 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7902 if ((res >> 26) == ALC880_HP_EVENT)
7903 alc883_2ch_fujitsu_pi2515_automute(codec);
7906 static void alc883_haier_w66_automute(struct hda_codec *codec)
7908 unsigned int present;
7911 present = snd_hda_codec_read(codec, 0x1b, 0,
7912 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7913 bits = present ? 0x80 : 0;
7914 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7918 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7921 if ((res >> 26) == ALC880_HP_EVENT)
7922 alc883_haier_w66_automute(codec);
7925 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7927 unsigned int present;
7930 present = snd_hda_codec_read(codec, 0x14, 0,
7931 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7932 bits = present ? HDA_AMP_MUTE : 0;
7933 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7934 HDA_AMP_MUTE, bits);
7937 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7939 unsigned int present;
7942 present = snd_hda_codec_read(codec, 0x1b, 0,
7943 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7944 bits = present ? HDA_AMP_MUTE : 0;
7945 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7946 HDA_AMP_MUTE, bits);
7947 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7948 HDA_AMP_MUTE, bits);
7951 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7954 if ((res >> 26) == ALC880_HP_EVENT)
7955 alc883_lenovo_101e_all_automute(codec);
7956 if ((res >> 26) == ALC880_FRONT_EVENT)
7957 alc883_lenovo_101e_ispeaker_automute(codec);
7960 /* toggle speaker-output according to the hp-jack state */
7961 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7963 unsigned int present;
7965 present = snd_hda_codec_read(codec, 0x14, 0,
7966 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7967 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7968 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7969 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7970 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7973 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7976 if ((res >> 26) == ALC880_HP_EVENT)
7977 alc883_acer_aspire_automute(codec);
7980 static struct hda_verb alc883_acer_eapd_verbs[] = {
7981 /* HP Pin: output 0 (0x0c) */
7982 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7983 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7985 /* Front Pin: output 0 (0x0c) */
7986 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7987 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7988 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7989 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7990 /* eanable EAPD on medion laptop */
7991 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7992 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7993 /* enable unsolicited event */
7994 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7998 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8000 unsigned int present;
8002 present = snd_hda_codec_read(codec, 0x1b, 0,
8003 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8004 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8005 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8006 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8007 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8008 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8009 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8010 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8011 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8014 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8017 switch (res >> 26) {
8018 case ALC880_HP_EVENT:
8019 printk("hp_event\n");
8020 alc888_6st_dell_front_automute(codec);
8025 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8028 unsigned int present;
8030 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8031 present = snd_hda_codec_read(codec, 0x1b, 0,
8032 AC_VERB_GET_PIN_SENSE, 0);
8033 present = (present & 0x80000000) != 0;
8035 /* mute internal speaker */
8036 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8037 HDA_AMP_MUTE, HDA_AMP_MUTE);
8038 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8039 HDA_AMP_MUTE, HDA_AMP_MUTE);
8040 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8041 HDA_AMP_MUTE, HDA_AMP_MUTE);
8042 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8043 HDA_AMP_MUTE, HDA_AMP_MUTE);
8044 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8045 HDA_AMP_MUTE, HDA_AMP_MUTE);
8047 /* unmute internal speaker if necessary */
8048 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8049 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8050 HDA_AMP_MUTE, mute);
8051 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8052 HDA_AMP_MUTE, mute);
8053 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8054 HDA_AMP_MUTE, mute);
8055 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8056 HDA_AMP_MUTE, mute);
8057 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8058 HDA_AMP_MUTE, mute);
8062 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8065 if ((res >> 26) == ALC880_HP_EVENT)
8066 alc888_lenovo_sky_front_automute(codec);
8070 * generic initialization of ADC, input mixers and output mixers
8072 static struct hda_verb alc883_auto_init_verbs[] = {
8074 * Unmute ADC0-2 and set the default input to mic-in
8076 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8077 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8078 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8079 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8081 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8083 * Note: PASD motherboards uses the Line In 2 as the input for
8084 * front panel mic (mic 2)
8086 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8094 * Set up output mixers (0x0c - 0x0f)
8096 /* set vol=0 to output mixers */
8097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8098 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8099 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8100 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8101 /* set up input amps for analog loopback */
8102 /* Amp Indices: DAC = 0, mixer = 1 */
8103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8104 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8107 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8108 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8109 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8110 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8111 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8112 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8114 /* FIXME: use matrix-type input source selection */
8115 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8120 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8126 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8132 /* capture mixer elements */
8133 static struct snd_kcontrol_new alc883_capture_mixer[] = {
8134 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8135 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8136 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8137 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8140 /* The multiple "Capture Source" controls confuse alsamixer
8141 * So call somewhat different..
8143 /* .name = "Capture Source", */
8144 .name = "Input Source",
8146 .info = alc882_mux_enum_info,
8147 .get = alc882_mux_enum_get,
8148 .put = alc882_mux_enum_put,
8153 static struct hda_verb alc888_asus_m90v_verbs[] = {
8154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8157 /* enable unsolicited event */
8158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8159 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8163 static void alc883_nb_mic_automute(struct hda_codec *codec)
8165 unsigned int present;
8167 present = snd_hda_codec_read(codec, 0x18, 0,
8168 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8169 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8170 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8171 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8172 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8175 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8177 unsigned int present;
8180 present = snd_hda_codec_read(codec, 0x1b, 0,
8181 AC_VERB_GET_PIN_SENSE, 0)
8182 & AC_PINSENSE_PRESENCE;
8183 bits = present ? 0 : PIN_OUT;
8184 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8186 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8188 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8192 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8195 switch (res >> 26) {
8196 case ALC880_HP_EVENT:
8197 alc883_M90V_speaker_automute(codec);
8199 case ALC880_MIC_EVENT:
8200 alc883_nb_mic_automute(codec);
8205 static void alc883_mode2_inithook(struct hda_codec *codec)
8207 alc883_M90V_speaker_automute(codec);
8208 alc883_nb_mic_automute(codec);
8211 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8212 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8213 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8217 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8218 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8219 /* enable unsolicited event */
8220 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8224 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8226 unsigned int present;
8229 present = snd_hda_codec_read(codec, 0x14, 0,
8230 AC_VERB_GET_PIN_SENSE, 0)
8231 & AC_PINSENSE_PRESENCE;
8232 bits = present ? 0 : PIN_OUT;
8233 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8237 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8240 switch (res >> 26) {
8241 case ALC880_HP_EVENT:
8242 alc883_eee1601_speaker_automute(codec);
8247 static void alc883_eee1601_inithook(struct hda_codec *codec)
8249 alc883_eee1601_speaker_automute(codec);
8252 #ifdef CONFIG_SND_HDA_POWER_SAVE
8253 #define alc883_loopbacks alc880_loopbacks
8256 /* pcm configuration: identiacal with ALC880 */
8257 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8258 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8259 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8260 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8261 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8264 * configuration and preset
8266 static const char *alc883_models[ALC883_MODEL_LAST] = {
8267 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8268 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8269 [ALC883_3ST_6ch] = "3stack-6ch",
8270 [ALC883_6ST_DIG] = "6stack-dig",
8271 [ALC883_TARGA_DIG] = "targa-dig",
8272 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8273 [ALC883_ACER] = "acer",
8274 [ALC883_ACER_ASPIRE] = "acer-aspire",
8275 [ALC883_MEDION] = "medion",
8276 [ALC883_MEDION_MD2] = "medion-md2",
8277 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8278 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8279 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8280 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8281 [ALC888_LENOVO_SKY] = "lenovo-sky",
8282 [ALC883_HAIER_W66] = "haier-w66",
8283 [ALC888_3ST_HP] = "3stack-hp",
8284 [ALC888_6ST_DELL] = "6stack-dell",
8285 [ALC883_MITAC] = "mitac",
8286 [ALC883_CLEVO_M720] = "clevo-m720",
8287 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8288 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8289 [ALC883_AUTO] = "auto",
8292 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8293 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8294 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8295 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8296 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8297 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8298 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8299 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8300 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8301 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8302 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8303 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8304 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8305 SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
8306 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8307 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8308 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8309 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8310 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8311 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8312 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8313 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8314 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8315 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8316 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8317 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8318 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8319 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8320 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8321 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8322 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8323 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8324 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8325 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8326 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8327 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8328 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8329 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8330 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8331 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8332 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8333 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8334 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8335 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8336 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8337 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8338 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8339 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8340 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8341 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8342 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8343 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8344 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8345 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8346 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8347 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8348 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8349 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8350 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8351 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8352 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8353 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8357 static struct alc_config_preset alc883_presets[] = {
8358 [ALC883_3ST_2ch_DIG] = {
8359 .mixers = { alc883_3ST_2ch_mixer },
8360 .init_verbs = { alc883_init_verbs },
8361 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8362 .dac_nids = alc883_dac_nids,
8363 .dig_out_nid = ALC883_DIGOUT_NID,
8364 .dig_in_nid = ALC883_DIGIN_NID,
8365 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8366 .channel_mode = alc883_3ST_2ch_modes,
8367 .input_mux = &alc883_capture_source,
8369 [ALC883_3ST_6ch_DIG] = {
8370 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8371 .init_verbs = { alc883_init_verbs },
8372 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8373 .dac_nids = alc883_dac_nids,
8374 .dig_out_nid = ALC883_DIGOUT_NID,
8375 .dig_in_nid = ALC883_DIGIN_NID,
8376 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8377 .channel_mode = alc883_3ST_6ch_modes,
8379 .input_mux = &alc883_capture_source,
8381 [ALC883_3ST_6ch] = {
8382 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8383 .init_verbs = { alc883_init_verbs },
8384 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8385 .dac_nids = alc883_dac_nids,
8386 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8387 .channel_mode = alc883_3ST_6ch_modes,
8389 .input_mux = &alc883_capture_source,
8391 [ALC883_3ST_6ch_INTEL] = {
8392 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8393 .init_verbs = { alc883_init_verbs },
8394 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8395 .dac_nids = alc883_dac_nids,
8396 .dig_out_nid = ALC883_DIGOUT_NID,
8397 .dig_in_nid = ALC883_DIGIN_NID,
8398 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8399 .channel_mode = alc883_3ST_6ch_intel_modes,
8401 .input_mux = &alc883_3stack_6ch_intel,
8403 [ALC883_6ST_DIG] = {
8404 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8405 .init_verbs = { alc883_init_verbs },
8406 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8407 .dac_nids = alc883_dac_nids,
8408 .dig_out_nid = ALC883_DIGOUT_NID,
8409 .dig_in_nid = ALC883_DIGIN_NID,
8410 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8411 .channel_mode = alc883_sixstack_modes,
8412 .input_mux = &alc883_capture_source,
8414 [ALC883_TARGA_DIG] = {
8415 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8416 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8417 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8418 .dac_nids = alc883_dac_nids,
8419 .dig_out_nid = ALC883_DIGOUT_NID,
8420 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8421 .channel_mode = alc883_3ST_6ch_modes,
8423 .input_mux = &alc883_capture_source,
8424 .unsol_event = alc883_tagra_unsol_event,
8425 .init_hook = alc883_tagra_automute,
8427 [ALC883_TARGA_2ch_DIG] = {
8428 .mixers = { alc883_tagra_2ch_mixer},
8429 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8430 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8431 .dac_nids = alc883_dac_nids,
8432 .dig_out_nid = ALC883_DIGOUT_NID,
8433 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8434 .channel_mode = alc883_3ST_2ch_modes,
8435 .input_mux = &alc883_capture_source,
8436 .unsol_event = alc883_tagra_unsol_event,
8437 .init_hook = alc883_tagra_automute,
8440 .mixers = { alc883_base_mixer },
8441 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8442 * and the headphone jack. Turn this on and rely on the
8443 * standard mute methods whenever the user wants to turn
8444 * these outputs off.
8446 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8447 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8448 .dac_nids = alc883_dac_nids,
8449 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8450 .channel_mode = alc883_3ST_2ch_modes,
8451 .input_mux = &alc883_capture_source,
8453 [ALC883_ACER_ASPIRE] = {
8454 .mixers = { alc883_acer_aspire_mixer },
8455 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8456 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8457 .dac_nids = alc883_dac_nids,
8458 .dig_out_nid = ALC883_DIGOUT_NID,
8459 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8460 .channel_mode = alc883_3ST_2ch_modes,
8461 .input_mux = &alc883_capture_source,
8462 .unsol_event = alc883_acer_aspire_unsol_event,
8463 .init_hook = alc883_acer_aspire_automute,
8466 .mixers = { alc883_fivestack_mixer,
8467 alc883_chmode_mixer },
8468 .init_verbs = { alc883_init_verbs,
8469 alc883_medion_eapd_verbs },
8470 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8471 .dac_nids = alc883_dac_nids,
8472 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8473 .channel_mode = alc883_sixstack_modes,
8474 .input_mux = &alc883_capture_source,
8476 [ALC883_MEDION_MD2] = {
8477 .mixers = { alc883_medion_md2_mixer},
8478 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8479 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8480 .dac_nids = alc883_dac_nids,
8481 .dig_out_nid = ALC883_DIGOUT_NID,
8482 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8483 .channel_mode = alc883_3ST_2ch_modes,
8484 .input_mux = &alc883_capture_source,
8485 .unsol_event = alc883_medion_md2_unsol_event,
8486 .init_hook = alc883_medion_md2_automute,
8488 [ALC883_LAPTOP_EAPD] = {
8489 .mixers = { alc883_base_mixer },
8490 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8491 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8492 .dac_nids = alc883_dac_nids,
8493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8494 .channel_mode = alc883_3ST_2ch_modes,
8495 .input_mux = &alc883_capture_source,
8497 [ALC883_CLEVO_M720] = {
8498 .mixers = { alc883_clevo_m720_mixer },
8499 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8500 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8501 .dac_nids = alc883_dac_nids,
8502 .dig_out_nid = ALC883_DIGOUT_NID,
8503 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8504 .channel_mode = alc883_3ST_2ch_modes,
8505 .input_mux = &alc883_capture_source,
8506 .unsol_event = alc883_clevo_m720_unsol_event,
8507 .init_hook = alc883_clevo_m720_automute,
8509 [ALC883_LENOVO_101E_2ch] = {
8510 .mixers = { alc883_lenovo_101e_2ch_mixer},
8511 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8512 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8513 .dac_nids = alc883_dac_nids,
8514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8515 .channel_mode = alc883_3ST_2ch_modes,
8516 .input_mux = &alc883_lenovo_101e_capture_source,
8517 .unsol_event = alc883_lenovo_101e_unsol_event,
8518 .init_hook = alc883_lenovo_101e_all_automute,
8520 [ALC883_LENOVO_NB0763] = {
8521 .mixers = { alc883_lenovo_nb0763_mixer },
8522 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8523 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8524 .dac_nids = alc883_dac_nids,
8525 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8526 .channel_mode = alc883_3ST_2ch_modes,
8528 .input_mux = &alc883_lenovo_nb0763_capture_source,
8529 .unsol_event = alc883_medion_md2_unsol_event,
8530 .init_hook = alc883_medion_md2_automute,
8532 [ALC888_LENOVO_MS7195_DIG] = {
8533 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8534 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8535 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8536 .dac_nids = alc883_dac_nids,
8537 .dig_out_nid = ALC883_DIGOUT_NID,
8538 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8539 .channel_mode = alc883_3ST_6ch_modes,
8541 .input_mux = &alc883_capture_source,
8542 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8543 .init_hook = alc888_lenovo_ms7195_front_automute,
8545 [ALC883_HAIER_W66] = {
8546 .mixers = { alc883_tagra_2ch_mixer},
8547 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8548 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8549 .dac_nids = alc883_dac_nids,
8550 .dig_out_nid = ALC883_DIGOUT_NID,
8551 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8552 .channel_mode = alc883_3ST_2ch_modes,
8553 .input_mux = &alc883_capture_source,
8554 .unsol_event = alc883_haier_w66_unsol_event,
8555 .init_hook = alc883_haier_w66_automute,
8558 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8559 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8560 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8561 .dac_nids = alc883_dac_nids,
8562 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8563 .channel_mode = alc888_3st_hp_modes,
8565 .input_mux = &alc883_capture_source,
8567 [ALC888_6ST_DELL] = {
8568 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8569 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8571 .dac_nids = alc883_dac_nids,
8572 .dig_out_nid = ALC883_DIGOUT_NID,
8573 .dig_in_nid = ALC883_DIGIN_NID,
8574 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8575 .channel_mode = alc883_sixstack_modes,
8576 .input_mux = &alc883_capture_source,
8577 .unsol_event = alc888_6st_dell_unsol_event,
8578 .init_hook = alc888_6st_dell_front_automute,
8581 .mixers = { alc883_mitac_mixer },
8582 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8583 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8584 .dac_nids = alc883_dac_nids,
8585 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8586 .channel_mode = alc883_3ST_2ch_modes,
8587 .input_mux = &alc883_capture_source,
8588 .unsol_event = alc883_mitac_unsol_event,
8589 .init_hook = alc883_mitac_automute,
8591 [ALC883_FUJITSU_PI2515] = {
8592 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8593 .init_verbs = { alc883_init_verbs,
8594 alc883_2ch_fujitsu_pi2515_verbs},
8595 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8596 .dac_nids = alc883_dac_nids,
8597 .dig_out_nid = ALC883_DIGOUT_NID,
8598 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8599 .channel_mode = alc883_3ST_2ch_modes,
8600 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8601 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8602 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8604 [ALC888_LENOVO_SKY] = {
8605 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8606 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8607 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8608 .dac_nids = alc883_dac_nids,
8609 .dig_out_nid = ALC883_DIGOUT_NID,
8610 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8611 .adc_nids = alc883_adc_nids,
8612 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8613 .channel_mode = alc883_sixstack_modes,
8615 .input_mux = &alc883_lenovo_sky_capture_source,
8616 .unsol_event = alc883_lenovo_sky_unsol_event,
8617 .init_hook = alc888_lenovo_sky_front_automute,
8619 [ALC888_ASUS_M90V] = {
8620 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8621 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8622 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8623 .dac_nids = alc883_dac_nids,
8624 .dig_out_nid = ALC883_DIGOUT_NID,
8625 .dig_in_nid = ALC883_DIGIN_NID,
8626 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8627 .channel_mode = alc883_3ST_6ch_modes,
8629 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8630 .unsol_event = alc883_mode2_unsol_event,
8631 .init_hook = alc883_mode2_inithook,
8633 [ALC888_ASUS_EEE1601] = {
8634 .mixers = { alc883_asus_eee1601_mixer },
8635 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8636 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8637 .dac_nids = alc883_dac_nids,
8638 .dig_out_nid = ALC883_DIGOUT_NID,
8639 .dig_in_nid = ALC883_DIGIN_NID,
8640 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8641 .channel_mode = alc883_3ST_2ch_modes,
8643 .input_mux = &alc883_asus_eee1601_capture_source,
8644 .unsol_event = alc883_eee1601_unsol_event,
8645 .init_hook = alc883_eee1601_inithook,
8651 * BIOS auto configuration
8653 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8654 hda_nid_t nid, int pin_type,
8658 struct alc_spec *spec = codec->spec;
8661 alc_set_pin_output(codec, nid, pin_type);
8662 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8665 idx = spec->multiout.dac_nids[dac_idx] - 2;
8666 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8670 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8672 struct alc_spec *spec = codec->spec;
8675 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8676 for (i = 0; i <= HDA_SIDE; i++) {
8677 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8678 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8680 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8685 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8687 struct alc_spec *spec = codec->spec;
8690 pin = spec->autocfg.hp_pins[0];
8691 if (pin) /* connect to front */
8693 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8694 pin = spec->autocfg.speaker_pins[0];
8696 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8699 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8700 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8702 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8704 struct alc_spec *spec = codec->spec;
8707 for (i = 0; i < AUTO_PIN_LAST; i++) {
8708 hda_nid_t nid = spec->autocfg.input_pins[i];
8709 if (alc883_is_input_pin(nid)) {
8710 snd_hda_codec_write(codec, nid, 0,
8711 AC_VERB_SET_PIN_WIDGET_CONTROL,
8712 (i <= AUTO_PIN_FRONT_MIC ?
8713 PIN_VREF80 : PIN_IN));
8714 if (nid != ALC883_PIN_CD_NID)
8715 snd_hda_codec_write(codec, nid, 0,
8716 AC_VERB_SET_AMP_GAIN_MUTE,
8722 #define alc883_auto_init_input_src alc882_auto_init_input_src
8724 /* almost identical with ALC880 parser... */
8725 static int alc883_parse_auto_config(struct hda_codec *codec)
8727 struct alc_spec *spec = codec->spec;
8728 int err = alc880_parse_auto_config(codec);
8733 return 0; /* no config found */
8735 err = alc_auto_add_mic_boost(codec);
8739 /* hack - override the init verbs */
8740 spec->init_verbs[0] = alc883_auto_init_verbs;
8741 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8744 return 1; /* config found */
8747 /* additional initialization for auto-configuration model */
8748 static void alc883_auto_init(struct hda_codec *codec)
8750 struct alc_spec *spec = codec->spec;
8751 alc883_auto_init_multi_out(codec);
8752 alc883_auto_init_hp_out(codec);
8753 alc883_auto_init_analog_input(codec);
8754 alc883_auto_init_input_src(codec);
8755 if (spec->unsol_event)
8756 alc_sku_automute(codec);
8759 static int patch_alc883(struct hda_codec *codec)
8761 struct alc_spec *spec;
8762 int err, board_config;
8764 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8770 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8772 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8775 if (board_config < 0) {
8776 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8777 "trying auto-probe from BIOS...\n");
8778 board_config = ALC883_AUTO;
8781 if (board_config == ALC883_AUTO) {
8782 /* automatic parse from the BIOS config */
8783 err = alc883_parse_auto_config(codec);
8789 "hda_codec: Cannot set up configuration "
8790 "from BIOS. Using base mode...\n");
8791 board_config = ALC883_3ST_2ch_DIG;
8795 if (board_config != ALC883_AUTO)
8796 setup_preset(spec, &alc883_presets[board_config]);
8798 switch (codec->vendor_id) {
8800 spec->stream_name_analog = "ALC888 Analog";
8801 spec->stream_name_digital = "ALC888 Digital";
8804 spec->stream_name_analog = "ALC889 Analog";
8805 spec->stream_name_digital = "ALC889 Digital";
8808 spec->stream_name_analog = "ALC883 Analog";
8809 spec->stream_name_digital = "ALC883 Digital";
8813 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8814 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8815 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8817 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8818 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8820 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8821 spec->adc_nids = alc883_adc_nids;
8822 spec->capsrc_nids = alc883_capsrc_nids;
8824 spec->vmaster_nid = 0x0c;
8826 codec->patch_ops = alc_patch_ops;
8827 if (board_config == ALC883_AUTO)
8828 spec->init_hook = alc883_auto_init;
8830 #ifdef CONFIG_SND_HDA_POWER_SAVE
8831 if (!spec->loopback.amplist)
8832 spec->loopback.amplist = alc883_loopbacks;
8842 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8843 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8845 #define alc262_dac_nids alc260_dac_nids
8846 #define alc262_adc_nids alc882_adc_nids
8847 #define alc262_adc_nids_alt alc882_adc_nids_alt
8848 #define alc262_capsrc_nids alc882_capsrc_nids
8849 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8851 #define alc262_modes alc260_modes
8852 #define alc262_capture_source alc882_capture_source
8854 static hda_nid_t alc262_dmic_adc_nids[1] = {
8859 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8861 static struct snd_kcontrol_new alc262_base_mixer[] = {
8862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8863 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8864 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8865 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8866 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8867 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8869 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8870 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8871 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8872 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8873 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8874 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8875 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8876 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8878 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8879 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8883 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8884 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8885 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8886 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8887 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8888 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8889 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8890 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8891 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8892 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8893 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8894 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8895 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8896 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8897 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8898 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8899 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8903 /* update HP, line and mono-out pins according to the master switch */
8904 static void alc262_hp_master_update(struct hda_codec *codec)
8906 struct alc_spec *spec = codec->spec;
8907 int val = spec->master_sw;
8910 snd_hda_codec_write_cache(codec, 0x1b, 0,
8911 AC_VERB_SET_PIN_WIDGET_CONTROL,
8913 snd_hda_codec_write_cache(codec, 0x15, 0,
8914 AC_VERB_SET_PIN_WIDGET_CONTROL,
8916 /* mono (speaker) depending on the HP jack sense */
8917 val = val && !spec->jack_present;
8918 snd_hda_codec_write_cache(codec, 0x16, 0,
8919 AC_VERB_SET_PIN_WIDGET_CONTROL,
8923 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8925 struct alc_spec *spec = codec->spec;
8926 unsigned int presence;
8927 presence = snd_hda_codec_read(codec, 0x1b, 0,
8928 AC_VERB_GET_PIN_SENSE, 0);
8929 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8930 alc262_hp_master_update(codec);
8933 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8935 if ((res >> 26) != ALC880_HP_EVENT)
8937 alc262_hp_bpc_automute(codec);
8940 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8942 struct alc_spec *spec = codec->spec;
8943 unsigned int presence;
8944 presence = snd_hda_codec_read(codec, 0x15, 0,
8945 AC_VERB_GET_PIN_SENSE, 0);
8946 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8947 alc262_hp_master_update(codec);
8950 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8953 if ((res >> 26) != ALC880_HP_EVENT)
8955 alc262_hp_wildwest_automute(codec);
8958 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8959 struct snd_ctl_elem_value *ucontrol)
8961 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8962 struct alc_spec *spec = codec->spec;
8963 *ucontrol->value.integer.value = spec->master_sw;
8967 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8968 struct snd_ctl_elem_value *ucontrol)
8970 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8971 struct alc_spec *spec = codec->spec;
8972 int val = !!*ucontrol->value.integer.value;
8974 if (val == spec->master_sw)
8976 spec->master_sw = val;
8977 alc262_hp_master_update(codec);
8981 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8984 .name = "Master Playback Switch",
8985 .info = snd_ctl_boolean_mono_info,
8986 .get = alc262_hp_master_sw_get,
8987 .put = alc262_hp_master_sw_put,
8989 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8990 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8992 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8994 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8996 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8997 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8998 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9001 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9004 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9005 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9006 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9007 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9008 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9009 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9013 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9016 .name = "Master Playback Switch",
9017 .info = snd_ctl_boolean_mono_info,
9018 .get = alc262_hp_master_sw_get,
9019 .put = alc262_hp_master_sw_put,
9021 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9022 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9023 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9024 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9025 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9027 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9029 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9031 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9032 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9033 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9034 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9035 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9036 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9037 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9041 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9042 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9043 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9044 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9048 /* mute/unmute internal speaker according to the hp jack and mute state */
9049 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9051 struct alc_spec *spec = codec->spec;
9053 if (force || !spec->sense_updated) {
9054 unsigned int present;
9055 present = snd_hda_codec_read(codec, 0x15, 0,
9056 AC_VERB_GET_PIN_SENSE, 0);
9057 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9058 spec->sense_updated = 1;
9060 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9061 spec->jack_present ? HDA_AMP_MUTE : 0);
9064 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9067 if ((res >> 26) != ALC880_HP_EVENT)
9069 alc262_hp_t5735_automute(codec, 1);
9072 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9074 alc262_hp_t5735_automute(codec, 1);
9077 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9078 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9081 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9082 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9084 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9088 static struct hda_verb alc262_hp_t5735_verbs[] = {
9089 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9092 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9096 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9099 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9106 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9107 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9108 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9109 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9110 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9111 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9112 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9113 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9114 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9120 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9127 /* bind hp and internal speaker mute (with plug check) */
9128 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9129 struct snd_ctl_elem_value *ucontrol)
9131 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9132 long *valp = ucontrol->value.integer.value;
9135 /* change hp mute */
9136 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9138 valp[0] ? 0 : HDA_AMP_MUTE);
9139 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9141 valp[1] ? 0 : HDA_AMP_MUTE);
9143 /* change speaker according to HP jack state */
9144 struct alc_spec *spec = codec->spec;
9146 if (spec->jack_present)
9147 mute = HDA_AMP_MUTE;
9149 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9151 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9152 HDA_AMP_MUTE, mute);
9157 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9158 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9160 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9161 .name = "Master Playback Switch",
9162 .info = snd_hda_mixer_amp_switch_info,
9163 .get = snd_hda_mixer_amp_switch_get,
9164 .put = alc262_sony_master_sw_put,
9165 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9169 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9170 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9174 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9175 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9176 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9179 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9180 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9181 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9185 #define alc262_capture_mixer alc882_capture_mixer
9186 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9189 * generic initialization of ADC, input mixers and output mixers
9191 static struct hda_verb alc262_init_verbs[] = {
9193 * Unmute ADC0-2 and set the default input to mic-in
9195 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9197 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9198 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9199 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9202 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9204 * Note: PASD motherboards uses the Line In 2 as the input for
9205 * front panel mic (mic 2)
9207 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9208 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9215 * Set up output mixers (0x0c - 0x0e)
9217 /* set vol=0 to output mixers */
9218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9221 /* set up input amps for analog loopback */
9222 /* Amp Indices: DAC = 0, mixer = 1 */
9223 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9225 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9226 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9227 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9228 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9230 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9231 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9232 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9233 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9234 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9235 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9237 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9238 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9239 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9240 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9241 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9243 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9244 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9246 /* FIXME: use matrix-type input source selection */
9247 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9248 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9249 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9251 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9252 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9254 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9255 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9256 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9257 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9262 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9267 static struct hda_verb alc262_eapd_verbs[] = {
9268 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9269 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9273 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9274 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9279 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9280 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9281 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9282 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9284 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9289 static struct hda_verb alc262_sony_unsol_verbs[] = {
9290 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9291 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9292 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9294 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9299 static struct hda_input_mux alc262_dmic_capture_source = {
9302 { "Int DMic", 0x9 },
9307 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9308 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9309 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9310 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9311 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9312 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9313 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9314 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9316 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9317 /* The multiple "Capture Source" controls confuse alsamixer
9318 * So call somewhat different..
9320 /* .name = "Capture Source", */
9321 .name = "Input Source",
9323 .info = alc_mux_enum_info,
9324 .get = alc_mux_enum_get,
9325 .put = alc_mux_enum_put,
9330 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9331 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9332 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9333 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9334 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9335 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9337 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9342 static void alc262_dmic_automute(struct hda_codec *codec)
9344 unsigned int present;
9346 present = snd_hda_codec_read(codec, 0x18, 0,
9347 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9348 snd_hda_codec_write(codec, 0x22, 0,
9349 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9352 /* toggle speaker-output according to the hp-jack state */
9353 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9355 unsigned int present;
9358 present = snd_hda_codec_read(codec, 0x15, 0,
9359 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9360 bits = present ? 0 : PIN_OUT;
9361 snd_hda_codec_write(codec, 0x14, 0,
9362 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9367 /* unsolicited event for HP jack sensing */
9368 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9371 if ((res >> 26) == ALC880_HP_EVENT)
9372 alc262_toshiba_s06_speaker_automute(codec);
9373 if ((res >> 26) == ALC880_MIC_EVENT)
9374 alc262_dmic_automute(codec);
9378 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9380 alc262_toshiba_s06_speaker_automute(codec);
9381 alc262_dmic_automute(codec);
9384 /* mute/unmute internal speaker according to the hp jack and mute state */
9385 static void alc262_hippo_automute(struct hda_codec *codec)
9387 struct alc_spec *spec = codec->spec;
9389 unsigned int present;
9391 /* need to execute and sync at first */
9392 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9393 present = snd_hda_codec_read(codec, 0x15, 0,
9394 AC_VERB_GET_PIN_SENSE, 0);
9395 spec->jack_present = (present & 0x80000000) != 0;
9396 if (spec->jack_present) {
9397 /* mute internal speaker */
9398 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9399 HDA_AMP_MUTE, HDA_AMP_MUTE);
9401 /* unmute internal speaker if necessary */
9402 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9403 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9404 HDA_AMP_MUTE, mute);
9408 /* unsolicited event for HP jack sensing */
9409 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9412 if ((res >> 26) != ALC880_HP_EVENT)
9414 alc262_hippo_automute(codec);
9417 static void alc262_hippo1_automute(struct hda_codec *codec)
9420 unsigned int present;
9422 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9423 present = snd_hda_codec_read(codec, 0x1b, 0,
9424 AC_VERB_GET_PIN_SENSE, 0);
9425 present = (present & 0x80000000) != 0;
9427 /* mute internal speaker */
9428 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9429 HDA_AMP_MUTE, HDA_AMP_MUTE);
9431 /* unmute internal speaker if necessary */
9432 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9433 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9434 HDA_AMP_MUTE, mute);
9438 /* unsolicited event for HP jack sensing */
9439 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9442 if ((res >> 26) != ALC880_HP_EVENT)
9444 alc262_hippo1_automute(codec);
9450 * 0x16 = internal speaker
9451 * 0x18 = external mic
9454 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9455 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9456 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9460 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9462 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9463 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9467 static struct hda_verb alc262_nec_verbs[] = {
9468 /* Unmute Speaker */
9469 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9472 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9473 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9475 /* External mic to headphone */
9476 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9477 /* External mic to speaker */
9478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9484 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9485 * 0x1b = port replicator headphone out
9488 #define ALC_HP_EVENT 0x37
9490 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9491 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9493 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9494 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9498 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9499 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9504 static struct hda_input_mux alc262_fujitsu_capture_source = {
9513 static struct hda_input_mux alc262_HP_capture_source = {
9517 { "Front Mic", 0x1 },
9524 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9528 { "Front Mic", 0x2 },
9534 /* mute/unmute internal speaker according to the hp jacks and mute state */
9535 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9537 struct alc_spec *spec = codec->spec;
9540 if (force || !spec->sense_updated) {
9541 unsigned int present;
9542 /* need to execute and sync at first */
9543 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9544 /* check laptop HP jack */
9545 present = snd_hda_codec_read(codec, 0x14, 0,
9546 AC_VERB_GET_PIN_SENSE, 0);
9547 /* need to execute and sync at first */
9548 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9549 /* check docking HP jack */
9550 present |= snd_hda_codec_read(codec, 0x1b, 0,
9551 AC_VERB_GET_PIN_SENSE, 0);
9552 if (present & AC_PINSENSE_PRESENCE)
9553 spec->jack_present = 1;
9555 spec->jack_present = 0;
9556 spec->sense_updated = 1;
9558 /* unmute internal speaker only if both HPs are unplugged and
9559 * master switch is on
9561 if (spec->jack_present)
9562 mute = HDA_AMP_MUTE;
9564 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9565 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9566 HDA_AMP_MUTE, mute);
9569 /* unsolicited event for HP jack sensing */
9570 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9573 if ((res >> 26) != ALC_HP_EVENT)
9575 alc262_fujitsu_automute(codec, 1);
9578 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9580 alc262_fujitsu_automute(codec, 1);
9583 /* bind volumes of both NID 0x0c and 0x0d */
9584 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9585 .ops = &snd_hda_bind_vol,
9587 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9588 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9593 /* mute/unmute internal speaker according to the hp jack and mute state */
9594 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9596 struct alc_spec *spec = codec->spec;
9599 if (force || !spec->sense_updated) {
9600 unsigned int present_int_hp;
9601 /* need to execute and sync at first */
9602 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9603 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9604 AC_VERB_GET_PIN_SENSE, 0);
9605 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9606 spec->sense_updated = 1;
9608 if (spec->jack_present) {
9609 /* mute internal speaker */
9610 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9611 HDA_AMP_MUTE, HDA_AMP_MUTE);
9612 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9613 HDA_AMP_MUTE, HDA_AMP_MUTE);
9615 /* unmute internal speaker if necessary */
9616 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9617 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9618 HDA_AMP_MUTE, mute);
9619 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9620 HDA_AMP_MUTE, mute);
9624 /* unsolicited event for HP jack sensing */
9625 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9628 if ((res >> 26) != ALC_HP_EVENT)
9630 alc262_lenovo_3000_automute(codec, 1);
9633 /* bind hp and internal speaker mute (with plug check) */
9634 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9635 struct snd_ctl_elem_value *ucontrol)
9637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9638 long *valp = ucontrol->value.integer.value;
9641 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9643 valp ? 0 : HDA_AMP_MUTE);
9644 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9646 valp ? 0 : HDA_AMP_MUTE);
9649 alc262_fujitsu_automute(codec, 0);
9653 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9654 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9657 .name = "Master Playback Switch",
9658 .info = snd_hda_mixer_amp_switch_info,
9659 .get = snd_hda_mixer_amp_switch_get,
9660 .put = alc262_fujitsu_master_sw_put,
9661 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9665 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9666 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9670 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9671 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9672 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9676 /* bind hp and internal speaker mute (with plug check) */
9677 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9678 struct snd_ctl_elem_value *ucontrol)
9680 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9681 long *valp = ucontrol->value.integer.value;
9684 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9686 valp ? 0 : HDA_AMP_MUTE);
9689 alc262_lenovo_3000_automute(codec, 0);
9693 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9694 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9697 .name = "Master Playback Switch",
9698 .info = snd_hda_mixer_amp_switch_info,
9699 .get = snd_hda_mixer_amp_switch_get,
9700 .put = alc262_lenovo_3000_master_sw_put,
9701 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9703 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9704 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9705 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9708 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9709 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9710 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9714 /* additional init verbs for Benq laptops */
9715 static struct hda_verb alc262_EAPD_verbs[] = {
9716 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9717 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9721 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9723 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9725 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9726 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9730 /* Samsung Q1 Ultra Vista model setup */
9731 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9732 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9733 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9735 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9736 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9737 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9741 static struct hda_verb alc262_ultra_verbs[] = {
9743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9748 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9750 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9752 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9753 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9754 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9755 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9756 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9758 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9759 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9760 /* ADC, choose mic */
9761 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9768 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9770 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9774 /* mute/unmute internal speaker according to the hp jack and mute state */
9775 static void alc262_ultra_automute(struct hda_codec *codec)
9777 struct alc_spec *spec = codec->spec;
9781 /* auto-mute only when HP is used as HP */
9782 if (!spec->cur_mux[0]) {
9783 unsigned int present;
9784 /* need to execute and sync at first */
9785 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9786 present = snd_hda_codec_read(codec, 0x15, 0,
9787 AC_VERB_GET_PIN_SENSE, 0);
9788 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9789 if (spec->jack_present)
9790 mute = HDA_AMP_MUTE;
9792 /* mute/unmute internal speaker */
9793 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9794 HDA_AMP_MUTE, mute);
9795 /* mute/unmute HP */
9796 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9797 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9800 /* unsolicited event for HP jack sensing */
9801 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9804 if ((res >> 26) != ALC880_HP_EVENT)
9806 alc262_ultra_automute(codec);
9809 static struct hda_input_mux alc262_ultra_capture_source = {
9813 { "Headphone", 0x7 },
9817 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9818 struct snd_ctl_elem_value *ucontrol)
9820 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9821 struct alc_spec *spec = codec->spec;
9824 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9827 /* reprogram the HP pin as mic or HP according to the input source */
9828 snd_hda_codec_write_cache(codec, 0x15, 0,
9829 AC_VERB_SET_PIN_WIDGET_CONTROL,
9830 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9831 alc262_ultra_automute(codec); /* mute/unmute HP */
9835 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9836 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9837 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9840 .name = "Capture Source",
9841 .info = alc882_mux_enum_info,
9842 .get = alc882_mux_enum_get,
9843 .put = alc262_ultra_mux_enum_put,
9848 /* add playback controls from the parsed DAC table */
9849 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9850 const struct auto_pin_cfg *cfg)
9855 spec->multiout.num_dacs = 1; /* only use one dac */
9856 spec->multiout.dac_nids = spec->private_dac_nids;
9857 spec->multiout.dac_nids[0] = 2;
9859 nid = cfg->line_out_pins[0];
9861 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9862 "Front Playback Volume",
9863 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9866 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9867 "Front Playback Switch",
9868 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9873 nid = cfg->speaker_pins[0];
9876 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9877 "Speaker Playback Volume",
9878 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9882 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9883 "Speaker Playback Switch",
9884 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9889 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9890 "Speaker Playback Switch",
9891 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9897 nid = cfg->hp_pins[0];
9899 /* spec->multiout.hp_nid = 2; */
9901 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9902 "Headphone Playback Volume",
9903 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9907 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9908 "Headphone Playback Switch",
9909 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9914 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9915 "Headphone Playback Switch",
9916 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9925 /* identical with ALC880 */
9926 #define alc262_auto_create_analog_input_ctls \
9927 alc880_auto_create_analog_input_ctls
9930 * generic initialization of ADC, input mixers and output mixers
9932 static struct hda_verb alc262_volume_init_verbs[] = {
9934 * Unmute ADC0-2 and set the default input to mic-in
9936 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9937 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9938 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9939 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9940 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9941 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9943 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9945 * Note: PASD motherboards uses the Line In 2 as the input for
9946 * front panel mic (mic 2)
9948 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9949 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9950 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9951 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9952 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9953 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9956 * Set up output mixers (0x0c - 0x0f)
9958 /* set vol=0 to output mixers */
9959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9961 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9963 /* set up input amps for analog loopback */
9964 /* Amp Indices: DAC = 0, mixer = 1 */
9965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9967 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9968 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9972 /* FIXME: use matrix-type input source selection */
9973 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9974 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9978 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9982 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9983 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9986 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9993 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9995 * Unmute ADC0-2 and set the default input to mic-in
9997 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9999 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10000 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10001 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10004 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10006 * Note: PASD motherboards uses the Line In 2 as the input for
10007 * front panel mic (mic 2)
10009 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10019 * Set up output mixers (0x0c - 0x0e)
10021 /* set vol=0 to output mixers */
10022 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10023 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10024 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10026 /* set up input amps for analog loopback */
10027 /* Amp Indices: DAC = 0, mixer = 1 */
10028 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10029 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10032 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10035 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10037 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10039 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10042 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10043 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10045 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10046 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10047 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10048 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10049 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10053 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10054 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10055 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10056 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10059 /* FIXME: use matrix-type input source selection */
10060 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10061 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10064 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10065 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10067 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10077 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10082 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10084 * Unmute ADC0-2 and set the default input to mic-in
10086 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10089 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10090 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10091 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10093 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10095 * Note: PASD motherboards uses the Line In 2 as the input for front
10096 * panel mic (mic 2)
10098 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10108 * Set up output mixers (0x0c - 0x0e)
10110 /* set vol=0 to output mixers */
10111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10112 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10115 /* set up input amps for analog loopback */
10116 /* Amp Indices: DAC = 0, mixer = 1 */
10117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10126 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10127 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10128 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10129 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10130 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10131 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10133 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10134 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10136 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10137 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10139 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10140 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10141 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10142 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10143 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10144 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10146 /* FIXME: use matrix-type input source selection */
10147 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10148 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10152 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10154 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10155 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10157 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10158 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10160 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10161 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10162 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10163 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10165 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10170 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10171 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10173 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10178 #ifdef CONFIG_SND_HDA_POWER_SAVE
10179 #define alc262_loopbacks alc880_loopbacks
10182 /* pcm configuration: identiacal with ALC880 */
10183 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10184 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10185 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10186 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10189 * BIOS auto configuration
10191 static int alc262_parse_auto_config(struct hda_codec *codec)
10193 struct alc_spec *spec = codec->spec;
10195 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10197 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10201 if (!spec->autocfg.line_outs)
10202 return 0; /* can't find valid BIOS pin config */
10203 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10206 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10210 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10212 if (spec->autocfg.dig_out_pin)
10213 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10214 if (spec->autocfg.dig_in_pin)
10215 spec->dig_in_nid = ALC262_DIGIN_NID;
10217 if (spec->kctl_alloc)
10218 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10220 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
10221 spec->num_mux_defs = 1;
10222 spec->input_mux = &spec->private_imux;
10224 err = alc_auto_add_mic_boost(codec);
10231 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10232 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10233 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10234 #define alc262_auto_init_input_src alc882_auto_init_input_src
10237 /* init callback for auto-configuration model -- overriding the default init */
10238 static void alc262_auto_init(struct hda_codec *codec)
10240 struct alc_spec *spec = codec->spec;
10241 alc262_auto_init_multi_out(codec);
10242 alc262_auto_init_hp_out(codec);
10243 alc262_auto_init_analog_input(codec);
10244 alc262_auto_init_input_src(codec);
10245 if (spec->unsol_event)
10246 alc_sku_automute(codec);
10250 * configuration and preset
10252 static const char *alc262_models[ALC262_MODEL_LAST] = {
10253 [ALC262_BASIC] = "basic",
10254 [ALC262_HIPPO] = "hippo",
10255 [ALC262_HIPPO_1] = "hippo_1",
10256 [ALC262_FUJITSU] = "fujitsu",
10257 [ALC262_HP_BPC] = "hp-bpc",
10258 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10259 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10260 [ALC262_HP_RP5700] = "hp-rp5700",
10261 [ALC262_BENQ_ED8] = "benq",
10262 [ALC262_BENQ_T31] = "benq-t31",
10263 [ALC262_SONY_ASSAMD] = "sony-assamd",
10264 [ALC262_ULTRA] = "ultra",
10265 [ALC262_LENOVO_3000] = "lenovo-3000",
10266 [ALC262_NEC] = "nec",
10267 [ALC262_AUTO] = "auto",
10270 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10271 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10272 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10273 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10274 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10275 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10276 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10277 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10278 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10279 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10280 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10281 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10282 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10283 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10284 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10285 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10286 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10287 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10288 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10289 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10290 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10291 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10292 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10293 ALC262_HP_TC_T5735),
10294 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10295 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10296 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10297 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10298 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10299 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10300 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10301 ALC262_SONY_ASSAMD),
10302 SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
10303 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10304 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10305 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10306 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10307 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10308 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10309 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10310 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10314 static struct alc_config_preset alc262_presets[] = {
10316 .mixers = { alc262_base_mixer },
10317 .init_verbs = { alc262_init_verbs },
10318 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10319 .dac_nids = alc262_dac_nids,
10321 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10322 .channel_mode = alc262_modes,
10323 .input_mux = &alc262_capture_source,
10326 .mixers = { alc262_base_mixer },
10327 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10328 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10329 .dac_nids = alc262_dac_nids,
10331 .dig_out_nid = ALC262_DIGOUT_NID,
10332 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10333 .channel_mode = alc262_modes,
10334 .input_mux = &alc262_capture_source,
10335 .unsol_event = alc262_hippo_unsol_event,
10336 .init_hook = alc262_hippo_automute,
10338 [ALC262_HIPPO_1] = {
10339 .mixers = { alc262_hippo1_mixer },
10340 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10341 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10342 .dac_nids = alc262_dac_nids,
10344 .dig_out_nid = ALC262_DIGOUT_NID,
10345 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10346 .channel_mode = alc262_modes,
10347 .input_mux = &alc262_capture_source,
10348 .unsol_event = alc262_hippo1_unsol_event,
10349 .init_hook = alc262_hippo1_automute,
10351 [ALC262_FUJITSU] = {
10352 .mixers = { alc262_fujitsu_mixer },
10353 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10354 alc262_fujitsu_unsol_verbs },
10355 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10356 .dac_nids = alc262_dac_nids,
10358 .dig_out_nid = ALC262_DIGOUT_NID,
10359 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10360 .channel_mode = alc262_modes,
10361 .input_mux = &alc262_fujitsu_capture_source,
10362 .unsol_event = alc262_fujitsu_unsol_event,
10363 .init_hook = alc262_fujitsu_init_hook,
10365 [ALC262_HP_BPC] = {
10366 .mixers = { alc262_HP_BPC_mixer },
10367 .init_verbs = { alc262_HP_BPC_init_verbs },
10368 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10369 .dac_nids = alc262_dac_nids,
10371 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10372 .channel_mode = alc262_modes,
10373 .input_mux = &alc262_HP_capture_source,
10374 .unsol_event = alc262_hp_bpc_unsol_event,
10375 .init_hook = alc262_hp_bpc_automute,
10377 [ALC262_HP_BPC_D7000_WF] = {
10378 .mixers = { alc262_HP_BPC_WildWest_mixer },
10379 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10380 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10381 .dac_nids = alc262_dac_nids,
10383 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10384 .channel_mode = alc262_modes,
10385 .input_mux = &alc262_HP_D7000_capture_source,
10386 .unsol_event = alc262_hp_wildwest_unsol_event,
10387 .init_hook = alc262_hp_wildwest_automute,
10389 [ALC262_HP_BPC_D7000_WL] = {
10390 .mixers = { alc262_HP_BPC_WildWest_mixer,
10391 alc262_HP_BPC_WildWest_option_mixer },
10392 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10393 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10394 .dac_nids = alc262_dac_nids,
10396 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10397 .channel_mode = alc262_modes,
10398 .input_mux = &alc262_HP_D7000_capture_source,
10399 .unsol_event = alc262_hp_wildwest_unsol_event,
10400 .init_hook = alc262_hp_wildwest_automute,
10402 [ALC262_HP_TC_T5735] = {
10403 .mixers = { alc262_hp_t5735_mixer },
10404 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10405 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10406 .dac_nids = alc262_dac_nids,
10408 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10409 .channel_mode = alc262_modes,
10410 .input_mux = &alc262_capture_source,
10411 .unsol_event = alc262_hp_t5735_unsol_event,
10412 .init_hook = alc262_hp_t5735_init_hook,
10414 [ALC262_HP_RP5700] = {
10415 .mixers = { alc262_hp_rp5700_mixer },
10416 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10417 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10418 .dac_nids = alc262_dac_nids,
10419 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10420 .channel_mode = alc262_modes,
10421 .input_mux = &alc262_hp_rp5700_capture_source,
10423 [ALC262_BENQ_ED8] = {
10424 .mixers = { alc262_base_mixer },
10425 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10426 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10427 .dac_nids = alc262_dac_nids,
10429 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10430 .channel_mode = alc262_modes,
10431 .input_mux = &alc262_capture_source,
10433 [ALC262_SONY_ASSAMD] = {
10434 .mixers = { alc262_sony_mixer },
10435 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10436 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10437 .dac_nids = alc262_dac_nids,
10439 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10440 .channel_mode = alc262_modes,
10441 .input_mux = &alc262_capture_source,
10442 .unsol_event = alc262_hippo_unsol_event,
10443 .init_hook = alc262_hippo_automute,
10445 [ALC262_BENQ_T31] = {
10446 .mixers = { alc262_benq_t31_mixer },
10447 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10448 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10449 .dac_nids = alc262_dac_nids,
10451 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10452 .channel_mode = alc262_modes,
10453 .input_mux = &alc262_capture_source,
10454 .unsol_event = alc262_hippo_unsol_event,
10455 .init_hook = alc262_hippo_automute,
10458 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10459 .init_verbs = { alc262_ultra_verbs },
10460 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10461 .dac_nids = alc262_dac_nids,
10462 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10463 .channel_mode = alc262_modes,
10464 .input_mux = &alc262_ultra_capture_source,
10465 .adc_nids = alc262_adc_nids, /* ADC0 */
10466 .capsrc_nids = alc262_capsrc_nids,
10467 .num_adc_nids = 1, /* single ADC */
10468 .unsol_event = alc262_ultra_unsol_event,
10469 .init_hook = alc262_ultra_automute,
10471 [ALC262_LENOVO_3000] = {
10472 .mixers = { alc262_lenovo_3000_mixer },
10473 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10474 alc262_lenovo_3000_unsol_verbs },
10475 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10476 .dac_nids = alc262_dac_nids,
10478 .dig_out_nid = ALC262_DIGOUT_NID,
10479 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10480 .channel_mode = alc262_modes,
10481 .input_mux = &alc262_fujitsu_capture_source,
10482 .unsol_event = alc262_lenovo_3000_unsol_event,
10485 .mixers = { alc262_nec_mixer },
10486 .init_verbs = { alc262_nec_verbs },
10487 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10488 .dac_nids = alc262_dac_nids,
10490 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10491 .channel_mode = alc262_modes,
10492 .input_mux = &alc262_capture_source,
10494 [ALC262_TOSHIBA_S06] = {
10495 .mixers = { alc262_toshiba_s06_mixer },
10496 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10497 alc262_eapd_verbs },
10498 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10499 .capsrc_nids = alc262_dmic_capsrc_nids,
10500 .dac_nids = alc262_dac_nids,
10501 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10502 .dig_out_nid = ALC262_DIGOUT_NID,
10503 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10504 .channel_mode = alc262_modes,
10505 .input_mux = &alc262_dmic_capture_source,
10506 .unsol_event = alc262_toshiba_s06_unsol_event,
10507 .init_hook = alc262_toshiba_s06_init_hook,
10511 static int patch_alc262(struct hda_codec *codec)
10513 struct alc_spec *spec;
10517 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10521 codec->spec = spec;
10523 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10528 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10529 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10530 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10531 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10535 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10537 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10541 if (board_config < 0) {
10542 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10543 "trying auto-probe from BIOS...\n");
10544 board_config = ALC262_AUTO;
10547 if (board_config == ALC262_AUTO) {
10548 /* automatic parse from the BIOS config */
10549 err = alc262_parse_auto_config(codec);
10555 "hda_codec: Cannot set up configuration "
10556 "from BIOS. Using base mode...\n");
10557 board_config = ALC262_BASIC;
10561 if (board_config != ALC262_AUTO)
10562 setup_preset(spec, &alc262_presets[board_config]);
10564 spec->stream_name_analog = "ALC262 Analog";
10565 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10566 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10568 spec->stream_name_digital = "ALC262 Digital";
10569 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10570 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10572 if (!spec->adc_nids && spec->input_mux) {
10573 /* check whether NID 0x07 is valid */
10574 unsigned int wcap = get_wcaps(codec, 0x07);
10577 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10578 if (wcap != AC_WID_AUD_IN) {
10579 spec->adc_nids = alc262_adc_nids_alt;
10580 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10581 spec->capsrc_nids = alc262_capsrc_nids_alt;
10582 spec->mixers[spec->num_mixers] =
10583 alc262_capture_alt_mixer;
10584 spec->num_mixers++;
10586 spec->adc_nids = alc262_adc_nids;
10587 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10588 spec->capsrc_nids = alc262_capsrc_nids;
10589 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10590 spec->num_mixers++;
10594 spec->vmaster_nid = 0x0c;
10596 codec->patch_ops = alc_patch_ops;
10597 if (board_config == ALC262_AUTO)
10598 spec->init_hook = alc262_auto_init;
10599 #ifdef CONFIG_SND_HDA_POWER_SAVE
10600 if (!spec->loopback.amplist)
10601 spec->loopback.amplist = alc262_loopbacks;
10608 * ALC268 channel source setting (2 channel)
10610 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10611 #define alc268_modes alc260_modes
10613 static hda_nid_t alc268_dac_nids[2] = {
10618 static hda_nid_t alc268_adc_nids[2] = {
10623 static hda_nid_t alc268_adc_nids_alt[1] = {
10628 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10630 static struct snd_kcontrol_new alc268_base_mixer[] = {
10631 /* output mixer control */
10632 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10633 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10634 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10636 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10637 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10638 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10642 /* bind Beep switches of both NID 0x0f and 0x10 */
10643 static struct hda_bind_ctls alc268_bind_beep_sw = {
10644 .ops = &snd_hda_bind_sw,
10646 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10647 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10652 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10653 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10654 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10658 static struct hda_verb alc268_eapd_verbs[] = {
10659 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10660 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10664 /* Toshiba specific */
10665 #define alc268_toshiba_automute alc262_hippo_automute
10667 static struct hda_verb alc268_toshiba_verbs[] = {
10668 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10672 static struct hda_input_mux alc268_acer_lc_capture_source = {
10680 /* Acer specific */
10681 /* bind volumes of both NID 0x02 and 0x03 */
10682 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10683 .ops = &snd_hda_bind_vol,
10685 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10686 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10691 /* mute/unmute internal speaker according to the hp jack and mute state */
10692 static void alc268_acer_automute(struct hda_codec *codec, int force)
10694 struct alc_spec *spec = codec->spec;
10697 if (force || !spec->sense_updated) {
10698 unsigned int present;
10699 present = snd_hda_codec_read(codec, 0x14, 0,
10700 AC_VERB_GET_PIN_SENSE, 0);
10701 spec->jack_present = (present & 0x80000000) != 0;
10702 spec->sense_updated = 1;
10704 if (spec->jack_present)
10705 mute = HDA_AMP_MUTE; /* mute internal speaker */
10706 else /* unmute internal speaker if necessary */
10707 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10708 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10709 HDA_AMP_MUTE, mute);
10713 /* bind hp and internal speaker mute (with plug check) */
10714 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10715 struct snd_ctl_elem_value *ucontrol)
10717 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10718 long *valp = ucontrol->value.integer.value;
10721 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10723 valp[0] ? 0 : HDA_AMP_MUTE);
10724 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10726 valp[1] ? 0 : HDA_AMP_MUTE);
10728 alc268_acer_automute(codec, 0);
10732 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10733 /* output mixer control */
10734 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10736 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10737 .name = "Master Playback Switch",
10738 .info = snd_hda_mixer_amp_switch_info,
10739 .get = snd_hda_mixer_amp_switch_get,
10740 .put = alc268_acer_master_sw_put,
10741 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10743 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10747 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10748 /* output mixer control */
10749 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10752 .name = "Master Playback Switch",
10753 .info = snd_hda_mixer_amp_switch_info,
10754 .get = snd_hda_mixer_amp_switch_get,
10755 .put = alc268_acer_master_sw_put,
10756 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10758 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10759 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10760 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10764 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10765 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10767 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10768 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10769 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10770 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10774 static struct hda_verb alc268_acer_verbs[] = {
10775 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10776 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10777 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10778 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10779 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10781 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10785 /* unsolicited event for HP jack sensing */
10786 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10789 if ((res >> 26) != ALC880_HP_EVENT)
10791 alc268_toshiba_automute(codec);
10794 static void alc268_acer_unsol_event(struct hda_codec *codec,
10797 if ((res >> 26) != ALC880_HP_EVENT)
10799 alc268_acer_automute(codec, 1);
10802 static void alc268_acer_init_hook(struct hda_codec *codec)
10804 alc268_acer_automute(codec, 1);
10807 /* toggle speaker-output according to the hp-jack state */
10808 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10810 unsigned int present;
10811 unsigned char bits;
10813 present = snd_hda_codec_read(codec, 0x15, 0,
10814 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10815 bits = present ? AMP_IN_MUTE(0) : 0;
10816 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10817 AMP_IN_MUTE(0), bits);
10818 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10819 AMP_IN_MUTE(0), bits);
10823 static void alc268_acer_mic_automute(struct hda_codec *codec)
10825 unsigned int present;
10827 present = snd_hda_codec_read(codec, 0x18, 0,
10828 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10829 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10830 present ? 0x0 : 0x6);
10833 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10836 if ((res >> 26) == ALC880_HP_EVENT)
10837 alc268_aspire_one_speaker_automute(codec);
10838 if ((res >> 26) == ALC880_MIC_EVENT)
10839 alc268_acer_mic_automute(codec);
10842 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10844 alc268_aspire_one_speaker_automute(codec);
10845 alc268_acer_mic_automute(codec);
10848 static struct snd_kcontrol_new alc268_dell_mixer[] = {
10849 /* output mixer control */
10850 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10851 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10855 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10859 static struct hda_verb alc268_dell_verbs[] = {
10860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10866 /* mute/unmute internal speaker according to the hp jack and mute state */
10867 static void alc268_dell_automute(struct hda_codec *codec)
10869 unsigned int present;
10872 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10873 if (present & 0x80000000)
10874 mute = HDA_AMP_MUTE;
10876 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10877 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10878 HDA_AMP_MUTE, mute);
10881 static void alc268_dell_unsol_event(struct hda_codec *codec,
10884 if ((res >> 26) != ALC880_HP_EVENT)
10886 alc268_dell_automute(codec);
10889 #define alc268_dell_init_hook alc268_dell_automute
10891 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10892 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10893 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10894 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10896 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10897 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10898 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10899 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10903 static struct hda_verb alc267_quanta_il1_verbs[] = {
10904 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10905 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10909 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10911 unsigned int present;
10913 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10914 & AC_PINSENSE_PRESENCE;
10915 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10916 present ? 0 : PIN_OUT);
10919 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10921 unsigned int present;
10923 present = snd_hda_codec_read(codec, 0x18, 0,
10924 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10925 snd_hda_codec_write(codec, 0x23, 0,
10926 AC_VERB_SET_CONNECT_SEL,
10927 present ? 0x00 : 0x01);
10930 static void alc267_quanta_il1_automute(struct hda_codec *codec)
10932 alc267_quanta_il1_hp_automute(codec);
10933 alc267_quanta_il1_mic_automute(codec);
10936 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10939 switch (res >> 26) {
10940 case ALC880_HP_EVENT:
10941 alc267_quanta_il1_hp_automute(codec);
10943 case ALC880_MIC_EVENT:
10944 alc267_quanta_il1_mic_automute(codec);
10950 * generic initialization of ADC, input mixers and output mixers
10952 static struct hda_verb alc268_base_init_verbs[] = {
10953 /* Unmute DAC0-1 and set vol = 0 */
10954 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10955 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10956 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10957 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10958 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10959 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10962 * Set up output mixers (0x0c - 0x0e)
10964 /* set vol=0 to output mixers */
10965 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10966 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10968 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10970 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10971 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10973 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10974 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10975 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10976 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10977 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10978 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10979 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10980 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10982 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10984 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10985 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10986 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10987 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10988 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10990 /* set PCBEEP vol = 0, mute connections */
10991 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10992 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10993 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10995 /* Unmute Selector 23h,24h and set the default input to mic-in */
10997 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10998 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10999 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11000 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11006 * generic initialization of ADC, input mixers and output mixers
11008 static struct hda_verb alc268_volume_init_verbs[] = {
11009 /* set output DAC */
11010 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11011 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11012 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11013 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11015 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11016 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11017 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11018 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11019 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11023 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11024 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11025 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11027 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11028 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11029 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11030 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11032 /* set PCBEEP vol = 0, mute connections */
11033 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11034 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11035 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11040 #define alc268_mux_enum_info alc_mux_enum_info
11041 #define alc268_mux_enum_get alc_mux_enum_get
11042 #define alc268_mux_enum_put alc_mux_enum_put
11044 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11045 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11046 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11049 /* The multiple "Capture Source" controls confuse alsamixer
11050 * So call somewhat different..
11052 /* .name = "Capture Source", */
11053 .name = "Input Source",
11055 .info = alc268_mux_enum_info,
11056 .get = alc268_mux_enum_get,
11057 .put = alc268_mux_enum_put,
11062 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11063 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11064 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11065 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11066 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11068 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11069 /* The multiple "Capture Source" controls confuse alsamixer
11070 * So call somewhat different..
11072 /* .name = "Capture Source", */
11073 .name = "Input Source",
11075 .info = alc268_mux_enum_info,
11076 .get = alc268_mux_enum_get,
11077 .put = alc268_mux_enum_put,
11082 static struct hda_input_mux alc268_capture_source = {
11086 { "Front Mic", 0x1 },
11092 static struct hda_input_mux alc268_acer_capture_source = {
11096 { "Internal Mic", 0x6 },
11101 #ifdef CONFIG_SND_DEBUG
11102 static struct snd_kcontrol_new alc268_test_mixer[] = {
11103 /* Volume widgets */
11104 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11105 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11106 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11107 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11108 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11109 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11110 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11111 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11112 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11113 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11114 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11115 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11116 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11117 /* The below appears problematic on some hardwares */
11118 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11119 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11120 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11121 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11122 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11124 /* Modes for retasking pin widgets */
11125 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11126 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11127 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11128 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11130 /* Controls for GPIO pins, assuming they are configured as outputs */
11131 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11132 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11133 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11134 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11136 /* Switches to allow the digital SPDIF output pin to be enabled.
11137 * The ALC268 does not have an SPDIF input.
11139 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11141 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11142 * this output to turn on an external amplifier.
11144 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11145 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11151 /* create input playback/capture controls for the given pin */
11152 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11153 const char *ctlname, int idx)
11158 sprintf(name, "%s Playback Volume", ctlname);
11160 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11161 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11165 } else if (nid == 0x15) {
11166 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11167 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11173 sprintf(name, "%s Playback Switch", ctlname);
11174 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11175 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11181 /* add playback controls from the parsed DAC table */
11182 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11183 const struct auto_pin_cfg *cfg)
11188 spec->multiout.num_dacs = 2; /* only use one dac */
11189 spec->multiout.dac_nids = spec->private_dac_nids;
11190 spec->multiout.dac_nids[0] = 2;
11191 spec->multiout.dac_nids[1] = 3;
11193 nid = cfg->line_out_pins[0];
11195 alc268_new_analog_output(spec, nid, "Front", 0);
11197 nid = cfg->speaker_pins[0];
11199 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11200 "Speaker Playback Volume",
11201 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11205 nid = cfg->hp_pins[0];
11207 alc268_new_analog_output(spec, nid, "Headphone", 0);
11209 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11211 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11212 "Mono Playback Switch",
11213 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11220 /* create playback/capture controls for input pins */
11221 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11222 const struct auto_pin_cfg *cfg)
11224 struct hda_input_mux *imux = &spec->private_imux;
11227 for (i = 0; i < AUTO_PIN_LAST; i++) {
11228 switch(cfg->input_pins[i]) {
11230 idx1 = 0; /* Mic 1 */
11233 idx1 = 1; /* Mic 2 */
11236 idx1 = 2; /* Line In */
11243 idx1 = 6; /* digital mics */
11248 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11249 imux->items[imux->num_items].index = idx1;
11255 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11257 struct alc_spec *spec = codec->spec;
11258 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11259 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11260 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11261 unsigned int dac_vol1, dac_vol2;
11264 snd_hda_codec_write(codec, speaker_nid, 0,
11265 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11266 snd_hda_codec_write(codec, 0x0f, 0,
11267 AC_VERB_SET_AMP_GAIN_MUTE,
11269 snd_hda_codec_write(codec, 0x10, 0,
11270 AC_VERB_SET_AMP_GAIN_MUTE,
11273 snd_hda_codec_write(codec, 0x0f, 0,
11274 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11275 snd_hda_codec_write(codec, 0x10, 0,
11276 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11279 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11280 if (line_nid == 0x14)
11281 dac_vol2 = AMP_OUT_ZERO;
11282 else if (line_nid == 0x15)
11283 dac_vol1 = AMP_OUT_ZERO;
11284 if (hp_nid == 0x14)
11285 dac_vol2 = AMP_OUT_ZERO;
11286 else if (hp_nid == 0x15)
11287 dac_vol1 = AMP_OUT_ZERO;
11288 if (line_nid != 0x16 || hp_nid != 0x16 ||
11289 spec->autocfg.line_out_pins[1] != 0x16 ||
11290 spec->autocfg.line_out_pins[2] != 0x16)
11291 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11293 snd_hda_codec_write(codec, 0x02, 0,
11294 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11295 snd_hda_codec_write(codec, 0x03, 0,
11296 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11299 /* pcm configuration: identiacal with ALC880 */
11300 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11301 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11302 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11303 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11306 * BIOS auto configuration
11308 static int alc268_parse_auto_config(struct hda_codec *codec)
11310 struct alc_spec *spec = codec->spec;
11312 static hda_nid_t alc268_ignore[] = { 0 };
11314 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11318 if (!spec->autocfg.line_outs)
11319 return 0; /* can't find valid BIOS pin config */
11321 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11324 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11328 spec->multiout.max_channels = 2;
11330 /* digital only support output */
11331 if (spec->autocfg.dig_out_pin)
11332 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11334 if (spec->kctl_alloc)
11335 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11337 if (spec->autocfg.speaker_pins[0] != 0x1d)
11338 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11340 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11341 spec->num_mux_defs = 1;
11342 spec->input_mux = &spec->private_imux;
11344 err = alc_auto_add_mic_boost(codec);
11351 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11352 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11353 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11355 /* init callback for auto-configuration model -- overriding the default init */
11356 static void alc268_auto_init(struct hda_codec *codec)
11358 struct alc_spec *spec = codec->spec;
11359 alc268_auto_init_multi_out(codec);
11360 alc268_auto_init_hp_out(codec);
11361 alc268_auto_init_mono_speaker_out(codec);
11362 alc268_auto_init_analog_input(codec);
11363 if (spec->unsol_event)
11364 alc_sku_automute(codec);
11368 * configuration and preset
11370 static const char *alc268_models[ALC268_MODEL_LAST] = {
11371 [ALC267_QUANTA_IL1] = "quanta-il1",
11372 [ALC268_3ST] = "3stack",
11373 [ALC268_TOSHIBA] = "toshiba",
11374 [ALC268_ACER] = "acer",
11375 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11376 [ALC268_DELL] = "dell",
11377 [ALC268_ZEPTO] = "zepto",
11378 #ifdef CONFIG_SND_DEBUG
11379 [ALC268_TEST] = "test",
11381 [ALC268_AUTO] = "auto",
11384 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11385 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11386 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11387 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11388 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11389 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11390 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11391 ALC268_ACER_ASPIRE_ONE),
11392 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11393 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11394 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11395 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11396 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11397 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11398 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11399 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11400 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11404 static struct alc_config_preset alc268_presets[] = {
11405 [ALC267_QUANTA_IL1] = {
11406 .mixers = { alc267_quanta_il1_mixer },
11407 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11408 alc267_quanta_il1_verbs },
11409 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11410 .dac_nids = alc268_dac_nids,
11411 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11412 .adc_nids = alc268_adc_nids_alt,
11414 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11415 .channel_mode = alc268_modes,
11416 .input_mux = &alc268_capture_source,
11417 .unsol_event = alc267_quanta_il1_unsol_event,
11418 .init_hook = alc267_quanta_il1_automute,
11421 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11422 alc268_beep_mixer },
11423 .init_verbs = { alc268_base_init_verbs },
11424 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11425 .dac_nids = alc268_dac_nids,
11426 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11427 .adc_nids = alc268_adc_nids_alt,
11428 .capsrc_nids = alc268_capsrc_nids,
11430 .dig_out_nid = ALC268_DIGOUT_NID,
11431 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11432 .channel_mode = alc268_modes,
11433 .input_mux = &alc268_capture_source,
11435 [ALC268_TOSHIBA] = {
11436 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11437 alc268_beep_mixer },
11438 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11439 alc268_toshiba_verbs },
11440 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11441 .dac_nids = alc268_dac_nids,
11442 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11443 .adc_nids = alc268_adc_nids_alt,
11444 .capsrc_nids = alc268_capsrc_nids,
11446 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11447 .channel_mode = alc268_modes,
11448 .input_mux = &alc268_capture_source,
11449 .unsol_event = alc268_toshiba_unsol_event,
11450 .init_hook = alc268_toshiba_automute,
11453 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11454 alc268_beep_mixer },
11455 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11456 alc268_acer_verbs },
11457 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11458 .dac_nids = alc268_dac_nids,
11459 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11460 .adc_nids = alc268_adc_nids_alt,
11461 .capsrc_nids = alc268_capsrc_nids,
11463 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11464 .channel_mode = alc268_modes,
11465 .input_mux = &alc268_acer_capture_source,
11466 .unsol_event = alc268_acer_unsol_event,
11467 .init_hook = alc268_acer_init_hook,
11469 [ALC268_ACER_ASPIRE_ONE] = {
11470 .mixers = { alc268_acer_aspire_one_mixer,
11471 alc268_capture_alt_mixer },
11472 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11473 alc268_acer_aspire_one_verbs },
11474 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11475 .dac_nids = alc268_dac_nids,
11476 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11477 .adc_nids = alc268_adc_nids_alt,
11478 .capsrc_nids = alc268_capsrc_nids,
11480 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11481 .channel_mode = alc268_modes,
11482 .input_mux = &alc268_acer_lc_capture_source,
11483 .unsol_event = alc268_acer_lc_unsol_event,
11484 .init_hook = alc268_acer_lc_init_hook,
11487 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11488 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11489 alc268_dell_verbs },
11490 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11491 .dac_nids = alc268_dac_nids,
11493 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11494 .channel_mode = alc268_modes,
11495 .unsol_event = alc268_dell_unsol_event,
11496 .init_hook = alc268_dell_init_hook,
11497 .input_mux = &alc268_capture_source,
11500 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11501 alc268_beep_mixer },
11502 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11503 alc268_toshiba_verbs },
11504 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11505 .dac_nids = alc268_dac_nids,
11506 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11507 .adc_nids = alc268_adc_nids_alt,
11508 .capsrc_nids = alc268_capsrc_nids,
11510 .dig_out_nid = ALC268_DIGOUT_NID,
11511 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11512 .channel_mode = alc268_modes,
11513 .input_mux = &alc268_capture_source,
11514 .unsol_event = alc268_toshiba_unsol_event,
11515 .init_hook = alc268_toshiba_automute
11517 #ifdef CONFIG_SND_DEBUG
11519 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11520 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11521 alc268_volume_init_verbs },
11522 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11523 .dac_nids = alc268_dac_nids,
11524 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11525 .adc_nids = alc268_adc_nids_alt,
11526 .capsrc_nids = alc268_capsrc_nids,
11528 .dig_out_nid = ALC268_DIGOUT_NID,
11529 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11530 .channel_mode = alc268_modes,
11531 .input_mux = &alc268_capture_source,
11536 static int patch_alc268(struct hda_codec *codec)
11538 struct alc_spec *spec;
11542 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11546 codec->spec = spec;
11548 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11552 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11553 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11554 "trying auto-probe from BIOS...\n");
11555 board_config = ALC268_AUTO;
11558 if (board_config == ALC268_AUTO) {
11559 /* automatic parse from the BIOS config */
11560 err = alc268_parse_auto_config(codec);
11566 "hda_codec: Cannot set up configuration "
11567 "from BIOS. Using base mode...\n");
11568 board_config = ALC268_3ST;
11572 if (board_config != ALC268_AUTO)
11573 setup_preset(spec, &alc268_presets[board_config]);
11575 if (codec->vendor_id == 0x10ec0267) {
11576 spec->stream_name_analog = "ALC267 Analog";
11577 spec->stream_name_digital = "ALC267 Digital";
11579 spec->stream_name_analog = "ALC268 Analog";
11580 spec->stream_name_digital = "ALC268 Digital";
11583 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11584 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11585 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11587 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11589 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11590 /* override the amp caps for beep generator */
11591 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11592 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11593 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11594 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11595 (0 << AC_AMPCAP_MUTE_SHIFT));
11597 if (!spec->adc_nids && spec->input_mux) {
11598 /* check whether NID 0x07 is valid */
11599 unsigned int wcap = get_wcaps(codec, 0x07);
11603 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11604 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11605 spec->adc_nids = alc268_adc_nids_alt;
11606 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11607 spec->mixers[spec->num_mixers] =
11608 alc268_capture_alt_mixer;
11609 spec->num_mixers++;
11611 spec->adc_nids = alc268_adc_nids;
11612 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11613 spec->mixers[spec->num_mixers] =
11614 alc268_capture_mixer;
11615 spec->num_mixers++;
11617 spec->capsrc_nids = alc268_capsrc_nids;
11618 /* set default input source */
11619 for (i = 0; i < spec->num_adc_nids; i++)
11620 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11621 0, AC_VERB_SET_CONNECT_SEL,
11622 spec->input_mux->items[0].index);
11625 spec->vmaster_nid = 0x02;
11627 codec->patch_ops = alc_patch_ops;
11628 if (board_config == ALC268_AUTO)
11629 spec->init_hook = alc268_auto_init;
11635 * ALC269 channel source setting (2 channel)
11637 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11639 #define alc269_dac_nids alc260_dac_nids
11641 static hda_nid_t alc269_adc_nids[1] = {
11646 static hda_nid_t alc269_capsrc_nids[1] = {
11650 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11654 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11662 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11670 #define alc269_modes alc260_modes
11671 #define alc269_capture_source alc880_lg_lw_capture_source
11673 static struct snd_kcontrol_new alc269_base_mixer[] = {
11674 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11675 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11676 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11677 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11680 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11681 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11682 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11683 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11684 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11685 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11686 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11687 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11691 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11692 /* output mixer control */
11693 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11695 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11696 .name = "Master Playback Switch",
11697 .info = snd_hda_mixer_amp_switch_info,
11698 .get = snd_hda_mixer_amp_switch_get,
11699 .put = alc268_acer_master_sw_put,
11700 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11704 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11705 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11706 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11707 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11708 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11709 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11713 /* bind volumes of both NID 0x0c and 0x0d */
11714 static struct hda_bind_ctls alc269_epc_bind_vol = {
11715 .ops = &snd_hda_bind_vol,
11717 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11718 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11723 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11724 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11725 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11726 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11730 /* capture mixer elements */
11731 static struct snd_kcontrol_new alc269_capture_mixer[] = {
11732 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11733 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11736 /* The multiple "Capture Source" controls confuse alsamixer
11737 * So call somewhat different..
11739 /* .name = "Capture Source", */
11740 .name = "Input Source",
11742 .info = alc_mux_enum_info,
11743 .get = alc_mux_enum_get,
11744 .put = alc_mux_enum_put,
11749 /* capture mixer elements */
11750 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11751 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11752 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11757 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11758 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11759 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11763 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11765 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11767 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11768 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11769 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11773 /* toggle speaker-output according to the hp-jack state */
11774 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11776 unsigned int present;
11777 unsigned char bits;
11779 present = snd_hda_codec_read(codec, 0x15, 0,
11780 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11781 bits = present ? AMP_IN_MUTE(0) : 0;
11782 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11783 AMP_IN_MUTE(0), bits);
11784 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11785 AMP_IN_MUTE(0), bits);
11787 snd_hda_codec_write(codec, 0x20, 0,
11788 AC_VERB_SET_COEF_INDEX, 0x0c);
11789 snd_hda_codec_write(codec, 0x20, 0,
11790 AC_VERB_SET_PROC_COEF, 0x680);
11792 snd_hda_codec_write(codec, 0x20, 0,
11793 AC_VERB_SET_COEF_INDEX, 0x0c);
11794 snd_hda_codec_write(codec, 0x20, 0,
11795 AC_VERB_SET_PROC_COEF, 0x480);
11798 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11800 unsigned int present;
11802 present = snd_hda_codec_read(codec, 0x18, 0,
11803 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11804 snd_hda_codec_write(codec, 0x23, 0,
11805 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11808 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11811 if ((res >> 26) == ALC880_HP_EVENT)
11812 alc269_quanta_fl1_speaker_automute(codec);
11813 if ((res >> 26) == ALC880_MIC_EVENT)
11814 alc269_quanta_fl1_mic_automute(codec);
11817 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11819 alc269_quanta_fl1_speaker_automute(codec);
11820 alc269_quanta_fl1_mic_automute(codec);
11823 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11824 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11825 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11826 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11828 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11829 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11830 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11834 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11835 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11836 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11837 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11838 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11839 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11840 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11844 /* toggle speaker-output according to the hp-jack state */
11845 static void alc269_speaker_automute(struct hda_codec *codec)
11847 unsigned int present;
11848 unsigned char bits;
11850 present = snd_hda_codec_read(codec, 0x15, 0,
11851 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11852 bits = present ? AMP_IN_MUTE(0) : 0;
11853 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11854 AMP_IN_MUTE(0), bits);
11855 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11856 AMP_IN_MUTE(0), bits);
11859 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11861 unsigned int present;
11863 present = snd_hda_codec_read(codec, 0x18, 0,
11864 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11865 snd_hda_codec_write(codec, 0x23, 0,
11866 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
11869 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11871 unsigned int present;
11873 present = snd_hda_codec_read(codec, 0x18, 0,
11874 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11875 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11876 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11877 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11878 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11881 /* unsolicited event for HP jack sensing */
11882 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11885 if ((res >> 26) == ALC880_HP_EVENT)
11886 alc269_speaker_automute(codec);
11888 if ((res >> 26) == ALC880_MIC_EVENT)
11889 alc269_eeepc_dmic_automute(codec);
11892 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11894 alc269_speaker_automute(codec);
11895 alc269_eeepc_dmic_automute(codec);
11898 /* unsolicited event for HP jack sensing */
11899 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11902 if ((res >> 26) == ALC880_HP_EVENT)
11903 alc269_speaker_automute(codec);
11905 if ((res >> 26) == ALC880_MIC_EVENT)
11906 alc269_eeepc_amic_automute(codec);
11909 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11911 alc269_speaker_automute(codec);
11912 alc269_eeepc_amic_automute(codec);
11916 * generic initialization of ADC, input mixers and output mixers
11918 static struct hda_verb alc269_init_verbs[] = {
11920 * Unmute ADC0 and set the default input to mic-in
11922 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11924 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11925 * analog-loopback mixer widget
11926 * Note: PASD motherboards uses the Line In 2 as the input for
11927 * front panel mic (mic 2)
11929 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11933 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11934 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11937 * Set up output mixers (0x0c - 0x0e)
11939 /* set vol=0 to output mixers */
11940 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11941 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11943 /* set up input amps for analog loopback */
11944 /* Amp Indices: DAC = 0, mixer = 1 */
11945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11946 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11947 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11948 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11949 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11950 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11954 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11955 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11956 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11958 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11960 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11961 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11962 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11963 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11964 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11965 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11966 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11968 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11969 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11971 /* FIXME: use matrix-type input source selection */
11972 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11973 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11980 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11981 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11985 /* add playback controls from the parsed DAC table */
11986 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11987 const struct auto_pin_cfg *cfg)
11992 spec->multiout.num_dacs = 1; /* only use one dac */
11993 spec->multiout.dac_nids = spec->private_dac_nids;
11994 spec->multiout.dac_nids[0] = 2;
11996 nid = cfg->line_out_pins[0];
11998 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11999 "Front Playback Volume",
12000 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12003 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12004 "Front Playback Switch",
12005 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12010 nid = cfg->speaker_pins[0];
12012 if (!cfg->line_out_pins[0]) {
12013 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12014 "Speaker Playback Volume",
12015 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12021 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12022 "Speaker Playback Switch",
12023 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12028 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12029 "Speaker Playback Switch",
12030 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12036 nid = cfg->hp_pins[0];
12038 /* spec->multiout.hp_nid = 2; */
12039 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12040 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12041 "Headphone Playback Volume",
12042 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12048 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12049 "Headphone Playback Switch",
12050 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12055 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12056 "Headphone Playback Switch",
12057 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12066 #define alc269_auto_create_analog_input_ctls \
12067 alc880_auto_create_analog_input_ctls
12069 #ifdef CONFIG_SND_HDA_POWER_SAVE
12070 #define alc269_loopbacks alc880_loopbacks
12073 /* pcm configuration: identiacal with ALC880 */
12074 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12075 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12076 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12077 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12080 * BIOS auto configuration
12082 static int alc269_parse_auto_config(struct hda_codec *codec)
12084 struct alc_spec *spec = codec->spec;
12086 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12088 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12093 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12096 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12100 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12102 if (spec->autocfg.dig_out_pin)
12103 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12105 if (spec->kctl_alloc)
12106 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12108 /* create a beep mixer control if the pin 0x1d isn't assigned */
12109 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12110 if (spec->autocfg.input_pins[i] == 0x1d)
12112 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12113 spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12115 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12116 spec->num_mux_defs = 1;
12117 spec->input_mux = &spec->private_imux;
12118 /* set default input source */
12119 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12120 0, AC_VERB_SET_CONNECT_SEL,
12121 spec->input_mux->items[0].index);
12123 err = alc_auto_add_mic_boost(codec);
12127 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12128 spec->num_mixers++;
12133 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12134 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12135 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12138 /* init callback for auto-configuration model -- overriding the default init */
12139 static void alc269_auto_init(struct hda_codec *codec)
12141 struct alc_spec *spec = codec->spec;
12142 alc269_auto_init_multi_out(codec);
12143 alc269_auto_init_hp_out(codec);
12144 alc269_auto_init_analog_input(codec);
12145 if (spec->unsol_event)
12146 alc_sku_automute(codec);
12150 * configuration and preset
12152 static const char *alc269_models[ALC269_MODEL_LAST] = {
12153 [ALC269_BASIC] = "basic",
12154 [ALC269_QUANTA_FL1] = "Quanta",
12155 [ALC269_ASUS_EEEPC_P901] = "Asus_Epc_Dmic"
12158 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12159 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12160 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12161 ALC269_ASUS_EEEPC_P703),
12162 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12163 ALC269_ASUS_EEEPC_P901),
12164 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12165 ALC269_ASUS_EEEPC_P901),
12169 static struct alc_config_preset alc269_presets[] = {
12171 .mixers = { alc269_base_mixer, alc269_capture_mixer },
12172 .init_verbs = { alc269_init_verbs },
12173 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12174 .dac_nids = alc269_dac_nids,
12176 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12177 .channel_mode = alc269_modes,
12178 .input_mux = &alc269_capture_source,
12180 [ALC269_QUANTA_FL1] = {
12181 .mixers = { alc269_quanta_fl1_mixer },
12182 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12183 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12184 .dac_nids = alc269_dac_nids,
12186 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12187 .channel_mode = alc269_modes,
12188 .input_mux = &alc269_capture_source,
12189 .unsol_event = alc269_quanta_fl1_unsol_event,
12190 .init_hook = alc269_quanta_fl1_init_hook,
12192 [ALC269_ASUS_EEEPC_P703] = {
12193 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12194 .init_verbs = { alc269_init_verbs,
12195 alc269_eeepc_amic_init_verbs },
12196 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12197 .dac_nids = alc269_dac_nids,
12199 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12200 .channel_mode = alc269_modes,
12201 .input_mux = &alc269_eeepc_amic_capture_source,
12202 .unsol_event = alc269_eeepc_amic_unsol_event,
12203 .init_hook = alc269_eeepc_amic_inithook,
12205 [ALC269_ASUS_EEEPC_P901] = {
12206 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12207 .init_verbs = { alc269_init_verbs,
12208 alc269_eeepc_dmic_init_verbs },
12209 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12210 .dac_nids = alc269_dac_nids,
12212 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12213 .channel_mode = alc269_modes,
12214 .input_mux = &alc269_eeepc_dmic_capture_source,
12215 .unsol_event = alc269_eeepc_dmic_unsol_event,
12216 .init_hook = alc269_eeepc_dmic_inithook,
12220 static int patch_alc269(struct hda_codec *codec)
12222 struct alc_spec *spec;
12226 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12230 codec->spec = spec;
12232 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12234 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12238 if (board_config < 0) {
12239 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12240 "trying auto-probe from BIOS...\n");
12241 board_config = ALC269_AUTO;
12244 if (board_config == ALC269_AUTO) {
12245 /* automatic parse from the BIOS config */
12246 err = alc269_parse_auto_config(codec);
12252 "hda_codec: Cannot set up configuration "
12253 "from BIOS. Using base mode...\n");
12254 board_config = ALC269_BASIC;
12258 if (board_config != ALC269_AUTO)
12259 setup_preset(spec, &alc269_presets[board_config]);
12261 spec->stream_name_analog = "ALC269 Analog";
12262 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12263 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12265 spec->stream_name_digital = "ALC269 Digital";
12266 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12267 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12269 spec->adc_nids = alc269_adc_nids;
12270 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12271 spec->capsrc_nids = alc269_capsrc_nids;
12273 codec->patch_ops = alc_patch_ops;
12274 if (board_config == ALC269_AUTO)
12275 spec->init_hook = alc269_auto_init;
12276 #ifdef CONFIG_SND_HDA_POWER_SAVE
12277 if (!spec->loopback.amplist)
12278 spec->loopback.amplist = alc269_loopbacks;
12285 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12289 * set the path ways for 2 channel output
12290 * need to set the codec line out and mic 1 pin widgets to inputs
12292 static struct hda_verb alc861_threestack_ch2_init[] = {
12293 /* set pin widget 1Ah (line in) for input */
12294 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12295 /* set pin widget 18h (mic1/2) for input, for mic also enable
12298 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12300 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12302 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12303 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12309 * need to set the codec line out and mic 1 pin widgets to outputs
12311 static struct hda_verb alc861_threestack_ch6_init[] = {
12312 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12313 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12314 /* set pin widget 18h (mic1) for output (CLFE)*/
12315 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12317 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12318 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12320 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12322 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12323 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12328 static struct hda_channel_mode alc861_threestack_modes[2] = {
12329 { 2, alc861_threestack_ch2_init },
12330 { 6, alc861_threestack_ch6_init },
12332 /* Set mic1 as input and unmute the mixer */
12333 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12334 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12335 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12338 /* Set mic1 as output and mute mixer */
12339 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12340 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12341 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12345 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12346 { 2, alc861_uniwill_m31_ch2_init },
12347 { 4, alc861_uniwill_m31_ch4_init },
12350 /* Set mic1 and line-in as input and unmute the mixer */
12351 static struct hda_verb alc861_asus_ch2_init[] = {
12352 /* set pin widget 1Ah (line in) for input */
12353 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12354 /* set pin widget 18h (mic1/2) for input, for mic also enable
12357 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12359 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12361 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12362 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12366 /* Set mic1 nad line-in as output and mute mixer */
12367 static struct hda_verb alc861_asus_ch6_init[] = {
12368 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12369 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12370 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12371 /* set pin widget 18h (mic1) for output (CLFE)*/
12372 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12373 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12374 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12375 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12377 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12379 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12380 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12385 static struct hda_channel_mode alc861_asus_modes[2] = {
12386 { 2, alc861_asus_ch2_init },
12387 { 6, alc861_asus_ch6_init },
12392 static struct snd_kcontrol_new alc861_base_mixer[] = {
12393 /* output mixer control */
12394 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12395 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12396 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12397 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12398 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12400 /*Input mixer control */
12401 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12402 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12403 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12404 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12405 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12406 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12407 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12408 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12409 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12410 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12412 /* Capture mixer control */
12413 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12414 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12417 .name = "Capture Source",
12419 .info = alc_mux_enum_info,
12420 .get = alc_mux_enum_get,
12421 .put = alc_mux_enum_put,
12426 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12427 /* output mixer control */
12428 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12429 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12430 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12431 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12432 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12434 /* Input mixer control */
12435 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12436 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12437 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12438 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12439 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12440 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12442 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12443 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12446 /* Capture mixer control */
12447 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12448 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12451 .name = "Capture Source",
12453 .info = alc_mux_enum_info,
12454 .get = alc_mux_enum_get,
12455 .put = alc_mux_enum_put,
12458 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12459 .name = "Channel Mode",
12460 .info = alc_ch_mode_info,
12461 .get = alc_ch_mode_get,
12462 .put = alc_ch_mode_put,
12463 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12468 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12469 /* output mixer control */
12470 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12472 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12474 /*Capture mixer control */
12475 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12476 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12479 .name = "Capture Source",
12481 .info = alc_mux_enum_info,
12482 .get = alc_mux_enum_get,
12483 .put = alc_mux_enum_put,
12489 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12490 /* output mixer control */
12491 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12492 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12493 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12494 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12495 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12497 /* Input mixer control */
12498 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12499 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12500 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12501 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12502 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12503 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12505 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12506 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12509 /* Capture mixer control */
12510 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12511 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12514 .name = "Capture Source",
12516 .info = alc_mux_enum_info,
12517 .get = alc_mux_enum_get,
12518 .put = alc_mux_enum_put,
12521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12522 .name = "Channel Mode",
12523 .info = alc_ch_mode_info,
12524 .get = alc_ch_mode_get,
12525 .put = alc_ch_mode_put,
12526 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12531 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12532 /* output mixer control */
12533 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12534 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12535 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12536 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12537 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12539 /* Input mixer control */
12540 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12541 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12542 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12543 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12544 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12545 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12547 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12548 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12551 /* Capture mixer control */
12552 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12553 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12556 .name = "Capture Source",
12558 .info = alc_mux_enum_info,
12559 .get = alc_mux_enum_get,
12560 .put = alc_mux_enum_put,
12563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12564 .name = "Channel Mode",
12565 .info = alc_ch_mode_info,
12566 .get = alc_ch_mode_get,
12567 .put = alc_ch_mode_put,
12568 .private_value = ARRAY_SIZE(alc861_asus_modes),
12573 /* additional mixer */
12574 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12575 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12576 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12577 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12578 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12583 * generic initialization of ADC, input mixers and output mixers
12585 static struct hda_verb alc861_base_init_verbs[] = {
12587 * Unmute ADC0 and set the default input to mic-in
12589 /* port-A for surround (rear panel) */
12590 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12591 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12592 /* port-B for mic-in (rear panel) with vref */
12593 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12594 /* port-C for line-in (rear panel) */
12595 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12596 /* port-D for Front */
12597 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12598 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12599 /* port-E for HP out (front panel) */
12600 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12601 /* route front PCM to HP */
12602 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12603 /* port-F for mic-in (front panel) with vref */
12604 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12605 /* port-G for CLFE (rear panel) */
12606 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12607 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12608 /* port-H for side (rear panel) */
12609 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12610 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12612 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12613 /* route front mic to ADC1*/
12614 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12615 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12617 /* Unmute DAC0~3 & spdif out*/
12618 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12619 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12620 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12621 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12624 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12625 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12626 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12627 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12628 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12630 /* Unmute Stereo Mixer 15 */
12631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12637 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12638 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12639 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12640 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12641 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12642 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12644 /* hp used DAC 3 (Front) */
12645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12651 static struct hda_verb alc861_threestack_init_verbs[] = {
12653 * Unmute ADC0 and set the default input to mic-in
12655 /* port-A for surround (rear panel) */
12656 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12657 /* port-B for mic-in (rear panel) with vref */
12658 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12659 /* port-C for line-in (rear panel) */
12660 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12661 /* port-D for Front */
12662 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12663 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12664 /* port-E for HP out (front panel) */
12665 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12666 /* route front PCM to HP */
12667 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12668 /* port-F for mic-in (front panel) with vref */
12669 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12670 /* port-G for CLFE (rear panel) */
12671 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12672 /* port-H for side (rear panel) */
12673 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12675 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12676 /* route front mic to ADC1*/
12677 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12678 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12679 /* Unmute DAC0~3 & spdif out*/
12680 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12681 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12682 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12683 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12686 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12687 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12688 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12689 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12690 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12692 /* Unmute Stereo Mixer 15 */
12693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12698 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12700 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12701 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12702 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12703 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12705 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12706 /* hp used DAC 3 (Front) */
12707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12708 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12712 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12714 * Unmute ADC0 and set the default input to mic-in
12716 /* port-A for surround (rear panel) */
12717 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12718 /* port-B for mic-in (rear panel) with vref */
12719 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12720 /* port-C for line-in (rear panel) */
12721 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12722 /* port-D for Front */
12723 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12724 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12725 /* port-E for HP out (front panel) */
12726 /* this has to be set to VREF80 */
12727 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12728 /* route front PCM to HP */
12729 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12730 /* port-F for mic-in (front panel) with vref */
12731 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12732 /* port-G for CLFE (rear panel) */
12733 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12734 /* port-H for side (rear panel) */
12735 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12737 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12738 /* route front mic to ADC1*/
12739 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12740 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12741 /* Unmute DAC0~3 & spdif out*/
12742 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12743 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12744 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12745 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12748 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12749 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12750 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12751 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12752 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12754 /* Unmute Stereo Mixer 15 */
12755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12757 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12758 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12760 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12761 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12762 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12763 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12764 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12765 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12766 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12767 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12768 /* hp used DAC 3 (Front) */
12769 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12770 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12774 static struct hda_verb alc861_asus_init_verbs[] = {
12776 * Unmute ADC0 and set the default input to mic-in
12778 /* port-A for surround (rear panel)
12779 * according to codec#0 this is the HP jack
12781 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12782 /* route front PCM to HP */
12783 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12784 /* port-B for mic-in (rear panel) with vref */
12785 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12786 /* port-C for line-in (rear panel) */
12787 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12788 /* port-D for Front */
12789 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12790 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12791 /* port-E for HP out (front panel) */
12792 /* this has to be set to VREF80 */
12793 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12794 /* route front PCM to HP */
12795 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12796 /* port-F for mic-in (front panel) with vref */
12797 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12798 /* port-G for CLFE (rear panel) */
12799 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12800 /* port-H for side (rear panel) */
12801 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12803 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12804 /* route front mic to ADC1*/
12805 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12806 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12807 /* Unmute DAC0~3 & spdif out*/
12808 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12809 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12810 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12811 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12813 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12814 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12815 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12816 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12817 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12819 /* Unmute Stereo Mixer 15 */
12820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12827 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12828 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12829 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12832 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12833 /* hp used DAC 3 (Front) */
12834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12835 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12839 /* additional init verbs for ASUS laptops */
12840 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12841 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12842 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12847 * generic initialization of ADC, input mixers and output mixers
12849 static struct hda_verb alc861_auto_init_verbs[] = {
12851 * Unmute ADC0 and set the default input to mic-in
12853 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12854 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12856 /* Unmute DAC0~3 & spdif out*/
12857 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12858 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12859 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12860 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12863 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12864 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12865 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12866 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12867 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12869 /* Unmute Stereo Mixer 15 */
12870 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12875 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12876 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12877 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12878 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12880 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12882 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12885 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12886 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12887 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12888 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12889 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12890 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12891 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12893 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
12898 static struct hda_verb alc861_toshiba_init_verbs[] = {
12899 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12904 /* toggle speaker-output according to the hp-jack state */
12905 static void alc861_toshiba_automute(struct hda_codec *codec)
12907 unsigned int present;
12909 present = snd_hda_codec_read(codec, 0x0f, 0,
12910 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12911 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12912 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12913 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12914 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12917 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12920 if ((res >> 26) == ALC880_HP_EVENT)
12921 alc861_toshiba_automute(codec);
12924 /* pcm configuration: identiacal with ALC880 */
12925 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
12926 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
12927 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
12928 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
12931 #define ALC861_DIGOUT_NID 0x07
12933 static struct hda_channel_mode alc861_8ch_modes[1] = {
12937 static hda_nid_t alc861_dac_nids[4] = {
12938 /* front, surround, clfe, side */
12939 0x03, 0x06, 0x05, 0x04
12942 static hda_nid_t alc660_dac_nids[3] = {
12943 /* front, clfe, surround */
12947 static hda_nid_t alc861_adc_nids[1] = {
12952 static struct hda_input_mux alc861_capture_source = {
12956 { "Front Mic", 0x3 },
12963 /* fill in the dac_nids table from the parsed pin configuration */
12964 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12965 const struct auto_pin_cfg *cfg)
12970 spec->multiout.dac_nids = spec->private_dac_nids;
12971 for (i = 0; i < cfg->line_outs; i++) {
12972 nid = cfg->line_out_pins[i];
12974 if (i >= ARRAY_SIZE(alc861_dac_nids))
12976 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12979 spec->multiout.num_dacs = cfg->line_outs;
12983 /* add playback controls from the parsed DAC table */
12984 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12985 const struct auto_pin_cfg *cfg)
12988 static const char *chname[4] = {
12989 "Front", "Surround", NULL /*CLFE*/, "Side"
12994 for (i = 0; i < cfg->line_outs; i++) {
12995 nid = spec->multiout.dac_nids[i];
13000 err = add_control(spec, ALC_CTL_BIND_MUTE,
13001 "Center Playback Switch",
13002 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13006 err = add_control(spec, ALC_CTL_BIND_MUTE,
13007 "LFE Playback Switch",
13008 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13013 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13015 if (nid == alc861_dac_nids[idx])
13017 sprintf(name, "%s Playback Switch", chname[idx]);
13018 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13019 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13028 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13036 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13038 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13039 "Headphone Playback Switch",
13040 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13043 spec->multiout.hp_nid = nid;
13048 /* create playback/capture controls for input pins */
13049 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13050 const struct auto_pin_cfg *cfg)
13052 struct hda_input_mux *imux = &spec->private_imux;
13053 int i, err, idx, idx1;
13055 for (i = 0; i < AUTO_PIN_LAST; i++) {
13056 switch (cfg->input_pins[i]) {
13059 idx = 2; /* Line In */
13063 idx = 2; /* Line In */
13067 idx = 1; /* Mic In */
13071 idx = 1; /* Mic In */
13081 err = new_analog_input(spec, cfg->input_pins[i],
13082 auto_pin_cfg_labels[i], idx, 0x15);
13086 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13087 imux->items[imux->num_items].index = idx1;
13093 static struct snd_kcontrol_new alc861_capture_mixer[] = {
13094 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13095 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13099 /* The multiple "Capture Source" controls confuse alsamixer
13100 * So call somewhat different..
13102 /* .name = "Capture Source", */
13103 .name = "Input Source",
13105 .info = alc_mux_enum_info,
13106 .get = alc_mux_enum_get,
13107 .put = alc_mux_enum_put,
13112 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13114 int pin_type, int dac_idx)
13116 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13118 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13122 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13124 struct alc_spec *spec = codec->spec;
13127 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13128 for (i = 0; i < spec->autocfg.line_outs; i++) {
13129 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13130 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13132 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13133 spec->multiout.dac_nids[i]);
13137 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13139 struct alc_spec *spec = codec->spec;
13142 pin = spec->autocfg.hp_pins[0];
13143 if (pin) /* connect to front */
13144 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13145 spec->multiout.dac_nids[0]);
13146 pin = spec->autocfg.speaker_pins[0];
13148 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13151 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13153 struct alc_spec *spec = codec->spec;
13156 for (i = 0; i < AUTO_PIN_LAST; i++) {
13157 hda_nid_t nid = spec->autocfg.input_pins[i];
13158 if (nid >= 0x0c && nid <= 0x11) {
13159 snd_hda_codec_write(codec, nid, 0,
13160 AC_VERB_SET_PIN_WIDGET_CONTROL,
13161 i <= AUTO_PIN_FRONT_MIC ?
13162 PIN_VREF80 : PIN_IN);
13167 /* parse the BIOS configuration and set up the alc_spec */
13168 /* return 1 if successful, 0 if the proper config is not found,
13169 * or a negative error code
13171 static int alc861_parse_auto_config(struct hda_codec *codec)
13173 struct alc_spec *spec = codec->spec;
13175 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13177 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13181 if (!spec->autocfg.line_outs)
13182 return 0; /* can't find valid BIOS pin config */
13184 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13187 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13190 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13193 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13197 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13199 if (spec->autocfg.dig_out_pin)
13200 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13202 if (spec->kctl_alloc)
13203 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13205 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13207 spec->num_mux_defs = 1;
13208 spec->input_mux = &spec->private_imux;
13210 spec->adc_nids = alc861_adc_nids;
13211 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13212 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13213 spec->num_mixers++;
13218 /* additional initialization for auto-configuration model */
13219 static void alc861_auto_init(struct hda_codec *codec)
13221 struct alc_spec *spec = codec->spec;
13222 alc861_auto_init_multi_out(codec);
13223 alc861_auto_init_hp_out(codec);
13224 alc861_auto_init_analog_input(codec);
13225 if (spec->unsol_event)
13226 alc_sku_automute(codec);
13229 #ifdef CONFIG_SND_HDA_POWER_SAVE
13230 static struct hda_amp_list alc861_loopbacks[] = {
13231 { 0x15, HDA_INPUT, 0 },
13232 { 0x15, HDA_INPUT, 1 },
13233 { 0x15, HDA_INPUT, 2 },
13234 { 0x15, HDA_INPUT, 3 },
13241 * configuration and preset
13243 static const char *alc861_models[ALC861_MODEL_LAST] = {
13244 [ALC861_3ST] = "3stack",
13245 [ALC660_3ST] = "3stack-660",
13246 [ALC861_3ST_DIG] = "3stack-dig",
13247 [ALC861_6ST_DIG] = "6stack-dig",
13248 [ALC861_UNIWILL_M31] = "uniwill-m31",
13249 [ALC861_TOSHIBA] = "toshiba",
13250 [ALC861_ASUS] = "asus",
13251 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13252 [ALC861_AUTO] = "auto",
13255 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13256 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13257 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13258 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13259 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13260 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13261 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13262 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13263 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13264 * Any other models that need this preset?
13266 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13267 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13268 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13269 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13270 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13271 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13272 /* FIXME: the below seems conflict */
13273 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13274 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13275 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13279 static struct alc_config_preset alc861_presets[] = {
13281 .mixers = { alc861_3ST_mixer },
13282 .init_verbs = { alc861_threestack_init_verbs },
13283 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13284 .dac_nids = alc861_dac_nids,
13285 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13286 .channel_mode = alc861_threestack_modes,
13288 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13289 .adc_nids = alc861_adc_nids,
13290 .input_mux = &alc861_capture_source,
13292 [ALC861_3ST_DIG] = {
13293 .mixers = { alc861_base_mixer },
13294 .init_verbs = { alc861_threestack_init_verbs },
13295 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13296 .dac_nids = alc861_dac_nids,
13297 .dig_out_nid = ALC861_DIGOUT_NID,
13298 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13299 .channel_mode = alc861_threestack_modes,
13301 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13302 .adc_nids = alc861_adc_nids,
13303 .input_mux = &alc861_capture_source,
13305 [ALC861_6ST_DIG] = {
13306 .mixers = { alc861_base_mixer },
13307 .init_verbs = { alc861_base_init_verbs },
13308 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13309 .dac_nids = alc861_dac_nids,
13310 .dig_out_nid = ALC861_DIGOUT_NID,
13311 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13312 .channel_mode = alc861_8ch_modes,
13313 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13314 .adc_nids = alc861_adc_nids,
13315 .input_mux = &alc861_capture_source,
13318 .mixers = { alc861_3ST_mixer },
13319 .init_verbs = { alc861_threestack_init_verbs },
13320 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13321 .dac_nids = alc660_dac_nids,
13322 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13323 .channel_mode = alc861_threestack_modes,
13325 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13326 .adc_nids = alc861_adc_nids,
13327 .input_mux = &alc861_capture_source,
13329 [ALC861_UNIWILL_M31] = {
13330 .mixers = { alc861_uniwill_m31_mixer },
13331 .init_verbs = { alc861_uniwill_m31_init_verbs },
13332 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13333 .dac_nids = alc861_dac_nids,
13334 .dig_out_nid = ALC861_DIGOUT_NID,
13335 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13336 .channel_mode = alc861_uniwill_m31_modes,
13338 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13339 .adc_nids = alc861_adc_nids,
13340 .input_mux = &alc861_capture_source,
13342 [ALC861_TOSHIBA] = {
13343 .mixers = { alc861_toshiba_mixer },
13344 .init_verbs = { alc861_base_init_verbs,
13345 alc861_toshiba_init_verbs },
13346 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13347 .dac_nids = alc861_dac_nids,
13348 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13349 .channel_mode = alc883_3ST_2ch_modes,
13350 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13351 .adc_nids = alc861_adc_nids,
13352 .input_mux = &alc861_capture_source,
13353 .unsol_event = alc861_toshiba_unsol_event,
13354 .init_hook = alc861_toshiba_automute,
13357 .mixers = { alc861_asus_mixer },
13358 .init_verbs = { alc861_asus_init_verbs },
13359 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13360 .dac_nids = alc861_dac_nids,
13361 .dig_out_nid = ALC861_DIGOUT_NID,
13362 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13363 .channel_mode = alc861_asus_modes,
13366 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13367 .adc_nids = alc861_adc_nids,
13368 .input_mux = &alc861_capture_source,
13370 [ALC861_ASUS_LAPTOP] = {
13371 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13372 .init_verbs = { alc861_asus_init_verbs,
13373 alc861_asus_laptop_init_verbs },
13374 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13375 .dac_nids = alc861_dac_nids,
13376 .dig_out_nid = ALC861_DIGOUT_NID,
13377 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13378 .channel_mode = alc883_3ST_2ch_modes,
13380 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13381 .adc_nids = alc861_adc_nids,
13382 .input_mux = &alc861_capture_source,
13387 static int patch_alc861(struct hda_codec *codec)
13389 struct alc_spec *spec;
13393 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13397 codec->spec = spec;
13399 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13403 if (board_config < 0) {
13404 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13405 "trying auto-probe from BIOS...\n");
13406 board_config = ALC861_AUTO;
13409 if (board_config == ALC861_AUTO) {
13410 /* automatic parse from the BIOS config */
13411 err = alc861_parse_auto_config(codec);
13417 "hda_codec: Cannot set up configuration "
13418 "from BIOS. Using base mode...\n");
13419 board_config = ALC861_3ST_DIG;
13423 if (board_config != ALC861_AUTO)
13424 setup_preset(spec, &alc861_presets[board_config]);
13426 spec->stream_name_analog = "ALC861 Analog";
13427 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13428 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13430 spec->stream_name_digital = "ALC861 Digital";
13431 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13432 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13434 spec->vmaster_nid = 0x03;
13436 codec->patch_ops = alc_patch_ops;
13437 if (board_config == ALC861_AUTO)
13438 spec->init_hook = alc861_auto_init;
13439 #ifdef CONFIG_SND_HDA_POWER_SAVE
13440 if (!spec->loopback.amplist)
13441 spec->loopback.amplist = alc861_loopbacks;
13448 * ALC861-VD support
13452 * In addition, an independent DAC
13454 #define ALC861VD_DIGOUT_NID 0x06
13456 static hda_nid_t alc861vd_dac_nids[4] = {
13457 /* front, surr, clfe, side surr */
13458 0x02, 0x03, 0x04, 0x05
13461 /* dac_nids for ALC660vd are in a different order - according to
13462 * Realtek's driver.
13463 * This should probably tesult in a different mixer for 6stack models
13464 * of ALC660vd codecs, but for now there is only 3stack mixer
13465 * - and it is the same as in 861vd.
13466 * adc_nids in ALC660vd are (is) the same as in 861vd
13468 static hda_nid_t alc660vd_dac_nids[3] = {
13469 /* front, rear, clfe, rear_surr */
13473 static hda_nid_t alc861vd_adc_nids[1] = {
13478 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13481 /* FIXME: should be a matrix-type input source selection */
13482 static struct hda_input_mux alc861vd_capture_source = {
13486 { "Front Mic", 0x1 },
13492 static struct hda_input_mux alc861vd_dallas_capture_source = {
13495 { "Ext Mic", 0x0 },
13496 { "Int Mic", 0x1 },
13500 static struct hda_input_mux alc861vd_hp_capture_source = {
13503 { "Front Mic", 0x0 },
13504 { "ATAPI Mic", 0x1 },
13508 #define alc861vd_mux_enum_info alc_mux_enum_info
13509 #define alc861vd_mux_enum_get alc_mux_enum_get
13510 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13511 #define alc861vd_mux_enum_put alc882_mux_enum_put
13516 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13523 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13524 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13525 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13526 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13527 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13534 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13535 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13536 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13537 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13538 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13542 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13543 { 6, alc861vd_6stack_ch6_init },
13544 { 8, alc861vd_6stack_ch8_init },
13547 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13549 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13550 .name = "Channel Mode",
13551 .info = alc_ch_mode_info,
13552 .get = alc_ch_mode_get,
13553 .put = alc_ch_mode_put,
13558 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13559 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13560 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13564 /* The multiple "Capture Source" controls confuse alsamixer
13565 * So call somewhat different..
13567 /* .name = "Capture Source", */
13568 .name = "Input Source",
13570 .info = alc861vd_mux_enum_info,
13571 .get = alc861vd_mux_enum_get,
13572 .put = alc861vd_mux_enum_put,
13577 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13578 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13580 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13581 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13582 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13584 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13585 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13587 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13589 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13591 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13592 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13594 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13595 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13597 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13599 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13603 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13604 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13605 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13607 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13608 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13610 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13611 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13613 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13614 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13619 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13620 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13621 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13625 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13627 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13629 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13633 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13634 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13639 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13640 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13645 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13646 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13647 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13648 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13652 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13653 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13654 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13656 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13660 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13661 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13666 /* Pin assignment: Speaker=0x14, HP = 0x15,
13667 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13669 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13670 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13671 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13672 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13673 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13674 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13675 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13676 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13677 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13678 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13679 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13680 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13681 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13685 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13686 * Front Mic=0x18, ATAPI Mic = 0x19,
13688 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13689 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13690 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13691 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13692 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13693 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13694 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13695 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13696 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13702 * generic initialization of ADC, input mixers and output mixers
13704 static struct hda_verb alc861vd_volume_init_verbs[] = {
13706 * Unmute ADC0 and set the default input to mic-in
13708 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13709 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13711 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13712 * the analog-loopback mixer widget
13714 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13721 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13722 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13723 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13728 * Set up output mixers (0x02 - 0x05)
13730 /* set vol=0 to output mixers */
13731 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13732 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13733 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13734 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13736 /* set up input amps for analog loopback */
13737 /* Amp Indices: DAC = 0, mixer = 1 */
13738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13741 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13742 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13743 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13744 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13745 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13751 * 3-stack pin configuration:
13752 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13754 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13756 * Set pin mode and muting
13758 /* set front pin widgets 0x14 for output */
13759 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13761 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13763 /* Mic (rear) pin: input vref at 80% */
13764 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13765 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13766 /* Front Mic pin: input vref at 80% */
13767 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13768 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13769 /* Line In pin: input */
13770 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13771 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13772 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13773 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13774 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13775 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13776 /* CD pin widget for input */
13777 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13783 * 6-stack pin configuration:
13785 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13787 * Set pin mode and muting
13789 /* set front pin widgets 0x14 for output */
13790 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13791 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13792 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13794 /* Rear Pin: output 1 (0x0d) */
13795 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13797 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13798 /* CLFE Pin: output 2 (0x0e) */
13799 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13801 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13802 /* Side Pin: output 3 (0x0f) */
13803 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13804 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13805 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13807 /* Mic (rear) pin: input vref at 80% */
13808 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13809 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13810 /* Front Mic pin: input vref at 80% */
13811 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13812 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13813 /* Line In pin: input */
13814 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13815 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13816 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13818 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13819 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13820 /* CD pin widget for input */
13821 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13826 static struct hda_verb alc861vd_eapd_verbs[] = {
13827 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13831 static struct hda_verb alc660vd_eapd_verbs[] = {
13832 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13833 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13837 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13841 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13842 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13846 /* toggle speaker-output according to the hp-jack state */
13847 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13849 unsigned int present;
13850 unsigned char bits;
13852 present = snd_hda_codec_read(codec, 0x1b, 0,
13853 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13854 bits = present ? HDA_AMP_MUTE : 0;
13855 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13856 HDA_AMP_MUTE, bits);
13859 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13861 unsigned int present;
13862 unsigned char bits;
13864 present = snd_hda_codec_read(codec, 0x18, 0,
13865 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13866 bits = present ? HDA_AMP_MUTE : 0;
13867 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13868 HDA_AMP_MUTE, bits);
13871 static void alc861vd_lenovo_automute(struct hda_codec *codec)
13873 alc861vd_lenovo_hp_automute(codec);
13874 alc861vd_lenovo_mic_automute(codec);
13877 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13880 switch (res >> 26) {
13881 case ALC880_HP_EVENT:
13882 alc861vd_lenovo_hp_automute(codec);
13884 case ALC880_MIC_EVENT:
13885 alc861vd_lenovo_mic_automute(codec);
13890 static struct hda_verb alc861vd_dallas_verbs[] = {
13891 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13892 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13893 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13894 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13896 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13897 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13898 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13899 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13900 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13901 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13902 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13903 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13905 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13906 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13908 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13909 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13910 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13911 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13912 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13914 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13915 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13916 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13917 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13918 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13919 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13920 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13921 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13924 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13925 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13929 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13930 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13935 /* toggle speaker-output according to the hp-jack state */
13936 static void alc861vd_dallas_automute(struct hda_codec *codec)
13938 unsigned int present;
13940 present = snd_hda_codec_read(codec, 0x15, 0,
13941 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13942 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13943 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13946 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13948 if ((res >> 26) == ALC880_HP_EVENT)
13949 alc861vd_dallas_automute(codec);
13952 #ifdef CONFIG_SND_HDA_POWER_SAVE
13953 #define alc861vd_loopbacks alc880_loopbacks
13956 /* pcm configuration: identiacal with ALC880 */
13957 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
13958 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
13959 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
13960 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
13963 * configuration and preset
13965 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13966 [ALC660VD_3ST] = "3stack-660",
13967 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13968 [ALC861VD_3ST] = "3stack",
13969 [ALC861VD_3ST_DIG] = "3stack-digout",
13970 [ALC861VD_6ST_DIG] = "6stack-digout",
13971 [ALC861VD_LENOVO] = "lenovo",
13972 [ALC861VD_DALLAS] = "dallas",
13973 [ALC861VD_HP] = "hp",
13974 [ALC861VD_AUTO] = "auto",
13977 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13978 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13979 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13980 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13981 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13982 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
13983 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13984 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13985 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13986 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13987 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13988 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13989 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13990 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13991 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13992 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13993 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13994 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
13998 static struct alc_config_preset alc861vd_presets[] = {
14000 .mixers = { alc861vd_3st_mixer },
14001 .init_verbs = { alc861vd_volume_init_verbs,
14002 alc861vd_3stack_init_verbs },
14003 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14004 .dac_nids = alc660vd_dac_nids,
14005 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14006 .channel_mode = alc861vd_3stack_2ch_modes,
14007 .input_mux = &alc861vd_capture_source,
14009 [ALC660VD_3ST_DIG] = {
14010 .mixers = { alc861vd_3st_mixer },
14011 .init_verbs = { alc861vd_volume_init_verbs,
14012 alc861vd_3stack_init_verbs },
14013 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14014 .dac_nids = alc660vd_dac_nids,
14015 .dig_out_nid = ALC861VD_DIGOUT_NID,
14016 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14017 .channel_mode = alc861vd_3stack_2ch_modes,
14018 .input_mux = &alc861vd_capture_source,
14021 .mixers = { alc861vd_3st_mixer },
14022 .init_verbs = { alc861vd_volume_init_verbs,
14023 alc861vd_3stack_init_verbs },
14024 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14025 .dac_nids = alc861vd_dac_nids,
14026 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14027 .channel_mode = alc861vd_3stack_2ch_modes,
14028 .input_mux = &alc861vd_capture_source,
14030 [ALC861VD_3ST_DIG] = {
14031 .mixers = { alc861vd_3st_mixer },
14032 .init_verbs = { alc861vd_volume_init_verbs,
14033 alc861vd_3stack_init_verbs },
14034 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14035 .dac_nids = alc861vd_dac_nids,
14036 .dig_out_nid = ALC861VD_DIGOUT_NID,
14037 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14038 .channel_mode = alc861vd_3stack_2ch_modes,
14039 .input_mux = &alc861vd_capture_source,
14041 [ALC861VD_6ST_DIG] = {
14042 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14043 .init_verbs = { alc861vd_volume_init_verbs,
14044 alc861vd_6stack_init_verbs },
14045 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14046 .dac_nids = alc861vd_dac_nids,
14047 .dig_out_nid = ALC861VD_DIGOUT_NID,
14048 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14049 .channel_mode = alc861vd_6stack_modes,
14050 .input_mux = &alc861vd_capture_source,
14052 [ALC861VD_LENOVO] = {
14053 .mixers = { alc861vd_lenovo_mixer },
14054 .init_verbs = { alc861vd_volume_init_verbs,
14055 alc861vd_3stack_init_verbs,
14056 alc861vd_eapd_verbs,
14057 alc861vd_lenovo_unsol_verbs },
14058 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14059 .dac_nids = alc660vd_dac_nids,
14060 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14061 .channel_mode = alc861vd_3stack_2ch_modes,
14062 .input_mux = &alc861vd_capture_source,
14063 .unsol_event = alc861vd_lenovo_unsol_event,
14064 .init_hook = alc861vd_lenovo_automute,
14066 [ALC861VD_DALLAS] = {
14067 .mixers = { alc861vd_dallas_mixer },
14068 .init_verbs = { alc861vd_dallas_verbs },
14069 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14070 .dac_nids = alc861vd_dac_nids,
14071 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14072 .channel_mode = alc861vd_3stack_2ch_modes,
14073 .input_mux = &alc861vd_dallas_capture_source,
14074 .unsol_event = alc861vd_dallas_unsol_event,
14075 .init_hook = alc861vd_dallas_automute,
14078 .mixers = { alc861vd_hp_mixer },
14079 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14080 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14081 .dac_nids = alc861vd_dac_nids,
14082 .dig_out_nid = ALC861VD_DIGOUT_NID,
14083 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14084 .channel_mode = alc861vd_3stack_2ch_modes,
14085 .input_mux = &alc861vd_hp_capture_source,
14086 .unsol_event = alc861vd_dallas_unsol_event,
14087 .init_hook = alc861vd_dallas_automute,
14092 * BIOS auto configuration
14094 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14095 hda_nid_t nid, int pin_type, int dac_idx)
14097 alc_set_pin_output(codec, nid, pin_type);
14100 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14102 struct alc_spec *spec = codec->spec;
14105 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14106 for (i = 0; i <= HDA_SIDE; i++) {
14107 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14108 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14110 alc861vd_auto_set_output_and_unmute(codec, nid,
14116 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14118 struct alc_spec *spec = codec->spec;
14121 pin = spec->autocfg.hp_pins[0];
14122 if (pin) /* connect to front and use dac 0 */
14123 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14124 pin = spec->autocfg.speaker_pins[0];
14126 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14129 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14130 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14132 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14134 struct alc_spec *spec = codec->spec;
14137 for (i = 0; i < AUTO_PIN_LAST; i++) {
14138 hda_nid_t nid = spec->autocfg.input_pins[i];
14139 if (alc861vd_is_input_pin(nid)) {
14140 snd_hda_codec_write(codec, nid, 0,
14141 AC_VERB_SET_PIN_WIDGET_CONTROL,
14142 i <= AUTO_PIN_FRONT_MIC ?
14143 PIN_VREF80 : PIN_IN);
14144 if (nid != ALC861VD_PIN_CD_NID)
14145 snd_hda_codec_write(codec, nid, 0,
14146 AC_VERB_SET_AMP_GAIN_MUTE,
14152 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14154 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14155 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14157 /* add playback controls from the parsed DAC table */
14158 /* Based on ALC880 version. But ALC861VD has separate,
14159 * different NIDs for mute/unmute switch and volume control */
14160 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14161 const struct auto_pin_cfg *cfg)
14164 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14165 hda_nid_t nid_v, nid_s;
14168 for (i = 0; i < cfg->line_outs; i++) {
14169 if (!spec->multiout.dac_nids[i])
14171 nid_v = alc861vd_idx_to_mixer_vol(
14173 spec->multiout.dac_nids[i]));
14174 nid_s = alc861vd_idx_to_mixer_switch(
14176 spec->multiout.dac_nids[i]));
14180 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14181 "Center Playback Volume",
14182 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14186 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14187 "LFE Playback Volume",
14188 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14192 err = add_control(spec, ALC_CTL_BIND_MUTE,
14193 "Center Playback Switch",
14194 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14198 err = add_control(spec, ALC_CTL_BIND_MUTE,
14199 "LFE Playback Switch",
14200 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14205 sprintf(name, "%s Playback Volume", chname[i]);
14206 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14207 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14211 sprintf(name, "%s Playback Switch", chname[i]);
14212 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14213 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14222 /* add playback controls for speaker and HP outputs */
14223 /* Based on ALC880 version. But ALC861VD has separate,
14224 * different NIDs for mute/unmute switch and volume control */
14225 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14226 hda_nid_t pin, const char *pfx)
14228 hda_nid_t nid_v, nid_s;
14235 if (alc880_is_fixed_pin(pin)) {
14236 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14237 /* specify the DAC as the extra output */
14238 if (!spec->multiout.hp_nid)
14239 spec->multiout.hp_nid = nid_v;
14241 spec->multiout.extra_out_nid[0] = nid_v;
14242 /* control HP volume/switch on the output mixer amp */
14243 nid_v = alc861vd_idx_to_mixer_vol(
14244 alc880_fixed_pin_idx(pin));
14245 nid_s = alc861vd_idx_to_mixer_switch(
14246 alc880_fixed_pin_idx(pin));
14248 sprintf(name, "%s Playback Volume", pfx);
14249 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14250 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14253 sprintf(name, "%s Playback Switch", pfx);
14254 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14255 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14258 } else if (alc880_is_multi_pin(pin)) {
14259 /* set manual connection */
14260 /* we have only a switch on HP-out PIN */
14261 sprintf(name, "%s Playback Switch", pfx);
14262 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14263 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14270 /* parse the BIOS configuration and set up the alc_spec
14271 * return 1 if successful, 0 if the proper config is not found,
14272 * or a negative error code
14273 * Based on ALC880 version - had to change it to override
14274 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14275 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14277 struct alc_spec *spec = codec->spec;
14279 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14281 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14285 if (!spec->autocfg.line_outs)
14286 return 0; /* can't find valid BIOS pin config */
14288 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14291 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14294 err = alc861vd_auto_create_extra_out(spec,
14295 spec->autocfg.speaker_pins[0],
14299 err = alc861vd_auto_create_extra_out(spec,
14300 spec->autocfg.hp_pins[0],
14304 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14308 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14310 if (spec->autocfg.dig_out_pin)
14311 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14313 if (spec->kctl_alloc)
14314 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14316 spec->init_verbs[spec->num_init_verbs++]
14317 = alc861vd_volume_init_verbs;
14319 spec->num_mux_defs = 1;
14320 spec->input_mux = &spec->private_imux;
14322 err = alc_auto_add_mic_boost(codec);
14329 /* additional initialization for auto-configuration model */
14330 static void alc861vd_auto_init(struct hda_codec *codec)
14332 struct alc_spec *spec = codec->spec;
14333 alc861vd_auto_init_multi_out(codec);
14334 alc861vd_auto_init_hp_out(codec);
14335 alc861vd_auto_init_analog_input(codec);
14336 alc861vd_auto_init_input_src(codec);
14337 if (spec->unsol_event)
14338 alc_sku_automute(codec);
14341 static int patch_alc861vd(struct hda_codec *codec)
14343 struct alc_spec *spec;
14344 int err, board_config;
14346 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14350 codec->spec = spec;
14352 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14356 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14357 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14358 "ALC861VD, trying auto-probe from BIOS...\n");
14359 board_config = ALC861VD_AUTO;
14362 if (board_config == ALC861VD_AUTO) {
14363 /* automatic parse from the BIOS config */
14364 err = alc861vd_parse_auto_config(codec);
14370 "hda_codec: Cannot set up configuration "
14371 "from BIOS. Using base mode...\n");
14372 board_config = ALC861VD_3ST;
14376 if (board_config != ALC861VD_AUTO)
14377 setup_preset(spec, &alc861vd_presets[board_config]);
14379 if (codec->vendor_id == 0x10ec0660) {
14380 spec->stream_name_analog = "ALC660-VD Analog";
14381 spec->stream_name_digital = "ALC660-VD Digital";
14382 /* always turn on EAPD */
14383 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
14385 spec->stream_name_analog = "ALC861VD Analog";
14386 spec->stream_name_digital = "ALC861VD Digital";
14389 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14390 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14392 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14393 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14395 spec->adc_nids = alc861vd_adc_nids;
14396 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14397 spec->capsrc_nids = alc861vd_capsrc_nids;
14399 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14400 spec->num_mixers++;
14402 spec->vmaster_nid = 0x02;
14404 codec->patch_ops = alc_patch_ops;
14406 if (board_config == ALC861VD_AUTO)
14407 spec->init_hook = alc861vd_auto_init;
14408 #ifdef CONFIG_SND_HDA_POWER_SAVE
14409 if (!spec->loopback.amplist)
14410 spec->loopback.amplist = alc861vd_loopbacks;
14419 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14420 * configuration. Each pin widget can choose any input DACs and a mixer.
14421 * Each ADC is connected from a mixer of all inputs. This makes possible
14422 * 6-channel independent captures.
14424 * In addition, an independent DAC for the multi-playback (not used in this
14427 #define ALC662_DIGOUT_NID 0x06
14428 #define ALC662_DIGIN_NID 0x0a
14430 static hda_nid_t alc662_dac_nids[4] = {
14431 /* front, rear, clfe, rear_surr */
14435 static hda_nid_t alc662_adc_nids[1] = {
14440 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14443 /* FIXME: should be a matrix-type input source selection */
14444 static struct hda_input_mux alc662_capture_source = {
14448 { "Front Mic", 0x1 },
14454 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14462 static struct hda_input_mux alc662_eeepc_capture_source = {
14470 static struct hda_input_mux alc663_capture_source = {
14474 { "Front Mic", 0x1 },
14479 static struct hda_input_mux alc663_m51va_capture_source = {
14482 { "Ext-Mic", 0x0 },
14487 #define alc662_mux_enum_info alc_mux_enum_info
14488 #define alc662_mux_enum_get alc_mux_enum_get
14489 #define alc662_mux_enum_put alc882_mux_enum_put
14494 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14501 static struct hda_verb alc662_3ST_ch2_init[] = {
14502 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14503 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14504 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14505 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14512 static struct hda_verb alc662_3ST_ch6_init[] = {
14513 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14514 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14515 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14516 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14517 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14518 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14522 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14523 { 2, alc662_3ST_ch2_init },
14524 { 6, alc662_3ST_ch6_init },
14530 static struct hda_verb alc662_sixstack_ch6_init[] = {
14531 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14532 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14533 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14540 static struct hda_verb alc662_sixstack_ch8_init[] = {
14541 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14542 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14543 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14547 static struct hda_channel_mode alc662_5stack_modes[2] = {
14548 { 2, alc662_sixstack_ch6_init },
14549 { 6, alc662_sixstack_ch8_init },
14552 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14553 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14556 static struct snd_kcontrol_new alc662_base_mixer[] = {
14557 /* output mixer control */
14558 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14559 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14560 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14561 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14562 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14563 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14564 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14565 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14566 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14568 /*Input mixer control */
14569 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14570 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14571 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14572 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14573 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14574 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14575 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14576 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14580 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14581 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14582 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14583 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14590 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14591 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14592 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14593 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14597 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14598 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14599 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14600 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14601 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14602 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14603 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14604 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14605 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14606 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14607 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14608 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14609 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14610 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14611 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14612 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14613 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14614 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14615 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14616 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14620 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14621 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14622 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14623 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14624 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14626 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14627 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14633 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14634 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14636 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14637 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14639 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14640 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14641 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14643 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14644 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14645 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14649 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14650 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14651 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14652 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14653 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, 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_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14657 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14658 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14659 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14660 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14661 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14663 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14667 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14668 .ops = &snd_hda_bind_vol,
14670 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14671 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14676 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14677 .ops = &snd_hda_bind_sw,
14679 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14680 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14685 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14686 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14687 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14689 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14693 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14694 .ops = &snd_hda_bind_sw,
14696 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14697 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14698 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14703 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14704 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14705 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14708 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14709 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14714 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14715 .ops = &snd_hda_bind_sw,
14717 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14718 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14719 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14724 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14725 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14726 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14729 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14730 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14734 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14735 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14736 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14738 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14740 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14741 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14745 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14746 .ops = &snd_hda_bind_vol,
14748 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14749 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14754 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14755 .ops = &snd_hda_bind_sw,
14757 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14758 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14763 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14764 HDA_BIND_VOL("Master Playback Volume",
14765 &alc663_asus_two_bind_master_vol),
14766 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14768 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14774 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14775 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14776 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14777 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14784 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14785 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14786 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14787 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14788 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14789 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14791 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14793 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14794 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14798 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14799 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14800 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14801 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14805 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14806 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14807 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14808 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14812 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14815 .name = "Channel Mode",
14816 .info = alc_ch_mode_info,
14817 .get = alc_ch_mode_get,
14818 .put = alc_ch_mode_put,
14823 static struct hda_verb alc662_init_verbs[] = {
14824 /* ADC: mute amp left and right */
14825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14826 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14827 /* Front mixer: unmute input/output amp left and right (volume = 0) */
14829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14838 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14839 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14840 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14842 /* Front Pin: output 0 (0x0c) */
14843 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14846 /* Rear Pin: output 1 (0x0d) */
14847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14850 /* CLFE Pin: output 2 (0x0e) */
14851 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14852 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14854 /* Mic (rear) pin: input vref at 80% */
14855 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14856 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14857 /* Front Mic pin: input vref at 80% */
14858 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14860 /* Line In pin: input */
14861 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14863 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14864 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14865 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14866 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14867 /* CD pin widget for input */
14868 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14870 /* FIXME: use matrix-type input source selection */
14871 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14878 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14879 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14880 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14881 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14883 /* always trun on EAPD */
14884 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14885 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14890 static struct hda_verb alc662_sue_init_verbs[] = {
14891 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14892 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14896 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14897 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14898 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14902 /* Set Unsolicited Event*/
14903 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14905 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14910 * generic initialization of ADC, input mixers and output mixers
14912 static struct hda_verb alc662_auto_init_verbs[] = {
14914 * Unmute ADC and set the default input to mic-in
14916 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14917 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14919 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14921 * Note: PASD motherboards uses the Line In 2 as the input for front
14922 * panel mic (mic 2)
14924 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14932 * Set up output mixers (0x0c - 0x0f)
14934 /* set vol=0 to output mixers */
14935 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14936 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14937 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14939 /* set up input amps for analog loopback */
14940 /* Amp Indices: DAC = 0, mixer = 1 */
14941 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14942 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14943 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14944 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14945 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14946 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14949 /* FIXME: use matrix-type input source selection */
14950 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14953 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14957 /* additional verbs for ALC663 */
14958 static struct hda_verb alc663_auto_init_verbs[] = {
14959 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14960 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14964 static struct hda_verb alc663_m51va_init_verbs[] = {
14965 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14966 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14967 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14968 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14969 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14971 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14972 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14973 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14977 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
14978 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14979 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14980 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14983 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14984 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14988 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
14989 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14990 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14991 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14992 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14995 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14996 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15000 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15001 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15006 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15007 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15011 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15012 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15013 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15014 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15015 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15016 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15017 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15018 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15020 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15021 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15022 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15023 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15027 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15028 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15029 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15030 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15031 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15035 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15037 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15038 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15039 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15043 static struct hda_verb alc663_g71v_init_verbs[] = {
15044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15045 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15046 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15048 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15049 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15050 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15052 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15053 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15054 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15058 static struct hda_verb alc663_g50v_init_verbs[] = {
15059 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15060 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15061 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15063 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15064 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15068 static struct hda_verb alc662_ecs_init_verbs[] = {
15069 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15071 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15076 /* capture mixer elements */
15077 static struct snd_kcontrol_new alc662_capture_mixer[] = {
15078 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15079 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15082 /* The multiple "Capture Source" controls confuse alsamixer
15083 * So call somewhat different..
15085 /* .name = "Capture Source", */
15086 .name = "Input Source",
15088 .info = alc662_mux_enum_info,
15089 .get = alc662_mux_enum_get,
15090 .put = alc662_mux_enum_put,
15095 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15096 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15097 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15101 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15103 unsigned int present;
15104 unsigned char bits;
15106 present = snd_hda_codec_read(codec, 0x14, 0,
15107 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15108 bits = present ? HDA_AMP_MUTE : 0;
15109 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15110 HDA_AMP_MUTE, bits);
15113 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15115 unsigned int present;
15116 unsigned char bits;
15118 present = snd_hda_codec_read(codec, 0x1b, 0,
15119 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15120 bits = present ? HDA_AMP_MUTE : 0;
15121 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15122 HDA_AMP_MUTE, bits);
15123 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15124 HDA_AMP_MUTE, bits);
15127 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15130 if ((res >> 26) == ALC880_HP_EVENT)
15131 alc662_lenovo_101e_all_automute(codec);
15132 if ((res >> 26) == ALC880_FRONT_EVENT)
15133 alc662_lenovo_101e_ispeaker_automute(codec);
15136 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15138 unsigned int present;
15140 present = snd_hda_codec_read(codec, 0x18, 0,
15141 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15142 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15143 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15144 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15145 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15146 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15147 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15148 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15149 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15152 /* unsolicited event for HP jack sensing */
15153 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15156 if ((res >> 26) == ALC880_HP_EVENT)
15157 alc262_hippo1_automute( codec );
15159 if ((res >> 26) == ALC880_MIC_EVENT)
15160 alc662_eeepc_mic_automute(codec);
15163 static void alc662_eeepc_inithook(struct hda_codec *codec)
15165 alc262_hippo1_automute( codec );
15166 alc662_eeepc_mic_automute(codec);
15169 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15172 unsigned int present;
15174 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15175 present = snd_hda_codec_read(codec, 0x14, 0,
15176 AC_VERB_GET_PIN_SENSE, 0);
15177 present = (present & 0x80000000) != 0;
15179 /* mute internal speaker */
15180 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15181 HDA_AMP_MUTE, HDA_AMP_MUTE);
15183 /* unmute internal speaker if necessary */
15184 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15185 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15186 HDA_AMP_MUTE, mute);
15190 /* unsolicited event for HP jack sensing */
15191 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15194 if ((res >> 26) == ALC880_HP_EVENT)
15195 alc662_eeepc_ep20_automute(codec);
15198 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15200 alc662_eeepc_ep20_automute(codec);
15203 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15205 unsigned int present;
15206 unsigned char bits;
15208 present = snd_hda_codec_read(codec, 0x21, 0,
15209 AC_VERB_GET_PIN_SENSE, 0)
15210 & AC_PINSENSE_PRESENCE;
15211 bits = present ? HDA_AMP_MUTE : 0;
15212 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15213 AMP_IN_MUTE(0), bits);
15214 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15215 AMP_IN_MUTE(0), bits);
15218 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15220 unsigned int present;
15221 unsigned char bits;
15223 present = snd_hda_codec_read(codec, 0x21, 0,
15224 AC_VERB_GET_PIN_SENSE, 0)
15225 & AC_PINSENSE_PRESENCE;
15226 bits = present ? HDA_AMP_MUTE : 0;
15227 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15228 AMP_IN_MUTE(0), bits);
15229 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15230 AMP_IN_MUTE(0), bits);
15231 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15232 AMP_IN_MUTE(0), bits);
15233 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15234 AMP_IN_MUTE(0), bits);
15237 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15239 unsigned int present;
15240 unsigned char bits;
15242 present = snd_hda_codec_read(codec, 0x15, 0,
15243 AC_VERB_GET_PIN_SENSE, 0)
15244 & AC_PINSENSE_PRESENCE;
15245 bits = present ? HDA_AMP_MUTE : 0;
15246 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15247 AMP_IN_MUTE(0), bits);
15248 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15249 AMP_IN_MUTE(0), bits);
15250 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15251 AMP_IN_MUTE(0), bits);
15252 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15253 AMP_IN_MUTE(0), bits);
15256 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15258 unsigned int present;
15259 unsigned char bits;
15261 present = snd_hda_codec_read(codec, 0x1b, 0,
15262 AC_VERB_GET_PIN_SENSE, 0)
15263 & AC_PINSENSE_PRESENCE;
15264 bits = present ? 0 : PIN_OUT;
15265 snd_hda_codec_write(codec, 0x14, 0,
15266 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15269 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15271 unsigned int present1, present2;
15273 present1 = snd_hda_codec_read(codec, 0x21, 0,
15274 AC_VERB_GET_PIN_SENSE, 0)
15275 & AC_PINSENSE_PRESENCE;
15276 present2 = snd_hda_codec_read(codec, 0x15, 0,
15277 AC_VERB_GET_PIN_SENSE, 0)
15278 & AC_PINSENSE_PRESENCE;
15280 if (present1 || present2) {
15281 snd_hda_codec_write_cache(codec, 0x14, 0,
15282 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15284 snd_hda_codec_write_cache(codec, 0x14, 0,
15285 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15289 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15291 unsigned int present1, present2;
15293 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15294 AC_VERB_GET_PIN_SENSE, 0)
15295 & AC_PINSENSE_PRESENCE;
15296 present2 = snd_hda_codec_read(codec, 0x15, 0,
15297 AC_VERB_GET_PIN_SENSE, 0)
15298 & AC_PINSENSE_PRESENCE;
15300 if (present1 || present2) {
15301 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15302 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15303 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15304 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15306 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15307 AMP_IN_MUTE(0), 0);
15308 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15309 AMP_IN_MUTE(0), 0);
15313 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15315 unsigned int present;
15317 present = snd_hda_codec_read(codec, 0x18, 0,
15318 AC_VERB_GET_PIN_SENSE, 0)
15319 & AC_PINSENSE_PRESENCE;
15320 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15321 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15322 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15323 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15324 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15325 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15326 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15327 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15330 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15333 switch (res >> 26) {
15334 case ALC880_HP_EVENT:
15335 alc663_m51va_speaker_automute(codec);
15337 case ALC880_MIC_EVENT:
15338 alc663_m51va_mic_automute(codec);
15343 static void alc663_m51va_inithook(struct hda_codec *codec)
15345 alc663_m51va_speaker_automute(codec);
15346 alc663_m51va_mic_automute(codec);
15349 /* ***************** Mode1 ******************************/
15350 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15353 switch (res >> 26) {
15354 case ALC880_HP_EVENT:
15355 alc663_m51va_speaker_automute(codec);
15357 case ALC880_MIC_EVENT:
15358 alc662_eeepc_mic_automute(codec);
15363 static void alc663_mode1_inithook(struct hda_codec *codec)
15365 alc663_m51va_speaker_automute(codec);
15366 alc662_eeepc_mic_automute(codec);
15368 /* ***************** Mode2 ******************************/
15369 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15372 switch (res >> 26) {
15373 case ALC880_HP_EVENT:
15374 alc662_f5z_speaker_automute(codec);
15376 case ALC880_MIC_EVENT:
15377 alc662_eeepc_mic_automute(codec);
15382 static void alc662_mode2_inithook(struct hda_codec *codec)
15384 alc662_f5z_speaker_automute(codec);
15385 alc662_eeepc_mic_automute(codec);
15387 /* ***************** Mode3 ******************************/
15388 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15391 switch (res >> 26) {
15392 case ALC880_HP_EVENT:
15393 alc663_two_hp_m1_speaker_automute(codec);
15395 case ALC880_MIC_EVENT:
15396 alc662_eeepc_mic_automute(codec);
15401 static void alc663_mode3_inithook(struct hda_codec *codec)
15403 alc663_two_hp_m1_speaker_automute(codec);
15404 alc662_eeepc_mic_automute(codec);
15406 /* ***************** Mode4 ******************************/
15407 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15410 switch (res >> 26) {
15411 case ALC880_HP_EVENT:
15412 alc663_21jd_two_speaker_automute(codec);
15414 case ALC880_MIC_EVENT:
15415 alc662_eeepc_mic_automute(codec);
15420 static void alc663_mode4_inithook(struct hda_codec *codec)
15422 alc663_21jd_two_speaker_automute(codec);
15423 alc662_eeepc_mic_automute(codec);
15425 /* ***************** Mode5 ******************************/
15426 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15429 switch (res >> 26) {
15430 case ALC880_HP_EVENT:
15431 alc663_15jd_two_speaker_automute(codec);
15433 case ALC880_MIC_EVENT:
15434 alc662_eeepc_mic_automute(codec);
15439 static void alc663_mode5_inithook(struct hda_codec *codec)
15441 alc663_15jd_two_speaker_automute(codec);
15442 alc662_eeepc_mic_automute(codec);
15444 /* ***************** Mode6 ******************************/
15445 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15448 switch (res >> 26) {
15449 case ALC880_HP_EVENT:
15450 alc663_two_hp_m2_speaker_automute(codec);
15452 case ALC880_MIC_EVENT:
15453 alc662_eeepc_mic_automute(codec);
15458 static void alc663_mode6_inithook(struct hda_codec *codec)
15460 alc663_two_hp_m2_speaker_automute(codec);
15461 alc662_eeepc_mic_automute(codec);
15464 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15466 unsigned int present;
15467 unsigned char bits;
15469 present = snd_hda_codec_read(codec, 0x21, 0,
15470 AC_VERB_GET_PIN_SENSE, 0)
15471 & AC_PINSENSE_PRESENCE;
15472 bits = present ? HDA_AMP_MUTE : 0;
15473 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15474 HDA_AMP_MUTE, bits);
15475 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15476 HDA_AMP_MUTE, bits);
15479 static void alc663_g71v_front_automute(struct hda_codec *codec)
15481 unsigned int present;
15482 unsigned char bits;
15484 present = snd_hda_codec_read(codec, 0x15, 0,
15485 AC_VERB_GET_PIN_SENSE, 0)
15486 & AC_PINSENSE_PRESENCE;
15487 bits = present ? HDA_AMP_MUTE : 0;
15488 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15489 HDA_AMP_MUTE, bits);
15492 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15495 switch (res >> 26) {
15496 case ALC880_HP_EVENT:
15497 alc663_g71v_hp_automute(codec);
15499 case ALC880_FRONT_EVENT:
15500 alc663_g71v_front_automute(codec);
15502 case ALC880_MIC_EVENT:
15503 alc662_eeepc_mic_automute(codec);
15508 static void alc663_g71v_inithook(struct hda_codec *codec)
15510 alc663_g71v_front_automute(codec);
15511 alc663_g71v_hp_automute(codec);
15512 alc662_eeepc_mic_automute(codec);
15515 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15518 switch (res >> 26) {
15519 case ALC880_HP_EVENT:
15520 alc663_m51va_speaker_automute(codec);
15522 case ALC880_MIC_EVENT:
15523 alc662_eeepc_mic_automute(codec);
15528 static void alc663_g50v_inithook(struct hda_codec *codec)
15530 alc663_m51va_speaker_automute(codec);
15531 alc662_eeepc_mic_automute(codec);
15534 /* bind hp and internal speaker mute (with plug check) */
15535 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15536 struct snd_ctl_elem_value *ucontrol)
15538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15539 long *valp = ucontrol->value.integer.value;
15542 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15544 valp[0] ? 0 : HDA_AMP_MUTE);
15545 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15547 valp[1] ? 0 : HDA_AMP_MUTE);
15549 alc262_hippo1_automute(codec);
15553 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15554 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15557 .name = "Master Playback Switch",
15558 .info = snd_hda_mixer_amp_switch_info,
15559 .get = snd_hda_mixer_amp_switch_get,
15560 .put = alc662_ecs_master_sw_put,
15561 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15564 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15565 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15566 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15568 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15569 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15570 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15574 #ifdef CONFIG_SND_HDA_POWER_SAVE
15575 #define alc662_loopbacks alc880_loopbacks
15579 /* pcm configuration: identiacal with ALC880 */
15580 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15581 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15582 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15583 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15586 * configuration and preset
15588 static const char *alc662_models[ALC662_MODEL_LAST] = {
15589 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15590 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15591 [ALC662_3ST_6ch] = "3stack-6ch",
15592 [ALC662_5ST_DIG] = "6stack-dig",
15593 [ALC662_LENOVO_101E] = "lenovo-101e",
15594 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15595 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15596 [ALC662_ECS] = "ecs",
15597 [ALC663_ASUS_M51VA] = "m51va",
15598 [ALC663_ASUS_G71V] = "g71v",
15599 [ALC663_ASUS_H13] = "h13",
15600 [ALC663_ASUS_G50V] = "g50v",
15601 [ALC663_ASUS_MODE1] = "asus-mode1",
15602 [ALC662_ASUS_MODE2] = "asus-mode2",
15603 [ALC663_ASUS_MODE3] = "asus-mode3",
15604 [ALC663_ASUS_MODE4] = "asus-mode4",
15605 [ALC663_ASUS_MODE5] = "asus-mode5",
15606 [ALC663_ASUS_MODE6] = "asus-mode6",
15607 [ALC662_AUTO] = "auto",
15610 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15611 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15612 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
15613 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15614 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15615 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15616 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15617 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15618 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15619 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15620 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15621 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15622 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15623 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15624 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15625 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15626 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15627 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15628 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15629 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15630 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15631 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15632 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15633 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15634 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15635 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15636 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15637 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15638 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15639 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15640 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15641 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15642 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15643 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15644 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15645 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15646 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15647 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15648 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15649 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15650 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15651 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15652 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15656 static struct alc_config_preset alc662_presets[] = {
15657 [ALC662_3ST_2ch_DIG] = {
15658 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15659 .init_verbs = { alc662_init_verbs },
15660 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15661 .dac_nids = alc662_dac_nids,
15662 .dig_out_nid = ALC662_DIGOUT_NID,
15663 .dig_in_nid = ALC662_DIGIN_NID,
15664 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15665 .channel_mode = alc662_3ST_2ch_modes,
15666 .input_mux = &alc662_capture_source,
15668 [ALC662_3ST_6ch_DIG] = {
15669 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15670 alc662_capture_mixer },
15671 .init_verbs = { alc662_init_verbs },
15672 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15673 .dac_nids = alc662_dac_nids,
15674 .dig_out_nid = ALC662_DIGOUT_NID,
15675 .dig_in_nid = ALC662_DIGIN_NID,
15676 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15677 .channel_mode = alc662_3ST_6ch_modes,
15679 .input_mux = &alc662_capture_source,
15681 [ALC662_3ST_6ch] = {
15682 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15683 alc662_capture_mixer },
15684 .init_verbs = { alc662_init_verbs },
15685 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15686 .dac_nids = alc662_dac_nids,
15687 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15688 .channel_mode = alc662_3ST_6ch_modes,
15690 .input_mux = &alc662_capture_source,
15692 [ALC662_5ST_DIG] = {
15693 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15694 alc662_capture_mixer },
15695 .init_verbs = { alc662_init_verbs },
15696 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15697 .dac_nids = alc662_dac_nids,
15698 .dig_out_nid = ALC662_DIGOUT_NID,
15699 .dig_in_nid = ALC662_DIGIN_NID,
15700 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15701 .channel_mode = alc662_5stack_modes,
15702 .input_mux = &alc662_capture_source,
15704 [ALC662_LENOVO_101E] = {
15705 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15706 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15707 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15708 .dac_nids = alc662_dac_nids,
15709 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15710 .channel_mode = alc662_3ST_2ch_modes,
15711 .input_mux = &alc662_lenovo_101e_capture_source,
15712 .unsol_event = alc662_lenovo_101e_unsol_event,
15713 .init_hook = alc662_lenovo_101e_all_automute,
15715 [ALC662_ASUS_EEEPC_P701] = {
15716 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15717 .init_verbs = { alc662_init_verbs,
15718 alc662_eeepc_sue_init_verbs },
15719 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15720 .dac_nids = alc662_dac_nids,
15721 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15722 .channel_mode = alc662_3ST_2ch_modes,
15723 .input_mux = &alc662_eeepc_capture_source,
15724 .unsol_event = alc662_eeepc_unsol_event,
15725 .init_hook = alc662_eeepc_inithook,
15727 [ALC662_ASUS_EEEPC_EP20] = {
15728 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15729 alc662_chmode_mixer },
15730 .init_verbs = { alc662_init_verbs,
15731 alc662_eeepc_ep20_sue_init_verbs },
15732 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15733 .dac_nids = alc662_dac_nids,
15734 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15735 .channel_mode = alc662_3ST_6ch_modes,
15736 .input_mux = &alc662_lenovo_101e_capture_source,
15737 .unsol_event = alc662_eeepc_ep20_unsol_event,
15738 .init_hook = alc662_eeepc_ep20_inithook,
15741 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15742 .init_verbs = { alc662_init_verbs,
15743 alc662_ecs_init_verbs },
15744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15745 .dac_nids = alc662_dac_nids,
15746 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15747 .channel_mode = alc662_3ST_2ch_modes,
15748 .input_mux = &alc662_eeepc_capture_source,
15749 .unsol_event = alc662_eeepc_unsol_event,
15750 .init_hook = alc662_eeepc_inithook,
15752 [ALC663_ASUS_M51VA] = {
15753 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15754 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15755 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15756 .dac_nids = alc662_dac_nids,
15757 .dig_out_nid = ALC662_DIGOUT_NID,
15758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15759 .channel_mode = alc662_3ST_2ch_modes,
15760 .input_mux = &alc663_m51va_capture_source,
15761 .unsol_event = alc663_m51va_unsol_event,
15762 .init_hook = alc663_m51va_inithook,
15764 [ALC663_ASUS_G71V] = {
15765 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15766 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15767 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15768 .dac_nids = alc662_dac_nids,
15769 .dig_out_nid = ALC662_DIGOUT_NID,
15770 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15771 .channel_mode = alc662_3ST_2ch_modes,
15772 .input_mux = &alc662_eeepc_capture_source,
15773 .unsol_event = alc663_g71v_unsol_event,
15774 .init_hook = alc663_g71v_inithook,
15776 [ALC663_ASUS_H13] = {
15777 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15778 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15779 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15780 .dac_nids = alc662_dac_nids,
15781 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15782 .channel_mode = alc662_3ST_2ch_modes,
15783 .input_mux = &alc663_m51va_capture_source,
15784 .unsol_event = alc663_m51va_unsol_event,
15785 .init_hook = alc663_m51va_inithook,
15787 [ALC663_ASUS_G50V] = {
15788 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15789 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15790 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15791 .dac_nids = alc662_dac_nids,
15792 .dig_out_nid = ALC662_DIGOUT_NID,
15793 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15794 .channel_mode = alc662_3ST_6ch_modes,
15795 .input_mux = &alc663_capture_source,
15796 .unsol_event = alc663_g50v_unsol_event,
15797 .init_hook = alc663_g50v_inithook,
15799 [ALC663_ASUS_MODE1] = {
15800 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
15801 .init_verbs = { alc662_init_verbs,
15802 alc663_21jd_amic_init_verbs },
15803 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15805 .dac_nids = alc662_dac_nids,
15806 .dig_out_nid = ALC662_DIGOUT_NID,
15807 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15808 .channel_mode = alc662_3ST_2ch_modes,
15809 .input_mux = &alc662_eeepc_capture_source,
15810 .unsol_event = alc663_mode1_unsol_event,
15811 .init_hook = alc663_mode1_inithook,
15813 [ALC662_ASUS_MODE2] = {
15814 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
15815 .init_verbs = { alc662_init_verbs,
15816 alc662_1bjd_amic_init_verbs },
15817 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15818 .dac_nids = alc662_dac_nids,
15819 .dig_out_nid = ALC662_DIGOUT_NID,
15820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15821 .channel_mode = alc662_3ST_2ch_modes,
15822 .input_mux = &alc662_eeepc_capture_source,
15823 .unsol_event = alc662_mode2_unsol_event,
15824 .init_hook = alc662_mode2_inithook,
15826 [ALC663_ASUS_MODE3] = {
15827 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
15828 .init_verbs = { alc662_init_verbs,
15829 alc663_two_hp_amic_m1_init_verbs },
15830 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15832 .dac_nids = alc662_dac_nids,
15833 .dig_out_nid = ALC662_DIGOUT_NID,
15834 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15835 .channel_mode = alc662_3ST_2ch_modes,
15836 .input_mux = &alc662_eeepc_capture_source,
15837 .unsol_event = alc663_mode3_unsol_event,
15838 .init_hook = alc663_mode3_inithook,
15840 [ALC663_ASUS_MODE4] = {
15841 .mixers = { alc663_asus_21jd_clfe_mixer,
15842 alc662_auto_capture_mixer},
15843 .init_verbs = { alc662_init_verbs,
15844 alc663_21jd_amic_init_verbs},
15845 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15847 .dac_nids = alc662_dac_nids,
15848 .dig_out_nid = ALC662_DIGOUT_NID,
15849 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15850 .channel_mode = alc662_3ST_2ch_modes,
15851 .input_mux = &alc662_eeepc_capture_source,
15852 .unsol_event = alc663_mode4_unsol_event,
15853 .init_hook = alc663_mode4_inithook,
15855 [ALC663_ASUS_MODE5] = {
15856 .mixers = { alc663_asus_15jd_clfe_mixer,
15857 alc662_auto_capture_mixer },
15858 .init_verbs = { alc662_init_verbs,
15859 alc663_15jd_amic_init_verbs },
15860 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15862 .dac_nids = alc662_dac_nids,
15863 .dig_out_nid = ALC662_DIGOUT_NID,
15864 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15865 .channel_mode = alc662_3ST_2ch_modes,
15866 .input_mux = &alc662_eeepc_capture_source,
15867 .unsol_event = alc663_mode5_unsol_event,
15868 .init_hook = alc663_mode5_inithook,
15870 [ALC663_ASUS_MODE6] = {
15871 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
15872 .init_verbs = { alc662_init_verbs,
15873 alc663_two_hp_amic_m2_init_verbs },
15874 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15876 .dac_nids = alc662_dac_nids,
15877 .dig_out_nid = ALC662_DIGOUT_NID,
15878 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15879 .channel_mode = alc662_3ST_2ch_modes,
15880 .input_mux = &alc662_eeepc_capture_source,
15881 .unsol_event = alc663_mode6_unsol_event,
15882 .init_hook = alc663_mode6_inithook,
15888 * BIOS auto configuration
15891 /* add playback controls from the parsed DAC table */
15892 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15893 const struct auto_pin_cfg *cfg)
15896 static const char *chname[4] = {
15897 "Front", "Surround", NULL /*CLFE*/, "Side"
15902 for (i = 0; i < cfg->line_outs; i++) {
15903 if (!spec->multiout.dac_nids[i])
15905 nid = alc880_idx_to_dac(i);
15908 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15909 "Center Playback Volume",
15910 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15914 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15915 "LFE Playback Volume",
15916 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15920 err = add_control(spec, ALC_CTL_BIND_MUTE,
15921 "Center Playback Switch",
15922 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
15926 err = add_control(spec, ALC_CTL_BIND_MUTE,
15927 "LFE Playback Switch",
15928 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
15933 sprintf(name, "%s Playback Volume", chname[i]);
15934 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15935 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
15939 sprintf(name, "%s Playback Switch", chname[i]);
15940 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15941 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
15950 /* add playback controls for speaker and HP outputs */
15951 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
15962 /* ALC663 has a mono output pin on 0x17 */
15963 sprintf(name, "%s Playback Switch", pfx);
15964 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15965 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
15969 if (alc880_is_fixed_pin(pin)) {
15970 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15971 /* printk("DAC nid=%x\n",nid); */
15972 /* specify the DAC as the extra output */
15973 if (!spec->multiout.hp_nid)
15974 spec->multiout.hp_nid = nid;
15976 spec->multiout.extra_out_nid[0] = nid;
15977 /* control HP volume/switch on the output mixer amp */
15978 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15979 sprintf(name, "%s Playback Volume", pfx);
15980 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15981 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
15984 sprintf(name, "%s Playback Switch", pfx);
15985 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15986 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
15989 } else if (alc880_is_multi_pin(pin)) {
15990 /* set manual connection */
15991 /* we have only a switch on HP-out PIN */
15992 sprintf(name, "%s Playback Switch", pfx);
15993 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15994 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16001 /* create playback/capture controls for input pins */
16002 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16003 const struct auto_pin_cfg *cfg)
16005 struct hda_input_mux *imux = &spec->private_imux;
16008 for (i = 0; i < AUTO_PIN_LAST; i++) {
16009 if (alc880_is_input_pin(cfg->input_pins[i])) {
16010 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16011 err = new_analog_input(spec, cfg->input_pins[i],
16012 auto_pin_cfg_labels[i],
16016 imux->items[imux->num_items].label =
16017 auto_pin_cfg_labels[i];
16018 imux->items[imux->num_items].index =
16019 alc880_input_pin_idx(cfg->input_pins[i]);
16026 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16027 hda_nid_t nid, int pin_type,
16030 alc_set_pin_output(codec, nid, pin_type);
16031 /* need the manual connection? */
16032 if (alc880_is_multi_pin(nid)) {
16033 struct alc_spec *spec = codec->spec;
16034 int idx = alc880_multi_pin_idx(nid);
16035 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16036 AC_VERB_SET_CONNECT_SEL,
16037 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16041 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16043 struct alc_spec *spec = codec->spec;
16046 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16047 for (i = 0; i <= HDA_SIDE; i++) {
16048 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16049 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16051 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16056 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16058 struct alc_spec *spec = codec->spec;
16061 pin = spec->autocfg.hp_pins[0];
16062 if (pin) /* connect to front */
16064 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16065 pin = spec->autocfg.speaker_pins[0];
16067 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16070 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16071 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16073 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16075 struct alc_spec *spec = codec->spec;
16078 for (i = 0; i < AUTO_PIN_LAST; i++) {
16079 hda_nid_t nid = spec->autocfg.input_pins[i];
16080 if (alc662_is_input_pin(nid)) {
16081 snd_hda_codec_write(codec, nid, 0,
16082 AC_VERB_SET_PIN_WIDGET_CONTROL,
16083 (i <= AUTO_PIN_FRONT_MIC ?
16084 PIN_VREF80 : PIN_IN));
16085 if (nid != ALC662_PIN_CD_NID)
16086 snd_hda_codec_write(codec, nid, 0,
16087 AC_VERB_SET_AMP_GAIN_MUTE,
16093 #define alc662_auto_init_input_src alc882_auto_init_input_src
16095 static int alc662_parse_auto_config(struct hda_codec *codec)
16097 struct alc_spec *spec = codec->spec;
16099 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16101 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16105 if (!spec->autocfg.line_outs)
16106 return 0; /* can't find valid BIOS pin config */
16108 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16111 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16114 err = alc662_auto_create_extra_out(spec,
16115 spec->autocfg.speaker_pins[0],
16119 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16123 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16127 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16129 if (spec->autocfg.dig_out_pin)
16130 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16132 if (spec->kctl_alloc)
16133 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
16135 spec->num_mux_defs = 1;
16136 spec->input_mux = &spec->private_imux;
16138 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
16139 if (codec->vendor_id == 0x10ec0663)
16140 spec->init_verbs[spec->num_init_verbs++] =
16141 alc663_auto_init_verbs;
16143 err = alc_auto_add_mic_boost(codec);
16147 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16148 spec->num_mixers++;
16152 /* additional initialization for auto-configuration model */
16153 static void alc662_auto_init(struct hda_codec *codec)
16155 struct alc_spec *spec = codec->spec;
16156 alc662_auto_init_multi_out(codec);
16157 alc662_auto_init_hp_out(codec);
16158 alc662_auto_init_analog_input(codec);
16159 alc662_auto_init_input_src(codec);
16160 if (spec->unsol_event)
16161 alc_sku_automute(codec);
16164 static int patch_alc662(struct hda_codec *codec)
16166 struct alc_spec *spec;
16167 int err, board_config;
16169 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16173 codec->spec = spec;
16175 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16177 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16180 if (board_config < 0) {
16181 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16182 "trying auto-probe from BIOS...\n");
16183 board_config = ALC662_AUTO;
16186 if (board_config == ALC662_AUTO) {
16187 /* automatic parse from the BIOS config */
16188 err = alc662_parse_auto_config(codec);
16194 "hda_codec: Cannot set up configuration "
16195 "from BIOS. Using base mode...\n");
16196 board_config = ALC662_3ST_2ch_DIG;
16200 if (board_config != ALC662_AUTO)
16201 setup_preset(spec, &alc662_presets[board_config]);
16203 if (codec->vendor_id == 0x10ec0663) {
16204 spec->stream_name_analog = "ALC663 Analog";
16205 spec->stream_name_digital = "ALC663 Digital";
16207 spec->stream_name_analog = "ALC662 Analog";
16208 spec->stream_name_digital = "ALC662 Digital";
16211 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16212 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16214 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16215 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16217 spec->adc_nids = alc662_adc_nids;
16218 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16219 spec->capsrc_nids = alc662_capsrc_nids;
16221 spec->vmaster_nid = 0x02;
16223 codec->patch_ops = alc_patch_ops;
16224 if (board_config == ALC662_AUTO)
16225 spec->init_hook = alc662_auto_init;
16226 #ifdef CONFIG_SND_HDA_POWER_SAVE
16227 if (!spec->loopback.amplist)
16228 spec->loopback.amplist = alc662_loopbacks;
16237 struct hda_codec_preset snd_hda_preset_realtek[] = {
16238 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16239 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16240 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16241 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16242 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16243 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16244 .patch = patch_alc861 },
16245 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16246 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16247 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16248 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16249 .patch = patch_alc883 },
16250 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16251 .patch = patch_alc662 },
16252 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16253 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16254 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16255 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16256 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16257 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16258 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16259 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16260 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16261 {} /* terminator */