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_HP_DC7600] = "hp-dc7600",
5243 [ALC260_FUJITSU_S702X] = "fujitsu",
5244 [ALC260_ACER] = "acer",
5245 [ALC260_WILL] = "will",
5246 [ALC260_REPLACER_672V] = "replacer",
5247 #ifdef CONFIG_SND_DEBUG
5248 [ALC260_TEST] = "test",
5250 [ALC260_AUTO] = "auto",
5253 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5254 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5255 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5256 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5257 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5258 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5259 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5260 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5261 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5262 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5263 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5264 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5265 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5266 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5267 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5268 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5269 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5270 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5271 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5275 static struct alc_config_preset alc260_presets[] = {
5277 .mixers = { alc260_base_output_mixer,
5279 alc260_pc_beep_mixer,
5280 alc260_capture_mixer },
5281 .init_verbs = { alc260_init_verbs },
5282 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5283 .dac_nids = alc260_dac_nids,
5284 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5285 .adc_nids = alc260_adc_nids,
5286 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5287 .channel_mode = alc260_modes,
5288 .input_mux = &alc260_capture_source,
5291 .mixers = { alc260_hp_output_mixer,
5293 alc260_capture_alt_mixer },
5294 .init_verbs = { alc260_init_verbs,
5295 alc260_hp_unsol_verbs },
5296 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5297 .dac_nids = alc260_dac_nids,
5298 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5299 .adc_nids = alc260_hp_adc_nids,
5300 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5301 .channel_mode = alc260_modes,
5302 .input_mux = &alc260_capture_source,
5303 .unsol_event = alc260_hp_unsol_event,
5304 .init_hook = alc260_hp_automute,
5306 [ALC260_HP_DC7600] = {
5307 .mixers = { alc260_hp_dc7600_mixer,
5309 alc260_capture_alt_mixer },
5310 .init_verbs = { alc260_init_verbs,
5311 alc260_hp_dc7600_verbs },
5312 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5313 .dac_nids = alc260_dac_nids,
5314 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5315 .adc_nids = alc260_hp_adc_nids,
5316 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5317 .channel_mode = alc260_modes,
5318 .input_mux = &alc260_capture_source,
5319 .unsol_event = alc260_hp_3012_unsol_event,
5320 .init_hook = alc260_hp_3012_automute,
5322 [ALC260_HP_3013] = {
5323 .mixers = { alc260_hp_3013_mixer,
5325 alc260_capture_alt_mixer },
5326 .init_verbs = { alc260_hp_3013_init_verbs,
5327 alc260_hp_3013_unsol_verbs },
5328 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5329 .dac_nids = alc260_dac_nids,
5330 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5331 .adc_nids = alc260_hp_adc_nids,
5332 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5333 .channel_mode = alc260_modes,
5334 .input_mux = &alc260_capture_source,
5335 .unsol_event = alc260_hp_3013_unsol_event,
5336 .init_hook = alc260_hp_3013_automute,
5338 [ALC260_FUJITSU_S702X] = {
5339 .mixers = { alc260_fujitsu_mixer,
5340 alc260_capture_mixer },
5341 .init_verbs = { alc260_fujitsu_init_verbs },
5342 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5343 .dac_nids = alc260_dac_nids,
5344 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5345 .adc_nids = alc260_dual_adc_nids,
5346 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5347 .channel_mode = alc260_modes,
5348 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5349 .input_mux = alc260_fujitsu_capture_sources,
5352 .mixers = { alc260_acer_mixer,
5353 alc260_capture_mixer },
5354 .init_verbs = { alc260_acer_init_verbs },
5355 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5356 .dac_nids = alc260_dac_nids,
5357 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5358 .adc_nids = alc260_dual_adc_nids,
5359 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5360 .channel_mode = alc260_modes,
5361 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5362 .input_mux = alc260_acer_capture_sources,
5365 .mixers = { alc260_will_mixer,
5366 alc260_capture_mixer },
5367 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5368 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5369 .dac_nids = alc260_dac_nids,
5370 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5371 .adc_nids = alc260_adc_nids,
5372 .dig_out_nid = ALC260_DIGOUT_NID,
5373 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5374 .channel_mode = alc260_modes,
5375 .input_mux = &alc260_capture_source,
5377 [ALC260_REPLACER_672V] = {
5378 .mixers = { alc260_replacer_672v_mixer,
5379 alc260_capture_mixer },
5380 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5381 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5382 .dac_nids = alc260_dac_nids,
5383 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5384 .adc_nids = alc260_adc_nids,
5385 .dig_out_nid = ALC260_DIGOUT_NID,
5386 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5387 .channel_mode = alc260_modes,
5388 .input_mux = &alc260_capture_source,
5389 .unsol_event = alc260_replacer_672v_unsol_event,
5390 .init_hook = alc260_replacer_672v_automute,
5392 #ifdef CONFIG_SND_DEBUG
5394 .mixers = { alc260_test_mixer,
5395 alc260_capture_mixer },
5396 .init_verbs = { alc260_test_init_verbs },
5397 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5398 .dac_nids = alc260_test_dac_nids,
5399 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5400 .adc_nids = alc260_test_adc_nids,
5401 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5402 .channel_mode = alc260_modes,
5403 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5404 .input_mux = alc260_test_capture_sources,
5409 static int patch_alc260(struct hda_codec *codec)
5411 struct alc_spec *spec;
5412 int err, board_config;
5414 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5420 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5423 if (board_config < 0) {
5424 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5425 "trying auto-probe from BIOS...\n");
5426 board_config = ALC260_AUTO;
5429 if (board_config == ALC260_AUTO) {
5430 /* automatic parse from the BIOS config */
5431 err = alc260_parse_auto_config(codec);
5437 "hda_codec: Cannot set up configuration "
5438 "from BIOS. Using base mode...\n");
5439 board_config = ALC260_BASIC;
5443 if (board_config != ALC260_AUTO)
5444 setup_preset(spec, &alc260_presets[board_config]);
5446 spec->stream_name_analog = "ALC260 Analog";
5447 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5448 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5450 spec->stream_name_digital = "ALC260 Digital";
5451 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5452 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5454 spec->vmaster_nid = 0x08;
5456 codec->patch_ops = alc_patch_ops;
5457 if (board_config == ALC260_AUTO)
5458 spec->init_hook = alc260_auto_init;
5459 #ifdef CONFIG_SND_HDA_POWER_SAVE
5460 if (!spec->loopback.amplist)
5461 spec->loopback.amplist = alc260_loopbacks;
5471 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5472 * configuration. Each pin widget can choose any input DACs and a mixer.
5473 * Each ADC is connected from a mixer of all inputs. This makes possible
5474 * 6-channel independent captures.
5476 * In addition, an independent DAC for the multi-playback (not used in this
5479 #define ALC882_DIGOUT_NID 0x06
5480 #define ALC882_DIGIN_NID 0x0a
5482 static struct hda_channel_mode alc882_ch_modes[1] = {
5486 static hda_nid_t alc882_dac_nids[4] = {
5487 /* front, rear, clfe, rear_surr */
5488 0x02, 0x03, 0x04, 0x05
5491 /* identical with ALC880 */
5492 #define alc882_adc_nids alc880_adc_nids
5493 #define alc882_adc_nids_alt alc880_adc_nids_alt
5495 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5496 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5499 /* FIXME: should be a matrix-type input source selection */
5501 static struct hda_input_mux alc882_capture_source = {
5505 { "Front Mic", 0x1 },
5510 #define alc882_mux_enum_info alc_mux_enum_info
5511 #define alc882_mux_enum_get alc_mux_enum_get
5513 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5514 struct snd_ctl_elem_value *ucontrol)
5516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5517 struct alc_spec *spec = codec->spec;
5518 const struct hda_input_mux *imux = spec->input_mux;
5519 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5520 hda_nid_t nid = spec->capsrc_nids ?
5521 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5522 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5523 unsigned int i, idx;
5525 idx = ucontrol->value.enumerated.item[0];
5526 if (idx >= imux->num_items)
5527 idx = imux->num_items - 1;
5528 if (*cur_val == idx)
5530 for (i = 0; i < imux->num_items; i++) {
5531 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5532 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5533 imux->items[i].index,
5543 static struct hda_verb alc882_3ST_ch2_init[] = {
5544 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5545 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5546 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5547 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5554 static struct hda_verb alc882_3ST_ch6_init[] = {
5555 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5556 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5557 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5558 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5559 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5560 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5564 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5565 { 2, alc882_3ST_ch2_init },
5566 { 6, alc882_3ST_ch6_init },
5572 static struct hda_verb alc882_sixstack_ch6_init[] = {
5573 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5574 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5575 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5576 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5583 static struct hda_verb alc882_sixstack_ch8_init[] = {
5584 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5585 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5586 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5587 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5591 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5592 { 6, alc882_sixstack_ch6_init },
5593 { 8, alc882_sixstack_ch8_init },
5597 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5603 static struct hda_verb alc885_mbp_ch2_init[] = {
5604 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5605 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5606 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5613 static struct hda_verb alc885_mbp_ch6_init[] = {
5614 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5615 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5616 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5617 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5618 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5622 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5623 { 2, alc885_mbp_ch2_init },
5624 { 6, alc885_mbp_ch6_init },
5628 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5629 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5631 static struct snd_kcontrol_new alc882_base_mixer[] = {
5632 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5633 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5634 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5635 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5636 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5637 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5638 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5639 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5640 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5641 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5642 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5643 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5644 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5648 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5650 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5651 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5652 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5653 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5654 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5658 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5659 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5660 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5661 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5662 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5663 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5664 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5665 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5666 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5667 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5668 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5671 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5672 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5673 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5674 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5675 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5676 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5677 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5679 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5680 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5681 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5682 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5686 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5687 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5688 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5690 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5691 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5692 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5693 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5694 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5695 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5696 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5697 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5698 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5699 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5703 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5704 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5706 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5707 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5708 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5709 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5710 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5711 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5712 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5713 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5714 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5715 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5716 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5717 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5718 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5719 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5723 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5724 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5725 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5727 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5728 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5729 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5730 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5731 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5732 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5734 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5735 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5739 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5742 .name = "Channel Mode",
5743 .info = alc_ch_mode_info,
5744 .get = alc_ch_mode_get,
5745 .put = alc_ch_mode_put,
5750 static struct hda_verb alc882_init_verbs[] = {
5751 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5757 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5758 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5760 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5761 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5762 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5765 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5766 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5768 /* Front Pin: output 0 (0x0c) */
5769 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5771 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5772 /* Rear Pin: output 1 (0x0d) */
5773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5775 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5776 /* CLFE Pin: output 2 (0x0e) */
5777 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5778 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5779 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5780 /* Side Pin: output 3 (0x0f) */
5781 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5782 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5783 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5784 /* Mic (rear) pin: input vref at 80% */
5785 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5786 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5787 /* Front Mic pin: input vref at 80% */
5788 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5789 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5790 /* Line In pin: input */
5791 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5792 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5793 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5794 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5795 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5796 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5797 /* CD pin widget for input */
5798 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5800 /* FIXME: use matrix-type input source selection */
5801 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5802 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5803 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5804 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5808 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5809 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5810 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5811 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5813 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5814 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5817 /* ADC1: mute amp left and right */
5818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5819 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5820 /* ADC2: mute amp left and right */
5821 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5822 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5823 /* ADC3: mute amp left and right */
5824 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5825 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5830 static struct hda_verb alc882_eapd_verbs[] = {
5831 /* change to EAPD mode */
5832 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5833 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5838 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5839 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5840 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5842 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5843 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5844 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5845 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5849 static struct hda_verb alc882_macpro_init_verbs[] = {
5850 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5852 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5853 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5854 /* Front Pin: output 0 (0x0c) */
5855 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5857 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5858 /* Front Mic pin: input vref at 80% */
5859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5860 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5861 /* Speaker: output */
5862 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5863 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5864 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5865 /* Headphone output (output 0 - 0x0c) */
5866 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5867 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5868 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5870 /* FIXME: use matrix-type input source selection */
5871 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5872 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5873 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5874 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5875 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5876 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5878 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5879 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5880 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5881 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5883 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5884 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5885 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5886 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5887 /* ADC1: mute amp left and right */
5888 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5889 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5890 /* ADC2: mute amp left and right */
5891 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5892 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5893 /* ADC3: mute amp left and right */
5894 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5895 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5900 /* Macbook Pro rev3 */
5901 static struct hda_verb alc885_mbp3_init_verbs[] = {
5902 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5905 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5909 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5910 /* Front Pin: output 0 (0x0c) */
5911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5913 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5914 /* HP Pin: output 0 (0x0d) */
5915 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5916 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5917 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5918 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5919 /* Mic (rear) pin: input vref at 80% */
5920 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5921 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5922 /* Front Mic pin: input vref at 80% */
5923 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5924 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5925 /* Line In pin: use output 1 when in LineOut mode */
5926 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5927 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5928 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5930 /* FIXME: use matrix-type input source selection */
5931 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5932 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5933 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5934 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5935 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5936 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5938 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5939 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5940 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5941 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5943 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5944 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5945 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5946 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5947 /* ADC1: mute amp left and right */
5948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5949 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5950 /* ADC2: mute amp left and right */
5951 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5952 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5953 /* ADC3: mute amp left and right */
5954 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5955 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5960 /* iMac 24 mixer. */
5961 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5962 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5963 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5967 /* iMac 24 init verbs. */
5968 static struct hda_verb alc885_imac24_init_verbs[] = {
5969 /* Internal speakers: output 0 (0x0c) */
5970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5971 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5972 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5973 /* Internal speakers: output 0 (0x0c) */
5974 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5975 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5976 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5977 /* Headphone: output 0 (0x0c) */
5978 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5979 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5980 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5981 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5982 /* Front Mic: input vref at 80% */
5983 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5984 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5988 /* Toggle speaker-output according to the hp-jack state */
5989 static void alc885_imac24_automute(struct hda_codec *codec)
5991 unsigned int present;
5993 present = snd_hda_codec_read(codec, 0x14, 0,
5994 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5995 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5996 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5997 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5998 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6001 /* Processes unsolicited events. */
6002 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6005 /* Headphone insertion or removal. */
6006 if ((res >> 26) == ALC880_HP_EVENT)
6007 alc885_imac24_automute(codec);
6010 static void alc885_mbp3_automute(struct hda_codec *codec)
6012 unsigned int present;
6014 present = snd_hda_codec_read(codec, 0x15, 0,
6015 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6016 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6017 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6018 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6019 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6022 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6025 /* Headphone insertion or removal. */
6026 if ((res >> 26) == ALC880_HP_EVENT)
6027 alc885_mbp3_automute(codec);
6031 static struct hda_verb alc882_targa_verbs[] = {
6032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6033 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6035 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6036 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6038 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6039 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6040 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6042 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6043 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6044 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6045 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6049 /* toggle speaker-output according to the hp-jack state */
6050 static void alc882_targa_automute(struct hda_codec *codec)
6052 unsigned int present;
6054 present = snd_hda_codec_read(codec, 0x14, 0,
6055 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6056 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6057 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6058 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6062 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6064 /* Looks like the unsol event is incompatible with the standard
6065 * definition. 4bit tag is placed at 26 bit!
6067 if (((res >> 26) == ALC880_HP_EVENT)) {
6068 alc882_targa_automute(codec);
6072 static struct hda_verb alc882_asus_a7j_verbs[] = {
6073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6074 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6076 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6077 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6078 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6080 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6081 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6082 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6084 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6085 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6086 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6090 static struct hda_verb alc882_asus_a7m_verbs[] = {
6091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6094 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6095 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6096 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6098 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6099 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6100 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6102 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6103 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6104 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6108 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6110 unsigned int gpiostate, gpiomask, gpiodir;
6112 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6113 AC_VERB_GET_GPIO_DATA, 0);
6116 gpiostate |= (1 << pin);
6118 gpiostate &= ~(1 << pin);
6120 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6121 AC_VERB_GET_GPIO_MASK, 0);
6122 gpiomask |= (1 << pin);
6124 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6125 AC_VERB_GET_GPIO_DIRECTION, 0);
6126 gpiodir |= (1 << pin);
6129 snd_hda_codec_write(codec, codec->afg, 0,
6130 AC_VERB_SET_GPIO_MASK, gpiomask);
6131 snd_hda_codec_write(codec, codec->afg, 0,
6132 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6136 snd_hda_codec_write(codec, codec->afg, 0,
6137 AC_VERB_SET_GPIO_DATA, gpiostate);
6140 /* set up GPIO at initialization */
6141 static void alc885_macpro_init_hook(struct hda_codec *codec)
6143 alc882_gpio_mute(codec, 0, 0);
6144 alc882_gpio_mute(codec, 1, 0);
6147 /* set up GPIO and update auto-muting at initialization */
6148 static void alc885_imac24_init_hook(struct hda_codec *codec)
6150 alc885_macpro_init_hook(codec);
6151 alc885_imac24_automute(codec);
6155 * generic initialization of ADC, input mixers and output mixers
6157 static struct hda_verb alc882_auto_init_verbs[] = {
6159 * Unmute ADC0-2 and set the default input to mic-in
6161 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6162 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6163 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6164 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6165 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6166 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6168 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6170 * Note: PASD motherboards uses the Line In 2 as the input for
6171 * front panel mic (mic 2)
6173 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6174 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6175 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6176 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6177 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6178 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6181 * Set up output mixers (0x0c - 0x0f)
6183 /* set vol=0 to output mixers */
6184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6185 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6186 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6187 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6188 /* set up input amps for analog loopback */
6189 /* Amp Indices: DAC = 0, mixer = 1 */
6190 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6191 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6192 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6193 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6194 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6195 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6196 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6197 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6198 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6199 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6201 /* FIXME: use matrix-type input source selection */
6202 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6203 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6217 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6222 /* capture mixer elements */
6223 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6224 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6225 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6226 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6227 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6230 /* The multiple "Capture Source" controls confuse alsamixer
6231 * So call somewhat different..
6233 /* .name = "Capture Source", */
6234 .name = "Input Source",
6236 .info = alc882_mux_enum_info,
6237 .get = alc882_mux_enum_get,
6238 .put = alc882_mux_enum_put,
6243 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6244 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6245 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6246 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6247 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6248 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6249 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6252 /* The multiple "Capture Source" controls confuse alsamixer
6253 * So call somewhat different..
6255 /* .name = "Capture Source", */
6256 .name = "Input Source",
6258 .info = alc882_mux_enum_info,
6259 .get = alc882_mux_enum_get,
6260 .put = alc882_mux_enum_put,
6265 #ifdef CONFIG_SND_HDA_POWER_SAVE
6266 #define alc882_loopbacks alc880_loopbacks
6269 /* pcm configuration: identiacal with ALC880 */
6270 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6271 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6272 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6273 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6276 * configuration and preset
6278 static const char *alc882_models[ALC882_MODEL_LAST] = {
6279 [ALC882_3ST_DIG] = "3stack-dig",
6280 [ALC882_6ST_DIG] = "6stack-dig",
6281 [ALC882_ARIMA] = "arima",
6282 [ALC882_W2JC] = "w2jc",
6283 [ALC882_TARGA] = "targa",
6284 [ALC882_ASUS_A7J] = "asus-a7j",
6285 [ALC882_ASUS_A7M] = "asus-a7m",
6286 [ALC885_MACPRO] = "macpro",
6287 [ALC885_MBP3] = "mbp3",
6288 [ALC885_IMAC24] = "imac24",
6289 [ALC882_AUTO] = "auto",
6292 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6293 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6294 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6295 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6296 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6297 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6298 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6299 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6300 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6301 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6302 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6303 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6304 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6308 static struct alc_config_preset alc882_presets[] = {
6309 [ALC882_3ST_DIG] = {
6310 .mixers = { alc882_base_mixer },
6311 .init_verbs = { alc882_init_verbs },
6312 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6313 .dac_nids = alc882_dac_nids,
6314 .dig_out_nid = ALC882_DIGOUT_NID,
6315 .dig_in_nid = ALC882_DIGIN_NID,
6316 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6317 .channel_mode = alc882_ch_modes,
6319 .input_mux = &alc882_capture_source,
6321 [ALC882_6ST_DIG] = {
6322 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6323 .init_verbs = { alc882_init_verbs },
6324 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6325 .dac_nids = alc882_dac_nids,
6326 .dig_out_nid = ALC882_DIGOUT_NID,
6327 .dig_in_nid = ALC882_DIGIN_NID,
6328 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6329 .channel_mode = alc882_sixstack_modes,
6330 .input_mux = &alc882_capture_source,
6333 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6334 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6335 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6336 .dac_nids = alc882_dac_nids,
6337 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6338 .channel_mode = alc882_sixstack_modes,
6339 .input_mux = &alc882_capture_source,
6342 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6343 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6344 alc880_gpio1_init_verbs },
6345 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6346 .dac_nids = alc882_dac_nids,
6347 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6348 .channel_mode = alc880_threestack_modes,
6350 .input_mux = &alc882_capture_source,
6351 .dig_out_nid = ALC882_DIGOUT_NID,
6354 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6355 .init_verbs = { alc885_mbp3_init_verbs,
6356 alc880_gpio1_init_verbs },
6357 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6358 .dac_nids = alc882_dac_nids,
6359 .channel_mode = alc885_mbp_6ch_modes,
6360 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6361 .input_mux = &alc882_capture_source,
6362 .dig_out_nid = ALC882_DIGOUT_NID,
6363 .dig_in_nid = ALC882_DIGIN_NID,
6364 .unsol_event = alc885_mbp3_unsol_event,
6365 .init_hook = alc885_mbp3_automute,
6368 .mixers = { alc882_macpro_mixer },
6369 .init_verbs = { alc882_macpro_init_verbs },
6370 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6371 .dac_nids = alc882_dac_nids,
6372 .dig_out_nid = ALC882_DIGOUT_NID,
6373 .dig_in_nid = ALC882_DIGIN_NID,
6374 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6375 .channel_mode = alc882_ch_modes,
6376 .input_mux = &alc882_capture_source,
6377 .init_hook = alc885_macpro_init_hook,
6380 .mixers = { alc885_imac24_mixer },
6381 .init_verbs = { alc885_imac24_init_verbs },
6382 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6383 .dac_nids = alc882_dac_nids,
6384 .dig_out_nid = ALC882_DIGOUT_NID,
6385 .dig_in_nid = ALC882_DIGIN_NID,
6386 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6387 .channel_mode = alc882_ch_modes,
6388 .input_mux = &alc882_capture_source,
6389 .unsol_event = alc885_imac24_unsol_event,
6390 .init_hook = alc885_imac24_init_hook,
6393 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6394 alc882_capture_mixer },
6395 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6396 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6397 .dac_nids = alc882_dac_nids,
6398 .dig_out_nid = ALC882_DIGOUT_NID,
6399 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6400 .adc_nids = alc882_adc_nids,
6401 .capsrc_nids = alc882_capsrc_nids,
6402 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6403 .channel_mode = alc882_3ST_6ch_modes,
6405 .input_mux = &alc882_capture_source,
6406 .unsol_event = alc882_targa_unsol_event,
6407 .init_hook = alc882_targa_automute,
6409 [ALC882_ASUS_A7J] = {
6410 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6411 alc882_capture_mixer },
6412 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6413 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6414 .dac_nids = alc882_dac_nids,
6415 .dig_out_nid = ALC882_DIGOUT_NID,
6416 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6417 .adc_nids = alc882_adc_nids,
6418 .capsrc_nids = alc882_capsrc_nids,
6419 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6420 .channel_mode = alc882_3ST_6ch_modes,
6422 .input_mux = &alc882_capture_source,
6424 [ALC882_ASUS_A7M] = {
6425 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6426 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6427 alc880_gpio1_init_verbs,
6428 alc882_asus_a7m_verbs },
6429 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6430 .dac_nids = alc882_dac_nids,
6431 .dig_out_nid = ALC882_DIGOUT_NID,
6432 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6433 .channel_mode = alc880_threestack_modes,
6435 .input_mux = &alc882_capture_source,
6444 PINFIX_ABIT_AW9D_MAX
6447 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6448 { 0x15, 0x01080104 }, /* side */
6449 { 0x16, 0x01011012 }, /* rear */
6450 { 0x17, 0x01016011 }, /* clfe */
6454 static const struct alc_pincfg *alc882_pin_fixes[] = {
6455 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6458 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6459 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6464 * BIOS auto configuration
6466 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6467 hda_nid_t nid, int pin_type,
6471 struct alc_spec *spec = codec->spec;
6474 alc_set_pin_output(codec, nid, pin_type);
6475 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6478 idx = spec->multiout.dac_nids[dac_idx] - 2;
6479 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6483 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6485 struct alc_spec *spec = codec->spec;
6488 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6489 for (i = 0; i <= HDA_SIDE; i++) {
6490 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6491 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6493 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6498 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6500 struct alc_spec *spec = codec->spec;
6503 pin = spec->autocfg.hp_pins[0];
6504 if (pin) /* connect to front */
6506 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6507 pin = spec->autocfg.speaker_pins[0];
6509 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6512 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6513 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6515 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6517 struct alc_spec *spec = codec->spec;
6520 for (i = 0; i < AUTO_PIN_LAST; i++) {
6521 hda_nid_t nid = spec->autocfg.input_pins[i];
6526 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6527 unsigned int pincap;
6528 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6529 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6533 snd_hda_codec_write(codec, nid, 0,
6534 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6535 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6536 snd_hda_codec_write(codec, nid, 0,
6537 AC_VERB_SET_AMP_GAIN_MUTE,
6542 static void alc882_auto_init_input_src(struct hda_codec *codec)
6544 struct alc_spec *spec = codec->spec;
6545 const struct hda_input_mux *imux = spec->input_mux;
6548 for (c = 0; c < spec->num_adc_nids; c++) {
6549 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6550 hda_nid_t nid = spec->capsrc_nids[c];
6551 int conns, mute, idx, item;
6553 conns = snd_hda_get_connections(codec, nid, conn_list,
6554 ARRAY_SIZE(conn_list));
6557 for (idx = 0; idx < conns; idx++) {
6558 /* if the current connection is the selected one,
6559 * unmute it as default - otherwise mute it
6561 mute = AMP_IN_MUTE(idx);
6562 for (item = 0; item < imux->num_items; item++) {
6563 if (imux->items[item].index == idx) {
6564 if (spec->cur_mux[c] == item)
6565 mute = AMP_IN_UNMUTE(idx);
6569 snd_hda_codec_write(codec, nid, 0,
6570 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6575 /* add mic boosts if needed */
6576 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6578 struct alc_spec *spec = codec->spec;
6582 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6583 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6584 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6586 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6590 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6591 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6592 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6594 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6601 /* almost identical with ALC880 parser... */
6602 static int alc882_parse_auto_config(struct hda_codec *codec)
6604 struct alc_spec *spec = codec->spec;
6605 int err = alc880_parse_auto_config(codec);
6610 return 0; /* no config found */
6612 err = alc_auto_add_mic_boost(codec);
6616 /* hack - override the init verbs */
6617 spec->init_verbs[0] = alc882_auto_init_verbs;
6619 return 1; /* config found */
6622 /* additional initialization for auto-configuration model */
6623 static void alc882_auto_init(struct hda_codec *codec)
6625 struct alc_spec *spec = codec->spec;
6626 alc882_auto_init_multi_out(codec);
6627 alc882_auto_init_hp_out(codec);
6628 alc882_auto_init_analog_input(codec);
6629 alc882_auto_init_input_src(codec);
6630 if (spec->unsol_event)
6631 alc_sku_automute(codec);
6634 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6636 static int patch_alc882(struct hda_codec *codec)
6638 struct alc_spec *spec;
6639 int err, board_config;
6641 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6647 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6651 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6652 /* Pick up systems that don't supply PCI SSID */
6653 switch (codec->subsystem_id) {
6654 case 0x106b0c00: /* Mac Pro */
6655 board_config = ALC885_MACPRO;
6657 case 0x106b1000: /* iMac 24 */
6658 board_config = ALC885_IMAC24;
6660 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6661 case 0x106b2c00: /* Macbook Pro rev3 */
6662 case 0x106b3600: /* Macbook 3.1 */
6663 board_config = ALC885_MBP3;
6666 /* ALC889A is handled better as ALC888-compatible */
6667 if (codec->revision_id == 0x100103) {
6669 return patch_alc883(codec);
6671 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6672 "trying auto-probe from BIOS...\n");
6673 board_config = ALC882_AUTO;
6677 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6679 if (board_config == ALC882_AUTO) {
6680 /* automatic parse from the BIOS config */
6681 err = alc882_parse_auto_config(codec);
6687 "hda_codec: Cannot set up configuration "
6688 "from BIOS. Using base mode...\n");
6689 board_config = ALC882_3ST_DIG;
6693 if (board_config != ALC882_AUTO)
6694 setup_preset(spec, &alc882_presets[board_config]);
6696 if (codec->vendor_id == 0x10ec0885) {
6697 spec->stream_name_analog = "ALC885 Analog";
6698 spec->stream_name_digital = "ALC885 Digital";
6700 spec->stream_name_analog = "ALC882 Analog";
6701 spec->stream_name_digital = "ALC882 Digital";
6704 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6705 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6706 /* FIXME: setup DAC5 */
6707 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6708 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6710 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6711 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6713 if (!spec->adc_nids && spec->input_mux) {
6714 /* check whether NID 0x07 is valid */
6715 unsigned int wcap = get_wcaps(codec, 0x07);
6717 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6718 if (wcap != AC_WID_AUD_IN) {
6719 spec->adc_nids = alc882_adc_nids_alt;
6720 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6721 spec->capsrc_nids = alc882_capsrc_nids_alt;
6722 spec->mixers[spec->num_mixers] =
6723 alc882_capture_alt_mixer;
6726 spec->adc_nids = alc882_adc_nids;
6727 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6728 spec->capsrc_nids = alc882_capsrc_nids;
6729 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6734 spec->vmaster_nid = 0x0c;
6736 codec->patch_ops = alc_patch_ops;
6737 if (board_config == ALC882_AUTO)
6738 spec->init_hook = alc882_auto_init;
6739 #ifdef CONFIG_SND_HDA_POWER_SAVE
6740 if (!spec->loopback.amplist)
6741 spec->loopback.amplist = alc882_loopbacks;
6750 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6751 * configuration. Each pin widget can choose any input DACs and a mixer.
6752 * Each ADC is connected from a mixer of all inputs. This makes possible
6753 * 6-channel independent captures.
6755 * In addition, an independent DAC for the multi-playback (not used in this
6758 #define ALC883_DIGOUT_NID 0x06
6759 #define ALC883_DIGIN_NID 0x0a
6761 static hda_nid_t alc883_dac_nids[4] = {
6762 /* front, rear, clfe, rear_surr */
6763 0x02, 0x03, 0x04, 0x05
6766 static hda_nid_t alc883_adc_nids[2] = {
6771 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6774 /* FIXME: should be a matrix-type input source selection */
6776 static struct hda_input_mux alc883_capture_source = {
6780 { "Front Mic", 0x1 },
6786 static struct hda_input_mux alc883_3stack_6ch_intel = {
6790 { "Front Mic", 0x0 },
6796 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6804 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6814 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6822 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6826 { "Front Mic", 0x1 },
6831 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6839 #define alc883_mux_enum_info alc_mux_enum_info
6840 #define alc883_mux_enum_get alc_mux_enum_get
6841 /* ALC883 has the ALC882-type input selection */
6842 #define alc883_mux_enum_put alc882_mux_enum_put
6847 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6854 static struct hda_verb alc883_3ST_ch2_init[] = {
6855 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6856 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6857 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6858 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6865 static struct hda_verb alc883_3ST_ch4_init[] = {
6866 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6867 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6868 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6869 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6870 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6877 static struct hda_verb alc883_3ST_ch6_init[] = {
6878 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6879 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6880 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6881 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6882 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6883 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6887 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6888 { 2, alc883_3ST_ch2_init },
6889 { 4, alc883_3ST_ch4_init },
6890 { 6, alc883_3ST_ch6_init },
6896 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6897 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6898 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6899 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6900 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6907 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6908 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6909 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6911 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6912 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6919 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6920 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6921 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6922 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6923 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6924 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6925 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6929 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6930 { 2, alc883_3ST_ch2_intel_init },
6931 { 4, alc883_3ST_ch4_intel_init },
6932 { 6, alc883_3ST_ch6_intel_init },
6938 static struct hda_verb alc883_sixstack_ch6_init[] = {
6939 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6940 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6941 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6942 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6949 static struct hda_verb alc883_sixstack_ch8_init[] = {
6950 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6951 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6952 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6953 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6957 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6958 { 6, alc883_sixstack_ch6_init },
6959 { 8, alc883_sixstack_ch8_init },
6962 static struct hda_verb alc883_medion_eapd_verbs[] = {
6963 /* eanable EAPD on medion laptop */
6964 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6965 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6969 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6970 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6973 static struct snd_kcontrol_new alc883_base_mixer[] = {
6974 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6975 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6976 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6977 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6978 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6979 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6980 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6981 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6982 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6983 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6985 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6986 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6992 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6993 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6994 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6995 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6996 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6997 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6998 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6999 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7000 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7003 /* .name = "Capture Source", */
7004 .name = "Input Source",
7006 .info = alc883_mux_enum_info,
7007 .get = alc883_mux_enum_get,
7008 .put = alc883_mux_enum_put,
7013 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7014 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7015 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7016 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7017 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7018 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7019 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7020 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7022 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7023 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7024 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7025 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7026 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7027 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7028 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7029 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7030 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7032 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7033 /* .name = "Capture Source", */
7034 .name = "Input Source",
7036 .info = alc883_mux_enum_info,
7037 .get = alc883_mux_enum_get,
7038 .put = alc883_mux_enum_put,
7043 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7044 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7045 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7046 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7047 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7049 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7050 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7051 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7052 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7053 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7054 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7055 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7056 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7057 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7060 /* .name = "Capture Source", */
7061 .name = "Input Source",
7063 .info = alc883_mux_enum_info,
7064 .get = alc883_mux_enum_get,
7065 .put = alc883_mux_enum_put,
7070 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7071 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7072 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7073 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7074 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7076 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7078 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7079 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7080 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7081 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7082 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7083 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7084 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7086 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7087 /* .name = "Capture Source", */
7088 .name = "Input Source",
7090 .info = alc883_mux_enum_info,
7091 .get = alc883_mux_enum_get,
7092 .put = alc883_mux_enum_put,
7097 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7098 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7099 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7100 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7101 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7102 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7103 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7104 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7106 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7107 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7108 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7109 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7110 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7111 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7112 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7113 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7114 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7115 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7116 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7119 /* .name = "Capture Source", */
7120 .name = "Input Source",
7122 .info = alc883_mux_enum_info,
7123 .get = alc883_mux_enum_get,
7124 .put = alc883_mux_enum_put,
7129 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7130 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7131 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7132 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7133 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7134 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7135 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7136 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7137 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7138 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7139 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7140 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7141 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7142 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7144 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7146 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7147 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7149 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7150 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7151 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7152 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7155 /* .name = "Capture Source", */
7156 .name = "Input Source",
7158 .info = alc883_mux_enum_info,
7159 .get = alc883_mux_enum_get,
7160 .put = alc883_mux_enum_put,
7165 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7166 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7167 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7168 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7169 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7170 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7172 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7173 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7174 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7175 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7176 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7177 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7178 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7179 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7180 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7181 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7182 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7183 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7184 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7185 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7186 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7187 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7188 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7189 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7190 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7191 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7193 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7194 /* .name = "Capture Source", */
7195 .name = "Input Source",
7197 .info = alc883_mux_enum_info,
7198 .get = alc883_mux_enum_get,
7199 .put = alc883_mux_enum_put,
7204 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7205 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7207 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7208 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7209 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7210 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7211 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7212 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7214 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7215 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7216 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7217 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7219 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7220 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7221 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7222 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7223 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7224 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7225 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7226 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7227 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7231 /* .name = "Capture Source", */
7232 .name = "Input Source",
7234 .info = alc883_mux_enum_info,
7235 .get = alc883_mux_enum_get,
7236 .put = alc883_mux_enum_put,
7241 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7242 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7243 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7244 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7245 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7246 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7247 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7248 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7249 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7250 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7251 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7252 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7253 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7254 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7256 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7258 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7259 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7260 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7261 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7263 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7264 /* .name = "Capture Source", */
7265 .name = "Input Source",
7267 .info = alc883_mux_enum_info,
7268 .get = alc883_mux_enum_get,
7269 .put = alc883_mux_enum_put,
7274 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7275 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7276 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7277 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7278 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7279 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7281 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7282 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7283 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7284 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7285 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7286 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7287 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7288 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7289 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7292 /* .name = "Capture Source", */
7293 .name = "Input Source",
7295 .info = alc883_mux_enum_info,
7296 .get = alc883_mux_enum_get,
7297 .put = alc883_mux_enum_put,
7302 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7303 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7304 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7305 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7306 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7307 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7309 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7310 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7311 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7312 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7315 /* .name = "Capture Source", */
7316 .name = "Input Source",
7318 .info = alc883_mux_enum_info,
7319 .get = alc883_mux_enum_get,
7320 .put = alc883_mux_enum_put,
7325 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7327 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7329 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7330 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7331 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7332 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7333 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7334 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7335 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7336 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7337 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7338 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7340 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7341 /* .name = "Capture Source", */
7342 .name = "Input Source",
7344 .info = alc883_mux_enum_info,
7345 .get = alc883_mux_enum_get,
7346 .put = alc883_mux_enum_put,
7351 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7352 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7353 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7354 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7355 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7356 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7357 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7358 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7359 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7360 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7361 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7362 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7363 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7364 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7366 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7367 /* .name = "Capture Source", */
7368 .name = "Input Source",
7370 .info = alc883_mux_enum_info,
7371 .get = alc883_mux_enum_get,
7372 .put = alc883_mux_enum_put,
7377 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7378 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7379 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7380 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7381 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7382 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7383 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7384 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7385 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7386 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7387 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7388 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7389 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7392 /* .name = "Capture Source", */
7393 .name = "Input Source",
7395 .info = alc883_mux_enum_info,
7396 .get = alc883_mux_enum_get,
7397 .put = alc883_mux_enum_put,
7402 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7403 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7404 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7405 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7406 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7407 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7408 0x0d, 1, 0x0, HDA_OUTPUT),
7409 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7410 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7411 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7412 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7413 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7414 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7415 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7416 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7417 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7418 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7419 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7420 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7421 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7422 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7423 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7424 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7425 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7426 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7427 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7428 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7429 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7431 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7432 /* .name = "Capture Source", */
7433 .name = "Input Source",
7435 .info = alc883_mux_enum_info,
7436 .get = alc883_mux_enum_get,
7437 .put = alc883_mux_enum_put,
7442 static struct hda_bind_ctls alc883_bind_cap_vol = {
7443 .ops = &snd_hda_bind_vol,
7445 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7446 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7451 static struct hda_bind_ctls alc883_bind_cap_switch = {
7452 .ops = &snd_hda_bind_sw,
7454 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7455 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7460 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7461 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7462 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7463 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7464 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7465 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7467 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7469 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7470 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7473 /* .name = "Capture Source", */
7474 .name = "Input Source",
7476 .info = alc883_mux_enum_info,
7477 .get = alc883_mux_enum_get,
7478 .put = alc883_mux_enum_put,
7483 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7485 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7486 .name = "Channel Mode",
7487 .info = alc_ch_mode_info,
7488 .get = alc_ch_mode_get,
7489 .put = alc_ch_mode_put,
7494 static struct hda_verb alc883_init_verbs[] = {
7495 /* ADC1: mute amp left and right */
7496 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7497 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7498 /* ADC2: mute amp left and right */
7499 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7500 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7501 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7511 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7512 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7516 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7518 /* mute analog input loopbacks */
7519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7525 /* Front Pin: output 0 (0x0c) */
7526 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7527 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7528 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7529 /* Rear Pin: output 1 (0x0d) */
7530 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7531 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7532 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7533 /* CLFE Pin: output 2 (0x0e) */
7534 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7535 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7536 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7537 /* Side Pin: output 3 (0x0f) */
7538 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7539 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7540 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7541 /* Mic (rear) pin: input vref at 80% */
7542 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7543 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7544 /* Front Mic pin: input vref at 80% */
7545 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7546 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7547 /* Line In pin: input */
7548 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7549 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7550 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7551 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7552 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7553 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7554 /* CD pin widget for input */
7555 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7557 /* FIXME: use matrix-type input source selection */
7558 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7563 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7565 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7572 /* toggle speaker-output according to the hp-jack state */
7573 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7575 unsigned int present;
7577 present = snd_hda_codec_read(codec, 0x15, 0,
7578 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7579 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7580 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7581 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7582 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7585 /* auto-toggle front mic */
7587 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7589 unsigned int present;
7592 present = snd_hda_codec_read(codec, 0x18, 0,
7593 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7594 bits = present ? HDA_AMP_MUTE : 0;
7595 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7599 static void alc883_mitac_automute(struct hda_codec *codec)
7601 alc883_mitac_hp_automute(codec);
7602 /* alc883_mitac_mic_automute(codec); */
7605 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7608 switch (res >> 26) {
7609 case ALC880_HP_EVENT:
7610 alc883_mitac_hp_automute(codec);
7612 case ALC880_MIC_EVENT:
7613 /* alc883_mitac_mic_automute(codec); */
7618 static struct hda_verb alc883_mitac_verbs[] = {
7620 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7621 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7623 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7624 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7626 /* enable unsolicited event */
7627 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7628 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7633 static struct hda_verb alc883_clevo_m720_verbs[] = {
7635 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7638 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7641 /* enable unsolicited event */
7642 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7643 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7648 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7650 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7653 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7654 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7656 /* enable unsolicited event */
7657 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7662 static struct hda_verb alc883_tagra_verbs[] = {
7663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7664 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7666 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7667 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7669 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7670 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7671 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7673 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7674 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7675 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7676 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7681 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7682 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7683 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7684 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7688 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7689 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7690 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7691 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7692 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7696 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7699 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7700 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7701 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7705 static struct hda_verb alc883_haier_w66_verbs[] = {
7706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7711 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7712 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7713 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7714 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7718 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7720 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7723 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7724 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7725 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7730 static struct hda_verb alc888_3st_hp_verbs[] = {
7731 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7732 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7733 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7737 static struct hda_verb alc888_6st_dell_verbs[] = {
7738 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7742 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7743 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7744 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7745 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7746 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7750 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7751 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7753 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7754 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7758 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7759 { 2, alc888_3st_hp_2ch_init },
7760 { 6, alc888_3st_hp_6ch_init },
7763 /* toggle front-jack and RCA according to the hp-jack state */
7764 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7766 unsigned int present;
7768 present = snd_hda_codec_read(codec, 0x1b, 0,
7769 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7770 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7771 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7772 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7773 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7776 /* toggle RCA according to the front-jack state */
7777 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7779 unsigned int present;
7781 present = snd_hda_codec_read(codec, 0x14, 0,
7782 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7783 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7784 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7787 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7790 if ((res >> 26) == ALC880_HP_EVENT)
7791 alc888_lenovo_ms7195_front_automute(codec);
7792 if ((res >> 26) == ALC880_FRONT_EVENT)
7793 alc888_lenovo_ms7195_rca_automute(codec);
7796 static struct hda_verb alc883_medion_md2_verbs[] = {
7797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7798 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7802 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7806 /* toggle speaker-output according to the hp-jack state */
7807 static void alc883_medion_md2_automute(struct hda_codec *codec)
7809 unsigned int present;
7811 present = snd_hda_codec_read(codec, 0x14, 0,
7812 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7813 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7814 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7817 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7820 if ((res >> 26) == ALC880_HP_EVENT)
7821 alc883_medion_md2_automute(codec);
7824 /* toggle speaker-output according to the hp-jack state */
7825 static void alc883_tagra_automute(struct hda_codec *codec)
7827 unsigned int present;
7830 present = snd_hda_codec_read(codec, 0x14, 0,
7831 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7832 bits = present ? HDA_AMP_MUTE : 0;
7833 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7834 HDA_AMP_MUTE, bits);
7835 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7839 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7841 if ((res >> 26) == ALC880_HP_EVENT)
7842 alc883_tagra_automute(codec);
7845 /* toggle speaker-output according to the hp-jack state */
7846 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7848 unsigned int present;
7851 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7852 & AC_PINSENSE_PRESENCE;
7853 bits = present ? HDA_AMP_MUTE : 0;
7854 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7855 HDA_AMP_MUTE, bits);
7858 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7860 unsigned int present;
7862 present = snd_hda_codec_read(codec, 0x18, 0,
7863 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7864 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7865 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7868 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7870 alc883_clevo_m720_hp_automute(codec);
7871 alc883_clevo_m720_mic_automute(codec);
7874 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7877 switch (res >> 26) {
7878 case ALC880_HP_EVENT:
7879 alc883_clevo_m720_hp_automute(codec);
7881 case ALC880_MIC_EVENT:
7882 alc883_clevo_m720_mic_automute(codec);
7887 /* toggle speaker-output according to the hp-jack state */
7888 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7890 unsigned int present;
7893 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7894 & AC_PINSENSE_PRESENCE;
7895 bits = present ? HDA_AMP_MUTE : 0;
7896 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7897 HDA_AMP_MUTE, bits);
7900 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7903 if ((res >> 26) == ALC880_HP_EVENT)
7904 alc883_2ch_fujitsu_pi2515_automute(codec);
7907 static void alc883_haier_w66_automute(struct hda_codec *codec)
7909 unsigned int present;
7912 present = snd_hda_codec_read(codec, 0x1b, 0,
7913 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7914 bits = present ? 0x80 : 0;
7915 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7919 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7922 if ((res >> 26) == ALC880_HP_EVENT)
7923 alc883_haier_w66_automute(codec);
7926 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7928 unsigned int present;
7931 present = snd_hda_codec_read(codec, 0x14, 0,
7932 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7933 bits = present ? HDA_AMP_MUTE : 0;
7934 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7935 HDA_AMP_MUTE, bits);
7938 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7940 unsigned int present;
7943 present = snd_hda_codec_read(codec, 0x1b, 0,
7944 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7945 bits = present ? HDA_AMP_MUTE : 0;
7946 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7947 HDA_AMP_MUTE, bits);
7948 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7949 HDA_AMP_MUTE, bits);
7952 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7955 if ((res >> 26) == ALC880_HP_EVENT)
7956 alc883_lenovo_101e_all_automute(codec);
7957 if ((res >> 26) == ALC880_FRONT_EVENT)
7958 alc883_lenovo_101e_ispeaker_automute(codec);
7961 /* toggle speaker-output according to the hp-jack state */
7962 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7964 unsigned int present;
7966 present = snd_hda_codec_read(codec, 0x14, 0,
7967 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7968 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7969 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7970 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7971 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7974 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7977 if ((res >> 26) == ALC880_HP_EVENT)
7978 alc883_acer_aspire_automute(codec);
7981 static struct hda_verb alc883_acer_eapd_verbs[] = {
7982 /* HP Pin: output 0 (0x0c) */
7983 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7986 /* Front Pin: output 0 (0x0c) */
7987 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7988 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7989 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7990 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7991 /* eanable EAPD on medion laptop */
7992 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7993 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7994 /* enable unsolicited event */
7995 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7999 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8001 unsigned int present;
8003 present = snd_hda_codec_read(codec, 0x1b, 0,
8004 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8005 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8006 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8007 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8008 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8009 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8010 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8011 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8012 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8015 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8018 switch (res >> 26) {
8019 case ALC880_HP_EVENT:
8020 printk("hp_event\n");
8021 alc888_6st_dell_front_automute(codec);
8026 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8029 unsigned int present;
8031 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8032 present = snd_hda_codec_read(codec, 0x1b, 0,
8033 AC_VERB_GET_PIN_SENSE, 0);
8034 present = (present & 0x80000000) != 0;
8036 /* mute internal speaker */
8037 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8038 HDA_AMP_MUTE, HDA_AMP_MUTE);
8039 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8040 HDA_AMP_MUTE, HDA_AMP_MUTE);
8041 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8042 HDA_AMP_MUTE, HDA_AMP_MUTE);
8043 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8044 HDA_AMP_MUTE, HDA_AMP_MUTE);
8045 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8046 HDA_AMP_MUTE, HDA_AMP_MUTE);
8048 /* unmute internal speaker if necessary */
8049 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8050 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8051 HDA_AMP_MUTE, mute);
8052 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8053 HDA_AMP_MUTE, mute);
8054 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8055 HDA_AMP_MUTE, mute);
8056 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8057 HDA_AMP_MUTE, mute);
8058 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8059 HDA_AMP_MUTE, mute);
8063 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8066 if ((res >> 26) == ALC880_HP_EVENT)
8067 alc888_lenovo_sky_front_automute(codec);
8071 * generic initialization of ADC, input mixers and output mixers
8073 static struct hda_verb alc883_auto_init_verbs[] = {
8075 * Unmute ADC0-2 and set the default input to mic-in
8077 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8078 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8079 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8080 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8082 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8084 * Note: PASD motherboards uses the Line In 2 as the input for
8085 * front panel mic (mic 2)
8087 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8095 * Set up output mixers (0x0c - 0x0f)
8097 /* set vol=0 to output mixers */
8098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8099 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8100 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8101 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8102 /* set up input amps for analog loopback */
8103 /* Amp Indices: DAC = 0, mixer = 1 */
8104 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8108 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8110 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8111 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8112 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8113 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8115 /* FIXME: use matrix-type input source selection */
8116 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8121 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8127 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8133 /* capture mixer elements */
8134 static struct snd_kcontrol_new alc883_capture_mixer[] = {
8135 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8136 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8137 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8138 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8140 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8141 /* The multiple "Capture Source" controls confuse alsamixer
8142 * So call somewhat different..
8144 /* .name = "Capture Source", */
8145 .name = "Input Source",
8147 .info = alc882_mux_enum_info,
8148 .get = alc882_mux_enum_get,
8149 .put = alc882_mux_enum_put,
8154 static struct hda_verb alc888_asus_m90v_verbs[] = {
8155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8157 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8158 /* enable unsolicited event */
8159 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8160 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8164 static void alc883_nb_mic_automute(struct hda_codec *codec)
8166 unsigned int present;
8168 present = snd_hda_codec_read(codec, 0x18, 0,
8169 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8170 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8171 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8172 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8173 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8176 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8178 unsigned int present;
8181 present = snd_hda_codec_read(codec, 0x1b, 0,
8182 AC_VERB_GET_PIN_SENSE, 0)
8183 & AC_PINSENSE_PRESENCE;
8184 bits = present ? 0 : PIN_OUT;
8185 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8187 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8189 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8193 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8196 switch (res >> 26) {
8197 case ALC880_HP_EVENT:
8198 alc883_M90V_speaker_automute(codec);
8200 case ALC880_MIC_EVENT:
8201 alc883_nb_mic_automute(codec);
8206 static void alc883_mode2_inithook(struct hda_codec *codec)
8208 alc883_M90V_speaker_automute(codec);
8209 alc883_nb_mic_automute(codec);
8212 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8213 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8214 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8217 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8218 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8219 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8220 /* enable unsolicited event */
8221 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8225 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8227 unsigned int present;
8230 present = snd_hda_codec_read(codec, 0x14, 0,
8231 AC_VERB_GET_PIN_SENSE, 0)
8232 & AC_PINSENSE_PRESENCE;
8233 bits = present ? 0 : PIN_OUT;
8234 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8238 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8241 switch (res >> 26) {
8242 case ALC880_HP_EVENT:
8243 alc883_eee1601_speaker_automute(codec);
8248 static void alc883_eee1601_inithook(struct hda_codec *codec)
8250 alc883_eee1601_speaker_automute(codec);
8253 #ifdef CONFIG_SND_HDA_POWER_SAVE
8254 #define alc883_loopbacks alc880_loopbacks
8257 /* pcm configuration: identiacal with ALC880 */
8258 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8259 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8260 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8261 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8262 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8265 * configuration and preset
8267 static const char *alc883_models[ALC883_MODEL_LAST] = {
8268 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8269 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8270 [ALC883_3ST_6ch] = "3stack-6ch",
8271 [ALC883_6ST_DIG] = "6stack-dig",
8272 [ALC883_TARGA_DIG] = "targa-dig",
8273 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8274 [ALC883_ACER] = "acer",
8275 [ALC883_ACER_ASPIRE] = "acer-aspire",
8276 [ALC883_MEDION] = "medion",
8277 [ALC883_MEDION_MD2] = "medion-md2",
8278 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8279 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8280 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8281 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8282 [ALC888_LENOVO_SKY] = "lenovo-sky",
8283 [ALC883_HAIER_W66] = "haier-w66",
8284 [ALC888_3ST_HP] = "3stack-hp",
8285 [ALC888_6ST_DELL] = "6stack-dell",
8286 [ALC883_MITAC] = "mitac",
8287 [ALC883_CLEVO_M720] = "clevo-m720",
8288 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8289 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8290 [ALC883_AUTO] = "auto",
8293 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8294 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8295 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8296 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8297 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8298 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8299 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8300 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8301 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8302 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8303 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8304 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8305 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8306 SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
8307 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8308 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8309 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8310 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8311 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8312 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8313 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8314 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8315 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8316 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8317 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8318 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8319 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8320 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8321 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8322 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8323 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8324 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8325 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8326 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8327 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8328 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8329 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8330 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8331 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8332 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8333 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8334 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8335 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8336 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8337 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8338 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8339 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8340 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8341 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8342 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8343 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8344 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8345 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8346 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8347 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8348 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8349 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8350 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8351 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8352 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8353 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8354 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8358 static struct alc_config_preset alc883_presets[] = {
8359 [ALC883_3ST_2ch_DIG] = {
8360 .mixers = { alc883_3ST_2ch_mixer },
8361 .init_verbs = { alc883_init_verbs },
8362 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8363 .dac_nids = alc883_dac_nids,
8364 .dig_out_nid = ALC883_DIGOUT_NID,
8365 .dig_in_nid = ALC883_DIGIN_NID,
8366 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8367 .channel_mode = alc883_3ST_2ch_modes,
8368 .input_mux = &alc883_capture_source,
8370 [ALC883_3ST_6ch_DIG] = {
8371 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8372 .init_verbs = { alc883_init_verbs },
8373 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8374 .dac_nids = alc883_dac_nids,
8375 .dig_out_nid = ALC883_DIGOUT_NID,
8376 .dig_in_nid = ALC883_DIGIN_NID,
8377 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8378 .channel_mode = alc883_3ST_6ch_modes,
8380 .input_mux = &alc883_capture_source,
8382 [ALC883_3ST_6ch] = {
8383 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8384 .init_verbs = { alc883_init_verbs },
8385 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8386 .dac_nids = alc883_dac_nids,
8387 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8388 .channel_mode = alc883_3ST_6ch_modes,
8390 .input_mux = &alc883_capture_source,
8392 [ALC883_3ST_6ch_INTEL] = {
8393 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8394 .init_verbs = { alc883_init_verbs },
8395 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8396 .dac_nids = alc883_dac_nids,
8397 .dig_out_nid = ALC883_DIGOUT_NID,
8398 .dig_in_nid = ALC883_DIGIN_NID,
8399 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8400 .channel_mode = alc883_3ST_6ch_intel_modes,
8402 .input_mux = &alc883_3stack_6ch_intel,
8404 [ALC883_6ST_DIG] = {
8405 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8406 .init_verbs = { alc883_init_verbs },
8407 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8408 .dac_nids = alc883_dac_nids,
8409 .dig_out_nid = ALC883_DIGOUT_NID,
8410 .dig_in_nid = ALC883_DIGIN_NID,
8411 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8412 .channel_mode = alc883_sixstack_modes,
8413 .input_mux = &alc883_capture_source,
8415 [ALC883_TARGA_DIG] = {
8416 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8417 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8418 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8419 .dac_nids = alc883_dac_nids,
8420 .dig_out_nid = ALC883_DIGOUT_NID,
8421 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8422 .channel_mode = alc883_3ST_6ch_modes,
8424 .input_mux = &alc883_capture_source,
8425 .unsol_event = alc883_tagra_unsol_event,
8426 .init_hook = alc883_tagra_automute,
8428 [ALC883_TARGA_2ch_DIG] = {
8429 .mixers = { alc883_tagra_2ch_mixer},
8430 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8431 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8432 .dac_nids = alc883_dac_nids,
8433 .dig_out_nid = ALC883_DIGOUT_NID,
8434 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8435 .channel_mode = alc883_3ST_2ch_modes,
8436 .input_mux = &alc883_capture_source,
8437 .unsol_event = alc883_tagra_unsol_event,
8438 .init_hook = alc883_tagra_automute,
8441 .mixers = { alc883_base_mixer },
8442 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8443 * and the headphone jack. Turn this on and rely on the
8444 * standard mute methods whenever the user wants to turn
8445 * these outputs off.
8447 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8448 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8449 .dac_nids = alc883_dac_nids,
8450 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8451 .channel_mode = alc883_3ST_2ch_modes,
8452 .input_mux = &alc883_capture_source,
8454 [ALC883_ACER_ASPIRE] = {
8455 .mixers = { alc883_acer_aspire_mixer },
8456 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8457 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8458 .dac_nids = alc883_dac_nids,
8459 .dig_out_nid = ALC883_DIGOUT_NID,
8460 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8461 .channel_mode = alc883_3ST_2ch_modes,
8462 .input_mux = &alc883_capture_source,
8463 .unsol_event = alc883_acer_aspire_unsol_event,
8464 .init_hook = alc883_acer_aspire_automute,
8467 .mixers = { alc883_fivestack_mixer,
8468 alc883_chmode_mixer },
8469 .init_verbs = { alc883_init_verbs,
8470 alc883_medion_eapd_verbs },
8471 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8472 .dac_nids = alc883_dac_nids,
8473 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8474 .channel_mode = alc883_sixstack_modes,
8475 .input_mux = &alc883_capture_source,
8477 [ALC883_MEDION_MD2] = {
8478 .mixers = { alc883_medion_md2_mixer},
8479 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8480 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8481 .dac_nids = alc883_dac_nids,
8482 .dig_out_nid = ALC883_DIGOUT_NID,
8483 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8484 .channel_mode = alc883_3ST_2ch_modes,
8485 .input_mux = &alc883_capture_source,
8486 .unsol_event = alc883_medion_md2_unsol_event,
8487 .init_hook = alc883_medion_md2_automute,
8489 [ALC883_LAPTOP_EAPD] = {
8490 .mixers = { alc883_base_mixer },
8491 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8492 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8493 .dac_nids = alc883_dac_nids,
8494 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8495 .channel_mode = alc883_3ST_2ch_modes,
8496 .input_mux = &alc883_capture_source,
8498 [ALC883_CLEVO_M720] = {
8499 .mixers = { alc883_clevo_m720_mixer },
8500 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8502 .dac_nids = alc883_dac_nids,
8503 .dig_out_nid = ALC883_DIGOUT_NID,
8504 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8505 .channel_mode = alc883_3ST_2ch_modes,
8506 .input_mux = &alc883_capture_source,
8507 .unsol_event = alc883_clevo_m720_unsol_event,
8508 .init_hook = alc883_clevo_m720_automute,
8510 [ALC883_LENOVO_101E_2ch] = {
8511 .mixers = { alc883_lenovo_101e_2ch_mixer},
8512 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8513 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8514 .dac_nids = alc883_dac_nids,
8515 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8516 .channel_mode = alc883_3ST_2ch_modes,
8517 .input_mux = &alc883_lenovo_101e_capture_source,
8518 .unsol_event = alc883_lenovo_101e_unsol_event,
8519 .init_hook = alc883_lenovo_101e_all_automute,
8521 [ALC883_LENOVO_NB0763] = {
8522 .mixers = { alc883_lenovo_nb0763_mixer },
8523 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8525 .dac_nids = alc883_dac_nids,
8526 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8527 .channel_mode = alc883_3ST_2ch_modes,
8529 .input_mux = &alc883_lenovo_nb0763_capture_source,
8530 .unsol_event = alc883_medion_md2_unsol_event,
8531 .init_hook = alc883_medion_md2_automute,
8533 [ALC888_LENOVO_MS7195_DIG] = {
8534 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8535 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8536 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8537 .dac_nids = alc883_dac_nids,
8538 .dig_out_nid = ALC883_DIGOUT_NID,
8539 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8540 .channel_mode = alc883_3ST_6ch_modes,
8542 .input_mux = &alc883_capture_source,
8543 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8544 .init_hook = alc888_lenovo_ms7195_front_automute,
8546 [ALC883_HAIER_W66] = {
8547 .mixers = { alc883_tagra_2ch_mixer},
8548 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8549 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8550 .dac_nids = alc883_dac_nids,
8551 .dig_out_nid = ALC883_DIGOUT_NID,
8552 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8553 .channel_mode = alc883_3ST_2ch_modes,
8554 .input_mux = &alc883_capture_source,
8555 .unsol_event = alc883_haier_w66_unsol_event,
8556 .init_hook = alc883_haier_w66_automute,
8559 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8560 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8561 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8562 .dac_nids = alc883_dac_nids,
8563 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8564 .channel_mode = alc888_3st_hp_modes,
8566 .input_mux = &alc883_capture_source,
8568 [ALC888_6ST_DELL] = {
8569 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8570 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8571 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8572 .dac_nids = alc883_dac_nids,
8573 .dig_out_nid = ALC883_DIGOUT_NID,
8574 .dig_in_nid = ALC883_DIGIN_NID,
8575 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8576 .channel_mode = alc883_sixstack_modes,
8577 .input_mux = &alc883_capture_source,
8578 .unsol_event = alc888_6st_dell_unsol_event,
8579 .init_hook = alc888_6st_dell_front_automute,
8582 .mixers = { alc883_mitac_mixer },
8583 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8584 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8585 .dac_nids = alc883_dac_nids,
8586 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8587 .channel_mode = alc883_3ST_2ch_modes,
8588 .input_mux = &alc883_capture_source,
8589 .unsol_event = alc883_mitac_unsol_event,
8590 .init_hook = alc883_mitac_automute,
8592 [ALC883_FUJITSU_PI2515] = {
8593 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8594 .init_verbs = { alc883_init_verbs,
8595 alc883_2ch_fujitsu_pi2515_verbs},
8596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8597 .dac_nids = alc883_dac_nids,
8598 .dig_out_nid = ALC883_DIGOUT_NID,
8599 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8600 .channel_mode = alc883_3ST_2ch_modes,
8601 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8602 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8603 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8605 [ALC888_LENOVO_SKY] = {
8606 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8607 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8608 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8609 .dac_nids = alc883_dac_nids,
8610 .dig_out_nid = ALC883_DIGOUT_NID,
8611 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8612 .adc_nids = alc883_adc_nids,
8613 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8614 .channel_mode = alc883_sixstack_modes,
8616 .input_mux = &alc883_lenovo_sky_capture_source,
8617 .unsol_event = alc883_lenovo_sky_unsol_event,
8618 .init_hook = alc888_lenovo_sky_front_automute,
8620 [ALC888_ASUS_M90V] = {
8621 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8622 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8623 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8624 .dac_nids = alc883_dac_nids,
8625 .dig_out_nid = ALC883_DIGOUT_NID,
8626 .dig_in_nid = ALC883_DIGIN_NID,
8627 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8628 .channel_mode = alc883_3ST_6ch_modes,
8630 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8631 .unsol_event = alc883_mode2_unsol_event,
8632 .init_hook = alc883_mode2_inithook,
8634 [ALC888_ASUS_EEE1601] = {
8635 .mixers = { alc883_asus_eee1601_mixer },
8636 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8637 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8638 .dac_nids = alc883_dac_nids,
8639 .dig_out_nid = ALC883_DIGOUT_NID,
8640 .dig_in_nid = ALC883_DIGIN_NID,
8641 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8642 .channel_mode = alc883_3ST_2ch_modes,
8644 .input_mux = &alc883_asus_eee1601_capture_source,
8645 .unsol_event = alc883_eee1601_unsol_event,
8646 .init_hook = alc883_eee1601_inithook,
8652 * BIOS auto configuration
8654 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8655 hda_nid_t nid, int pin_type,
8659 struct alc_spec *spec = codec->spec;
8662 alc_set_pin_output(codec, nid, pin_type);
8663 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8666 idx = spec->multiout.dac_nids[dac_idx] - 2;
8667 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8671 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8673 struct alc_spec *spec = codec->spec;
8676 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8677 for (i = 0; i <= HDA_SIDE; i++) {
8678 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8679 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8681 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8686 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8688 struct alc_spec *spec = codec->spec;
8691 pin = spec->autocfg.hp_pins[0];
8692 if (pin) /* connect to front */
8694 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8695 pin = spec->autocfg.speaker_pins[0];
8697 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8700 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8701 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8703 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8705 struct alc_spec *spec = codec->spec;
8708 for (i = 0; i < AUTO_PIN_LAST; i++) {
8709 hda_nid_t nid = spec->autocfg.input_pins[i];
8710 if (alc883_is_input_pin(nid)) {
8711 snd_hda_codec_write(codec, nid, 0,
8712 AC_VERB_SET_PIN_WIDGET_CONTROL,
8713 (i <= AUTO_PIN_FRONT_MIC ?
8714 PIN_VREF80 : PIN_IN));
8715 if (nid != ALC883_PIN_CD_NID)
8716 snd_hda_codec_write(codec, nid, 0,
8717 AC_VERB_SET_AMP_GAIN_MUTE,
8723 #define alc883_auto_init_input_src alc882_auto_init_input_src
8725 /* almost identical with ALC880 parser... */
8726 static int alc883_parse_auto_config(struct hda_codec *codec)
8728 struct alc_spec *spec = codec->spec;
8729 int err = alc880_parse_auto_config(codec);
8734 return 0; /* no config found */
8736 err = alc_auto_add_mic_boost(codec);
8740 /* hack - override the init verbs */
8741 spec->init_verbs[0] = alc883_auto_init_verbs;
8742 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8745 return 1; /* config found */
8748 /* additional initialization for auto-configuration model */
8749 static void alc883_auto_init(struct hda_codec *codec)
8751 struct alc_spec *spec = codec->spec;
8752 alc883_auto_init_multi_out(codec);
8753 alc883_auto_init_hp_out(codec);
8754 alc883_auto_init_analog_input(codec);
8755 alc883_auto_init_input_src(codec);
8756 if (spec->unsol_event)
8757 alc_sku_automute(codec);
8760 static int patch_alc883(struct hda_codec *codec)
8762 struct alc_spec *spec;
8763 int err, board_config;
8765 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8771 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8773 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8776 if (board_config < 0) {
8777 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8778 "trying auto-probe from BIOS...\n");
8779 board_config = ALC883_AUTO;
8782 if (board_config == ALC883_AUTO) {
8783 /* automatic parse from the BIOS config */
8784 err = alc883_parse_auto_config(codec);
8790 "hda_codec: Cannot set up configuration "
8791 "from BIOS. Using base mode...\n");
8792 board_config = ALC883_3ST_2ch_DIG;
8796 if (board_config != ALC883_AUTO)
8797 setup_preset(spec, &alc883_presets[board_config]);
8799 switch (codec->vendor_id) {
8801 spec->stream_name_analog = "ALC888 Analog";
8802 spec->stream_name_digital = "ALC888 Digital";
8805 spec->stream_name_analog = "ALC889 Analog";
8806 spec->stream_name_digital = "ALC889 Digital";
8809 spec->stream_name_analog = "ALC883 Analog";
8810 spec->stream_name_digital = "ALC883 Digital";
8814 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8815 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8816 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8818 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8819 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8821 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8822 spec->adc_nids = alc883_adc_nids;
8823 spec->capsrc_nids = alc883_capsrc_nids;
8825 spec->vmaster_nid = 0x0c;
8827 codec->patch_ops = alc_patch_ops;
8828 if (board_config == ALC883_AUTO)
8829 spec->init_hook = alc883_auto_init;
8831 #ifdef CONFIG_SND_HDA_POWER_SAVE
8832 if (!spec->loopback.amplist)
8833 spec->loopback.amplist = alc883_loopbacks;
8843 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8844 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8846 #define alc262_dac_nids alc260_dac_nids
8847 #define alc262_adc_nids alc882_adc_nids
8848 #define alc262_adc_nids_alt alc882_adc_nids_alt
8849 #define alc262_capsrc_nids alc882_capsrc_nids
8850 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8852 #define alc262_modes alc260_modes
8853 #define alc262_capture_source alc882_capture_source
8855 static hda_nid_t alc262_dmic_adc_nids[1] = {
8860 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8862 static struct snd_kcontrol_new alc262_base_mixer[] = {
8863 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8864 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8865 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8866 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8867 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8868 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8869 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8870 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8871 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8872 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8873 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8874 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8875 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8876 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8877 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8878 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8879 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8880 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8884 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8885 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8886 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8887 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8888 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8889 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8890 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8891 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8892 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8893 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8894 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8895 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8896 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8897 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8898 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8899 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8904 /* update HP, line and mono-out pins according to the master switch */
8905 static void alc262_hp_master_update(struct hda_codec *codec)
8907 struct alc_spec *spec = codec->spec;
8908 int val = spec->master_sw;
8911 snd_hda_codec_write_cache(codec, 0x1b, 0,
8912 AC_VERB_SET_PIN_WIDGET_CONTROL,
8914 snd_hda_codec_write_cache(codec, 0x15, 0,
8915 AC_VERB_SET_PIN_WIDGET_CONTROL,
8917 /* mono (speaker) depending on the HP jack sense */
8918 val = val && !spec->jack_present;
8919 snd_hda_codec_write_cache(codec, 0x16, 0,
8920 AC_VERB_SET_PIN_WIDGET_CONTROL,
8924 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8926 struct alc_spec *spec = codec->spec;
8927 unsigned int presence;
8928 presence = snd_hda_codec_read(codec, 0x1b, 0,
8929 AC_VERB_GET_PIN_SENSE, 0);
8930 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8931 alc262_hp_master_update(codec);
8934 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8936 if ((res >> 26) != ALC880_HP_EVENT)
8938 alc262_hp_bpc_automute(codec);
8941 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8943 struct alc_spec *spec = codec->spec;
8944 unsigned int presence;
8945 presence = snd_hda_codec_read(codec, 0x15, 0,
8946 AC_VERB_GET_PIN_SENSE, 0);
8947 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8948 alc262_hp_master_update(codec);
8951 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8954 if ((res >> 26) != ALC880_HP_EVENT)
8956 alc262_hp_wildwest_automute(codec);
8959 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8960 struct snd_ctl_elem_value *ucontrol)
8962 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8963 struct alc_spec *spec = codec->spec;
8964 *ucontrol->value.integer.value = spec->master_sw;
8968 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8969 struct snd_ctl_elem_value *ucontrol)
8971 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8972 struct alc_spec *spec = codec->spec;
8973 int val = !!*ucontrol->value.integer.value;
8975 if (val == spec->master_sw)
8977 spec->master_sw = val;
8978 alc262_hp_master_update(codec);
8982 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8984 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8985 .name = "Master Playback Switch",
8986 .info = snd_ctl_boolean_mono_info,
8987 .get = alc262_hp_master_sw_get,
8988 .put = alc262_hp_master_sw_put,
8990 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8992 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8993 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8995 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9001 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9002 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9005 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9006 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9007 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9008 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9009 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9010 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9014 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9016 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9017 .name = "Master Playback Switch",
9018 .info = snd_ctl_boolean_mono_info,
9019 .get = alc262_hp_master_sw_get,
9020 .put = alc262_hp_master_sw_put,
9022 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9023 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9024 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9025 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9026 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9028 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9031 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9032 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9034 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9035 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9036 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9037 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9038 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9042 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9043 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9044 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9045 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9049 /* mute/unmute internal speaker according to the hp jack and mute state */
9050 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9052 struct alc_spec *spec = codec->spec;
9054 if (force || !spec->sense_updated) {
9055 unsigned int present;
9056 present = snd_hda_codec_read(codec, 0x15, 0,
9057 AC_VERB_GET_PIN_SENSE, 0);
9058 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9059 spec->sense_updated = 1;
9061 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9062 spec->jack_present ? HDA_AMP_MUTE : 0);
9065 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9068 if ((res >> 26) != ALC880_HP_EVENT)
9070 alc262_hp_t5735_automute(codec, 1);
9073 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9075 alc262_hp_t5735_automute(codec, 1);
9078 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9079 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9080 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9081 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9084 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9085 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9089 static struct hda_verb alc262_hp_t5735_verbs[] = {
9090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9091 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9093 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9097 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9098 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9101 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9102 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9103 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9107 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9108 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9109 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9110 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9111 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9112 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9113 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9117 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9121 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9128 /* bind hp and internal speaker mute (with plug check) */
9129 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9130 struct snd_ctl_elem_value *ucontrol)
9132 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9133 long *valp = ucontrol->value.integer.value;
9136 /* change hp mute */
9137 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9139 valp[0] ? 0 : HDA_AMP_MUTE);
9140 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9142 valp[1] ? 0 : HDA_AMP_MUTE);
9144 /* change speaker according to HP jack state */
9145 struct alc_spec *spec = codec->spec;
9147 if (spec->jack_present)
9148 mute = HDA_AMP_MUTE;
9150 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9152 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9153 HDA_AMP_MUTE, mute);
9158 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9159 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9161 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9162 .name = "Master Playback Switch",
9163 .info = snd_hda_mixer_amp_switch_info,
9164 .get = snd_hda_mixer_amp_switch_get,
9165 .put = alc262_sony_master_sw_put,
9166 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9168 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9169 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9170 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9171 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9175 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9176 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9177 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9178 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9181 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9182 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9186 #define alc262_capture_mixer alc882_capture_mixer
9187 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9190 * generic initialization of ADC, input mixers and output mixers
9192 static struct hda_verb alc262_init_verbs[] = {
9194 * Unmute ADC0-2 and set the default input to mic-in
9196 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9197 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9198 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9199 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9200 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9201 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9203 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9205 * Note: PASD motherboards uses the Line In 2 as the input for
9206 * front panel mic (mic 2)
9208 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9216 * Set up output mixers (0x0c - 0x0e)
9218 /* set vol=0 to output mixers */
9219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9220 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9222 /* set up input amps for analog loopback */
9223 /* Amp Indices: DAC = 0, mixer = 1 */
9224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9225 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9226 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9227 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9228 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9229 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9233 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9234 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9235 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9236 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9240 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9241 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9242 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9244 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9245 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9247 /* FIXME: use matrix-type input source selection */
9248 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9249 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9251 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9252 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9253 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9255 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9256 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9257 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9258 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9262 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9263 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9268 static struct hda_verb alc262_eapd_verbs[] = {
9269 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9270 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9274 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9275 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9276 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9280 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9281 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9282 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9283 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9285 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9286 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9290 static struct hda_verb alc262_sony_unsol_verbs[] = {
9291 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9292 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9293 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9295 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9300 static struct hda_input_mux alc262_dmic_capture_source = {
9303 { "Int DMic", 0x9 },
9308 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9309 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9310 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9313 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9314 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9315 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9317 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9318 /* The multiple "Capture Source" controls confuse alsamixer
9319 * So call somewhat different..
9321 /* .name = "Capture Source", */
9322 .name = "Input Source",
9324 .info = alc_mux_enum_info,
9325 .get = alc_mux_enum_get,
9326 .put = alc_mux_enum_put,
9331 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9332 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9333 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9334 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9336 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9337 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9338 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9339 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9343 static void alc262_dmic_automute(struct hda_codec *codec)
9345 unsigned int present;
9347 present = snd_hda_codec_read(codec, 0x18, 0,
9348 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9349 snd_hda_codec_write(codec, 0x22, 0,
9350 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9353 /* toggle speaker-output according to the hp-jack state */
9354 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9356 unsigned int present;
9359 present = snd_hda_codec_read(codec, 0x15, 0,
9360 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9361 bits = present ? 0 : PIN_OUT;
9362 snd_hda_codec_write(codec, 0x14, 0,
9363 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9368 /* unsolicited event for HP jack sensing */
9369 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9372 if ((res >> 26) == ALC880_HP_EVENT)
9373 alc262_toshiba_s06_speaker_automute(codec);
9374 if ((res >> 26) == ALC880_MIC_EVENT)
9375 alc262_dmic_automute(codec);
9379 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9381 alc262_toshiba_s06_speaker_automute(codec);
9382 alc262_dmic_automute(codec);
9385 /* mute/unmute internal speaker according to the hp jack and mute state */
9386 static void alc262_hippo_automute(struct hda_codec *codec)
9388 struct alc_spec *spec = codec->spec;
9390 unsigned int present;
9392 /* need to execute and sync at first */
9393 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9394 present = snd_hda_codec_read(codec, 0x15, 0,
9395 AC_VERB_GET_PIN_SENSE, 0);
9396 spec->jack_present = (present & 0x80000000) != 0;
9397 if (spec->jack_present) {
9398 /* mute internal speaker */
9399 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9400 HDA_AMP_MUTE, HDA_AMP_MUTE);
9402 /* unmute internal speaker if necessary */
9403 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9404 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9405 HDA_AMP_MUTE, mute);
9409 /* unsolicited event for HP jack sensing */
9410 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9413 if ((res >> 26) != ALC880_HP_EVENT)
9415 alc262_hippo_automute(codec);
9418 static void alc262_hippo1_automute(struct hda_codec *codec)
9421 unsigned int present;
9423 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9424 present = snd_hda_codec_read(codec, 0x1b, 0,
9425 AC_VERB_GET_PIN_SENSE, 0);
9426 present = (present & 0x80000000) != 0;
9428 /* mute internal speaker */
9429 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9430 HDA_AMP_MUTE, HDA_AMP_MUTE);
9432 /* unmute internal speaker if necessary */
9433 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9434 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9435 HDA_AMP_MUTE, mute);
9439 /* unsolicited event for HP jack sensing */
9440 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9443 if ((res >> 26) != ALC880_HP_EVENT)
9445 alc262_hippo1_automute(codec);
9451 * 0x16 = internal speaker
9452 * 0x18 = external mic
9455 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9456 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9457 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9460 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9461 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9463 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9468 static struct hda_verb alc262_nec_verbs[] = {
9469 /* Unmute Speaker */
9470 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9473 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9476 /* External mic to headphone */
9477 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9478 /* External mic to speaker */
9479 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9485 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9486 * 0x1b = port replicator headphone out
9489 #define ALC_HP_EVENT 0x37
9491 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9492 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9499 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9500 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9501 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9505 static struct hda_input_mux alc262_fujitsu_capture_source = {
9514 static struct hda_input_mux alc262_HP_capture_source = {
9518 { "Front Mic", 0x1 },
9525 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9529 { "Front Mic", 0x2 },
9535 /* mute/unmute internal speaker according to the hp jacks and mute state */
9536 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9538 struct alc_spec *spec = codec->spec;
9541 if (force || !spec->sense_updated) {
9542 unsigned int present;
9543 /* need to execute and sync at first */
9544 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9545 /* check laptop HP jack */
9546 present = snd_hda_codec_read(codec, 0x14, 0,
9547 AC_VERB_GET_PIN_SENSE, 0);
9548 /* need to execute and sync at first */
9549 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9550 /* check docking HP jack */
9551 present |= snd_hda_codec_read(codec, 0x1b, 0,
9552 AC_VERB_GET_PIN_SENSE, 0);
9553 if (present & AC_PINSENSE_PRESENCE)
9554 spec->jack_present = 1;
9556 spec->jack_present = 0;
9557 spec->sense_updated = 1;
9559 /* unmute internal speaker only if both HPs are unplugged and
9560 * master switch is on
9562 if (spec->jack_present)
9563 mute = HDA_AMP_MUTE;
9565 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9566 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9567 HDA_AMP_MUTE, mute);
9570 /* unsolicited event for HP jack sensing */
9571 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9574 if ((res >> 26) != ALC_HP_EVENT)
9576 alc262_fujitsu_automute(codec, 1);
9579 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9581 alc262_fujitsu_automute(codec, 1);
9584 /* bind volumes of both NID 0x0c and 0x0d */
9585 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9586 .ops = &snd_hda_bind_vol,
9588 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9589 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9594 /* mute/unmute internal speaker according to the hp jack and mute state */
9595 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9597 struct alc_spec *spec = codec->spec;
9600 if (force || !spec->sense_updated) {
9601 unsigned int present_int_hp;
9602 /* need to execute and sync at first */
9603 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9604 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9605 AC_VERB_GET_PIN_SENSE, 0);
9606 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9607 spec->sense_updated = 1;
9609 if (spec->jack_present) {
9610 /* mute internal speaker */
9611 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9612 HDA_AMP_MUTE, HDA_AMP_MUTE);
9613 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9614 HDA_AMP_MUTE, HDA_AMP_MUTE);
9616 /* unmute internal speaker if necessary */
9617 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9618 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9619 HDA_AMP_MUTE, mute);
9620 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9621 HDA_AMP_MUTE, mute);
9625 /* unsolicited event for HP jack sensing */
9626 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9629 if ((res >> 26) != ALC_HP_EVENT)
9631 alc262_lenovo_3000_automute(codec, 1);
9634 /* bind hp and internal speaker mute (with plug check) */
9635 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9636 struct snd_ctl_elem_value *ucontrol)
9638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9639 long *valp = ucontrol->value.integer.value;
9642 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9644 valp ? 0 : HDA_AMP_MUTE);
9645 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9647 valp ? 0 : HDA_AMP_MUTE);
9650 alc262_fujitsu_automute(codec, 0);
9654 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9655 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9657 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9658 .name = "Master Playback Switch",
9659 .info = snd_hda_mixer_amp_switch_info,
9660 .get = snd_hda_mixer_amp_switch_get,
9661 .put = alc262_fujitsu_master_sw_put,
9662 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9664 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9665 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9666 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9667 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9668 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9669 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9670 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9671 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9672 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9673 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9677 /* bind hp and internal speaker mute (with plug check) */
9678 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9679 struct snd_ctl_elem_value *ucontrol)
9681 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9682 long *valp = ucontrol->value.integer.value;
9685 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9687 valp ? 0 : HDA_AMP_MUTE);
9690 alc262_lenovo_3000_automute(codec, 0);
9694 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9695 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9697 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9698 .name = "Master Playback Switch",
9699 .info = snd_hda_mixer_amp_switch_info,
9700 .get = snd_hda_mixer_amp_switch_get,
9701 .put = alc262_lenovo_3000_master_sw_put,
9702 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9704 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9705 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9706 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9709 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9710 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9711 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9715 /* additional init verbs for Benq laptops */
9716 static struct hda_verb alc262_EAPD_verbs[] = {
9717 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9718 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9722 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9723 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9724 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9726 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9727 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9731 /* Samsung Q1 Ultra Vista model setup */
9732 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9733 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9734 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9735 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9736 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9737 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9738 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9742 static struct hda_verb alc262_ultra_verbs[] = {
9744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9748 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9750 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9751 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9753 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9754 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9756 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9757 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9759 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9760 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9761 /* ADC, choose mic */
9762 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9768 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9770 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9771 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9775 /* mute/unmute internal speaker according to the hp jack and mute state */
9776 static void alc262_ultra_automute(struct hda_codec *codec)
9778 struct alc_spec *spec = codec->spec;
9782 /* auto-mute only when HP is used as HP */
9783 if (!spec->cur_mux[0]) {
9784 unsigned int present;
9785 /* need to execute and sync at first */
9786 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9787 present = snd_hda_codec_read(codec, 0x15, 0,
9788 AC_VERB_GET_PIN_SENSE, 0);
9789 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9790 if (spec->jack_present)
9791 mute = HDA_AMP_MUTE;
9793 /* mute/unmute internal speaker */
9794 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9795 HDA_AMP_MUTE, mute);
9796 /* mute/unmute HP */
9797 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9798 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9801 /* unsolicited event for HP jack sensing */
9802 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9805 if ((res >> 26) != ALC880_HP_EVENT)
9807 alc262_ultra_automute(codec);
9810 static struct hda_input_mux alc262_ultra_capture_source = {
9814 { "Headphone", 0x7 },
9818 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9819 struct snd_ctl_elem_value *ucontrol)
9821 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9822 struct alc_spec *spec = codec->spec;
9825 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9828 /* reprogram the HP pin as mic or HP according to the input source */
9829 snd_hda_codec_write_cache(codec, 0x15, 0,
9830 AC_VERB_SET_PIN_WIDGET_CONTROL,
9831 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9832 alc262_ultra_automute(codec); /* mute/unmute HP */
9836 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9837 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9838 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9841 .name = "Capture Source",
9842 .info = alc882_mux_enum_info,
9843 .get = alc882_mux_enum_get,
9844 .put = alc262_ultra_mux_enum_put,
9849 /* add playback controls from the parsed DAC table */
9850 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9851 const struct auto_pin_cfg *cfg)
9856 spec->multiout.num_dacs = 1; /* only use one dac */
9857 spec->multiout.dac_nids = spec->private_dac_nids;
9858 spec->multiout.dac_nids[0] = 2;
9860 nid = cfg->line_out_pins[0];
9862 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9863 "Front Playback Volume",
9864 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9867 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9868 "Front Playback Switch",
9869 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9874 nid = cfg->speaker_pins[0];
9877 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9878 "Speaker Playback Volume",
9879 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9883 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9884 "Speaker Playback Switch",
9885 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9890 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9891 "Speaker Playback Switch",
9892 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9898 nid = cfg->hp_pins[0];
9900 /* spec->multiout.hp_nid = 2; */
9902 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9903 "Headphone Playback Volume",
9904 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9908 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9909 "Headphone Playback Switch",
9910 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9915 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9916 "Headphone Playback Switch",
9917 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9926 /* identical with ALC880 */
9927 #define alc262_auto_create_analog_input_ctls \
9928 alc880_auto_create_analog_input_ctls
9931 * generic initialization of ADC, input mixers and output mixers
9933 static struct hda_verb alc262_volume_init_verbs[] = {
9935 * Unmute ADC0-2 and set the default input to mic-in
9937 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9938 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9939 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9940 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9941 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9942 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9944 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9946 * Note: PASD motherboards uses the Line In 2 as the input for
9947 * front panel mic (mic 2)
9949 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9950 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9951 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9952 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9953 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9954 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9957 * Set up output mixers (0x0c - 0x0f)
9959 /* set vol=0 to output mixers */
9960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9962 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9964 /* set up input amps for analog loopback */
9965 /* Amp Indices: DAC = 0, mixer = 1 */
9966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9967 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9968 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9969 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9971 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9973 /* FIXME: use matrix-type input source selection */
9974 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9975 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9978 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9979 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9982 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9983 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9984 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9986 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9989 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9994 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9996 * Unmute ADC0-2 and set the default input to mic-in
9998 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10000 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10001 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10002 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10003 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10005 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10007 * Note: PASD motherboards uses the Line In 2 as the input for
10008 * front panel mic (mic 2)
10010 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10017 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10020 * Set up output mixers (0x0c - 0x0e)
10022 /* set vol=0 to output mixers */
10023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10024 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10025 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10027 /* set up input amps for analog loopback */
10028 /* Amp Indices: DAC = 0, mixer = 1 */
10029 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10030 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10032 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10034 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10036 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10037 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10038 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10040 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10041 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10043 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10046 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10047 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10048 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10049 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10050 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10052 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10053 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10054 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10055 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10056 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10057 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10060 /* FIXME: use matrix-type input source selection */
10061 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10062 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10064 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10065 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10066 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10071 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10076 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10078 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10083 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10085 * Unmute ADC0-2 and set the default input to mic-in
10087 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10088 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10089 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10090 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10091 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10092 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10094 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10096 * Note: PASD motherboards uses the Line In 2 as the input for front
10097 * panel mic (mic 2)
10099 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10109 * Set up output mixers (0x0c - 0x0e)
10111 /* set vol=0 to output mixers */
10112 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10113 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10114 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10116 /* set up input amps for analog loopback */
10117 /* Amp Indices: DAC = 0, mixer = 1 */
10118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10123 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10127 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10128 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10129 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10130 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10131 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10132 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10134 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10137 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10138 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10140 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10141 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10142 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10143 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10144 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10145 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10147 /* FIXME: use matrix-type input source selection */
10148 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10149 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10152 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10154 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10155 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10156 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10158 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10160 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10161 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10162 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10163 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10164 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10170 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10171 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10172 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10174 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10179 #ifdef CONFIG_SND_HDA_POWER_SAVE
10180 #define alc262_loopbacks alc880_loopbacks
10183 /* pcm configuration: identiacal with ALC880 */
10184 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10185 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10186 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10187 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10190 * BIOS auto configuration
10192 static int alc262_parse_auto_config(struct hda_codec *codec)
10194 struct alc_spec *spec = codec->spec;
10196 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10198 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10202 if (!spec->autocfg.line_outs)
10203 return 0; /* can't find valid BIOS pin config */
10204 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10207 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10211 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10213 if (spec->autocfg.dig_out_pin)
10214 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10215 if (spec->autocfg.dig_in_pin)
10216 spec->dig_in_nid = ALC262_DIGIN_NID;
10218 if (spec->kctl_alloc)
10219 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10221 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
10222 spec->num_mux_defs = 1;
10223 spec->input_mux = &spec->private_imux;
10225 err = alc_auto_add_mic_boost(codec);
10232 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10233 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10234 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10235 #define alc262_auto_init_input_src alc882_auto_init_input_src
10238 /* init callback for auto-configuration model -- overriding the default init */
10239 static void alc262_auto_init(struct hda_codec *codec)
10241 struct alc_spec *spec = codec->spec;
10242 alc262_auto_init_multi_out(codec);
10243 alc262_auto_init_hp_out(codec);
10244 alc262_auto_init_analog_input(codec);
10245 alc262_auto_init_input_src(codec);
10246 if (spec->unsol_event)
10247 alc_sku_automute(codec);
10251 * configuration and preset
10253 static const char *alc262_models[ALC262_MODEL_LAST] = {
10254 [ALC262_BASIC] = "basic",
10255 [ALC262_HIPPO] = "hippo",
10256 [ALC262_HIPPO_1] = "hippo_1",
10257 [ALC262_FUJITSU] = "fujitsu",
10258 [ALC262_HP_BPC] = "hp-bpc",
10259 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10260 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10261 [ALC262_HP_RP5700] = "hp-rp5700",
10262 [ALC262_BENQ_ED8] = "benq",
10263 [ALC262_BENQ_T31] = "benq-t31",
10264 [ALC262_SONY_ASSAMD] = "sony-assamd",
10265 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10266 [ALC262_ULTRA] = "ultra",
10267 [ALC262_LENOVO_3000] = "lenovo-3000",
10268 [ALC262_NEC] = "nec",
10269 [ALC262_AUTO] = "auto",
10272 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10273 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10274 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10275 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10276 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10277 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10278 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10279 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10280 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10281 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10282 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10283 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10284 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10285 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10286 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10287 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10288 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10289 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10290 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10291 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10292 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10293 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10294 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10295 ALC262_HP_TC_T5735),
10296 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10297 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10298 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10299 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10300 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10301 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10302 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10303 ALC262_SONY_ASSAMD),
10304 SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
10305 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10306 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10307 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10308 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10309 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10310 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10311 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10312 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10316 static struct alc_config_preset alc262_presets[] = {
10318 .mixers = { alc262_base_mixer },
10319 .init_verbs = { alc262_init_verbs },
10320 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10321 .dac_nids = alc262_dac_nids,
10323 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10324 .channel_mode = alc262_modes,
10325 .input_mux = &alc262_capture_source,
10328 .mixers = { alc262_base_mixer },
10329 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10330 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10331 .dac_nids = alc262_dac_nids,
10333 .dig_out_nid = ALC262_DIGOUT_NID,
10334 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10335 .channel_mode = alc262_modes,
10336 .input_mux = &alc262_capture_source,
10337 .unsol_event = alc262_hippo_unsol_event,
10338 .init_hook = alc262_hippo_automute,
10340 [ALC262_HIPPO_1] = {
10341 .mixers = { alc262_hippo1_mixer },
10342 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10343 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10344 .dac_nids = alc262_dac_nids,
10346 .dig_out_nid = ALC262_DIGOUT_NID,
10347 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10348 .channel_mode = alc262_modes,
10349 .input_mux = &alc262_capture_source,
10350 .unsol_event = alc262_hippo1_unsol_event,
10351 .init_hook = alc262_hippo1_automute,
10353 [ALC262_FUJITSU] = {
10354 .mixers = { alc262_fujitsu_mixer },
10355 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10356 alc262_fujitsu_unsol_verbs },
10357 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10358 .dac_nids = alc262_dac_nids,
10360 .dig_out_nid = ALC262_DIGOUT_NID,
10361 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10362 .channel_mode = alc262_modes,
10363 .input_mux = &alc262_fujitsu_capture_source,
10364 .unsol_event = alc262_fujitsu_unsol_event,
10365 .init_hook = alc262_fujitsu_init_hook,
10367 [ALC262_HP_BPC] = {
10368 .mixers = { alc262_HP_BPC_mixer },
10369 .init_verbs = { alc262_HP_BPC_init_verbs },
10370 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10371 .dac_nids = alc262_dac_nids,
10373 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10374 .channel_mode = alc262_modes,
10375 .input_mux = &alc262_HP_capture_source,
10376 .unsol_event = alc262_hp_bpc_unsol_event,
10377 .init_hook = alc262_hp_bpc_automute,
10379 [ALC262_HP_BPC_D7000_WF] = {
10380 .mixers = { alc262_HP_BPC_WildWest_mixer },
10381 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10382 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10383 .dac_nids = alc262_dac_nids,
10385 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10386 .channel_mode = alc262_modes,
10387 .input_mux = &alc262_HP_D7000_capture_source,
10388 .unsol_event = alc262_hp_wildwest_unsol_event,
10389 .init_hook = alc262_hp_wildwest_automute,
10391 [ALC262_HP_BPC_D7000_WL] = {
10392 .mixers = { alc262_HP_BPC_WildWest_mixer,
10393 alc262_HP_BPC_WildWest_option_mixer },
10394 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10395 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10396 .dac_nids = alc262_dac_nids,
10398 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10399 .channel_mode = alc262_modes,
10400 .input_mux = &alc262_HP_D7000_capture_source,
10401 .unsol_event = alc262_hp_wildwest_unsol_event,
10402 .init_hook = alc262_hp_wildwest_automute,
10404 [ALC262_HP_TC_T5735] = {
10405 .mixers = { alc262_hp_t5735_mixer },
10406 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10407 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10408 .dac_nids = alc262_dac_nids,
10410 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10411 .channel_mode = alc262_modes,
10412 .input_mux = &alc262_capture_source,
10413 .unsol_event = alc262_hp_t5735_unsol_event,
10414 .init_hook = alc262_hp_t5735_init_hook,
10416 [ALC262_HP_RP5700] = {
10417 .mixers = { alc262_hp_rp5700_mixer },
10418 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10419 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10420 .dac_nids = alc262_dac_nids,
10421 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10422 .channel_mode = alc262_modes,
10423 .input_mux = &alc262_hp_rp5700_capture_source,
10425 [ALC262_BENQ_ED8] = {
10426 .mixers = { alc262_base_mixer },
10427 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10428 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10429 .dac_nids = alc262_dac_nids,
10431 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10432 .channel_mode = alc262_modes,
10433 .input_mux = &alc262_capture_source,
10435 [ALC262_SONY_ASSAMD] = {
10436 .mixers = { alc262_sony_mixer },
10437 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10438 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10439 .dac_nids = alc262_dac_nids,
10441 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10442 .channel_mode = alc262_modes,
10443 .input_mux = &alc262_capture_source,
10444 .unsol_event = alc262_hippo_unsol_event,
10445 .init_hook = alc262_hippo_automute,
10447 [ALC262_BENQ_T31] = {
10448 .mixers = { alc262_benq_t31_mixer },
10449 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10450 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10451 .dac_nids = alc262_dac_nids,
10453 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10454 .channel_mode = alc262_modes,
10455 .input_mux = &alc262_capture_source,
10456 .unsol_event = alc262_hippo_unsol_event,
10457 .init_hook = alc262_hippo_automute,
10460 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10461 .init_verbs = { alc262_ultra_verbs },
10462 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10463 .dac_nids = alc262_dac_nids,
10464 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10465 .channel_mode = alc262_modes,
10466 .input_mux = &alc262_ultra_capture_source,
10467 .adc_nids = alc262_adc_nids, /* ADC0 */
10468 .capsrc_nids = alc262_capsrc_nids,
10469 .num_adc_nids = 1, /* single ADC */
10470 .unsol_event = alc262_ultra_unsol_event,
10471 .init_hook = alc262_ultra_automute,
10473 [ALC262_LENOVO_3000] = {
10474 .mixers = { alc262_lenovo_3000_mixer },
10475 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10476 alc262_lenovo_3000_unsol_verbs },
10477 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10478 .dac_nids = alc262_dac_nids,
10480 .dig_out_nid = ALC262_DIGOUT_NID,
10481 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10482 .channel_mode = alc262_modes,
10483 .input_mux = &alc262_fujitsu_capture_source,
10484 .unsol_event = alc262_lenovo_3000_unsol_event,
10487 .mixers = { alc262_nec_mixer },
10488 .init_verbs = { alc262_nec_verbs },
10489 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10490 .dac_nids = alc262_dac_nids,
10492 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10493 .channel_mode = alc262_modes,
10494 .input_mux = &alc262_capture_source,
10496 [ALC262_TOSHIBA_S06] = {
10497 .mixers = { alc262_toshiba_s06_mixer },
10498 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10499 alc262_eapd_verbs },
10500 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10501 .capsrc_nids = alc262_dmic_capsrc_nids,
10502 .dac_nids = alc262_dac_nids,
10503 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10504 .dig_out_nid = ALC262_DIGOUT_NID,
10505 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10506 .channel_mode = alc262_modes,
10507 .input_mux = &alc262_dmic_capture_source,
10508 .unsol_event = alc262_toshiba_s06_unsol_event,
10509 .init_hook = alc262_toshiba_s06_init_hook,
10513 static int patch_alc262(struct hda_codec *codec)
10515 struct alc_spec *spec;
10519 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10523 codec->spec = spec;
10525 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10530 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10531 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10532 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10533 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10537 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10539 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10543 if (board_config < 0) {
10544 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10545 "trying auto-probe from BIOS...\n");
10546 board_config = ALC262_AUTO;
10549 if (board_config == ALC262_AUTO) {
10550 /* automatic parse from the BIOS config */
10551 err = alc262_parse_auto_config(codec);
10557 "hda_codec: Cannot set up configuration "
10558 "from BIOS. Using base mode...\n");
10559 board_config = ALC262_BASIC;
10563 if (board_config != ALC262_AUTO)
10564 setup_preset(spec, &alc262_presets[board_config]);
10566 spec->stream_name_analog = "ALC262 Analog";
10567 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10568 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10570 spec->stream_name_digital = "ALC262 Digital";
10571 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10572 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10574 if (!spec->adc_nids && spec->input_mux) {
10575 /* check whether NID 0x07 is valid */
10576 unsigned int wcap = get_wcaps(codec, 0x07);
10579 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10580 if (wcap != AC_WID_AUD_IN) {
10581 spec->adc_nids = alc262_adc_nids_alt;
10582 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10583 spec->capsrc_nids = alc262_capsrc_nids_alt;
10584 spec->mixers[spec->num_mixers] =
10585 alc262_capture_alt_mixer;
10586 spec->num_mixers++;
10588 spec->adc_nids = alc262_adc_nids;
10589 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10590 spec->capsrc_nids = alc262_capsrc_nids;
10591 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10592 spec->num_mixers++;
10596 spec->vmaster_nid = 0x0c;
10598 codec->patch_ops = alc_patch_ops;
10599 if (board_config == ALC262_AUTO)
10600 spec->init_hook = alc262_auto_init;
10601 #ifdef CONFIG_SND_HDA_POWER_SAVE
10602 if (!spec->loopback.amplist)
10603 spec->loopback.amplist = alc262_loopbacks;
10610 * ALC268 channel source setting (2 channel)
10612 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10613 #define alc268_modes alc260_modes
10615 static hda_nid_t alc268_dac_nids[2] = {
10620 static hda_nid_t alc268_adc_nids[2] = {
10625 static hda_nid_t alc268_adc_nids_alt[1] = {
10630 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10632 static struct snd_kcontrol_new alc268_base_mixer[] = {
10633 /* output mixer control */
10634 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10635 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10636 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10638 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10639 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10640 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10644 /* bind Beep switches of both NID 0x0f and 0x10 */
10645 static struct hda_bind_ctls alc268_bind_beep_sw = {
10646 .ops = &snd_hda_bind_sw,
10648 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10649 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10654 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10655 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10656 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10660 static struct hda_verb alc268_eapd_verbs[] = {
10661 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10662 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10666 /* Toshiba specific */
10667 #define alc268_toshiba_automute alc262_hippo_automute
10669 static struct hda_verb alc268_toshiba_verbs[] = {
10670 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10674 static struct hda_input_mux alc268_acer_lc_capture_source = {
10682 /* Acer specific */
10683 /* bind volumes of both NID 0x02 and 0x03 */
10684 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10685 .ops = &snd_hda_bind_vol,
10687 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10688 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10693 /* mute/unmute internal speaker according to the hp jack and mute state */
10694 static void alc268_acer_automute(struct hda_codec *codec, int force)
10696 struct alc_spec *spec = codec->spec;
10699 if (force || !spec->sense_updated) {
10700 unsigned int present;
10701 present = snd_hda_codec_read(codec, 0x14, 0,
10702 AC_VERB_GET_PIN_SENSE, 0);
10703 spec->jack_present = (present & 0x80000000) != 0;
10704 spec->sense_updated = 1;
10706 if (spec->jack_present)
10707 mute = HDA_AMP_MUTE; /* mute internal speaker */
10708 else /* unmute internal speaker if necessary */
10709 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10710 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10711 HDA_AMP_MUTE, mute);
10715 /* bind hp and internal speaker mute (with plug check) */
10716 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10717 struct snd_ctl_elem_value *ucontrol)
10719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10720 long *valp = ucontrol->value.integer.value;
10723 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10725 valp[0] ? 0 : HDA_AMP_MUTE);
10726 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10728 valp[1] ? 0 : HDA_AMP_MUTE);
10730 alc268_acer_automute(codec, 0);
10734 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10735 /* output mixer control */
10736 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10739 .name = "Master Playback Switch",
10740 .info = snd_hda_mixer_amp_switch_info,
10741 .get = snd_hda_mixer_amp_switch_get,
10742 .put = alc268_acer_master_sw_put,
10743 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10745 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10749 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10750 /* output mixer control */
10751 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10753 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10754 .name = "Master Playback Switch",
10755 .info = snd_hda_mixer_amp_switch_info,
10756 .get = snd_hda_mixer_amp_switch_get,
10757 .put = alc268_acer_master_sw_put,
10758 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10760 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10761 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10762 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10766 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10767 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10768 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10769 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10770 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10771 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10772 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10776 static struct hda_verb alc268_acer_verbs[] = {
10777 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10778 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10781 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10782 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10783 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10787 /* unsolicited event for HP jack sensing */
10788 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10791 if ((res >> 26) != ALC880_HP_EVENT)
10793 alc268_toshiba_automute(codec);
10796 static void alc268_acer_unsol_event(struct hda_codec *codec,
10799 if ((res >> 26) != ALC880_HP_EVENT)
10801 alc268_acer_automute(codec, 1);
10804 static void alc268_acer_init_hook(struct hda_codec *codec)
10806 alc268_acer_automute(codec, 1);
10809 /* toggle speaker-output according to the hp-jack state */
10810 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10812 unsigned int present;
10813 unsigned char bits;
10815 present = snd_hda_codec_read(codec, 0x15, 0,
10816 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10817 bits = present ? AMP_IN_MUTE(0) : 0;
10818 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10819 AMP_IN_MUTE(0), bits);
10820 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10821 AMP_IN_MUTE(0), bits);
10825 static void alc268_acer_mic_automute(struct hda_codec *codec)
10827 unsigned int present;
10829 present = snd_hda_codec_read(codec, 0x18, 0,
10830 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10831 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10832 present ? 0x0 : 0x6);
10835 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10838 if ((res >> 26) == ALC880_HP_EVENT)
10839 alc268_aspire_one_speaker_automute(codec);
10840 if ((res >> 26) == ALC880_MIC_EVENT)
10841 alc268_acer_mic_automute(codec);
10844 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10846 alc268_aspire_one_speaker_automute(codec);
10847 alc268_acer_mic_automute(codec);
10850 static struct snd_kcontrol_new alc268_dell_mixer[] = {
10851 /* output mixer control */
10852 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10853 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10854 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10855 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10856 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10857 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10861 static struct hda_verb alc268_dell_verbs[] = {
10862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10864 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10868 /* mute/unmute internal speaker according to the hp jack and mute state */
10869 static void alc268_dell_automute(struct hda_codec *codec)
10871 unsigned int present;
10874 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10875 if (present & 0x80000000)
10876 mute = HDA_AMP_MUTE;
10878 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10879 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10880 HDA_AMP_MUTE, mute);
10883 static void alc268_dell_unsol_event(struct hda_codec *codec,
10886 if ((res >> 26) != ALC880_HP_EVENT)
10888 alc268_dell_automute(codec);
10891 #define alc268_dell_init_hook alc268_dell_automute
10893 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10894 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10895 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10896 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10898 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10899 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10900 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10901 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10905 static struct hda_verb alc267_quanta_il1_verbs[] = {
10906 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10907 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10911 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10913 unsigned int present;
10915 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10916 & AC_PINSENSE_PRESENCE;
10917 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10918 present ? 0 : PIN_OUT);
10921 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10923 unsigned int present;
10925 present = snd_hda_codec_read(codec, 0x18, 0,
10926 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10927 snd_hda_codec_write(codec, 0x23, 0,
10928 AC_VERB_SET_CONNECT_SEL,
10929 present ? 0x00 : 0x01);
10932 static void alc267_quanta_il1_automute(struct hda_codec *codec)
10934 alc267_quanta_il1_hp_automute(codec);
10935 alc267_quanta_il1_mic_automute(codec);
10938 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10941 switch (res >> 26) {
10942 case ALC880_HP_EVENT:
10943 alc267_quanta_il1_hp_automute(codec);
10945 case ALC880_MIC_EVENT:
10946 alc267_quanta_il1_mic_automute(codec);
10952 * generic initialization of ADC, input mixers and output mixers
10954 static struct hda_verb alc268_base_init_verbs[] = {
10955 /* Unmute DAC0-1 and set vol = 0 */
10956 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10957 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10958 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10959 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10960 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10961 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10964 * Set up output mixers (0x0c - 0x0e)
10966 /* set vol=0 to output mixers */
10967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10968 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10970 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10972 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10973 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10975 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10978 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10979 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10980 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10981 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10982 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10986 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10987 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10988 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10989 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10990 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10992 /* set PCBEEP vol = 0, mute connections */
10993 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10994 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10995 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10997 /* Unmute Selector 23h,24h and set the default input to mic-in */
10999 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11001 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11002 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11008 * generic initialization of ADC, input mixers and output mixers
11010 static struct hda_verb alc268_volume_init_verbs[] = {
11011 /* set output DAC */
11012 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11013 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11014 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11015 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11017 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11018 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11019 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11020 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11021 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11023 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11024 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11025 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11026 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11027 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11029 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11030 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11031 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11032 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11034 /* set PCBEEP vol = 0, mute connections */
11035 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11036 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11037 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11042 #define alc268_mux_enum_info alc_mux_enum_info
11043 #define alc268_mux_enum_get alc_mux_enum_get
11044 #define alc268_mux_enum_put alc_mux_enum_put
11046 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11047 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11048 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11050 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11051 /* The multiple "Capture Source" controls confuse alsamixer
11052 * So call somewhat different..
11054 /* .name = "Capture Source", */
11055 .name = "Input Source",
11057 .info = alc268_mux_enum_info,
11058 .get = alc268_mux_enum_get,
11059 .put = alc268_mux_enum_put,
11064 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11065 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11066 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11067 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11068 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11070 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11071 /* The multiple "Capture Source" controls confuse alsamixer
11072 * So call somewhat different..
11074 /* .name = "Capture Source", */
11075 .name = "Input Source",
11077 .info = alc268_mux_enum_info,
11078 .get = alc268_mux_enum_get,
11079 .put = alc268_mux_enum_put,
11084 static struct hda_input_mux alc268_capture_source = {
11088 { "Front Mic", 0x1 },
11094 static struct hda_input_mux alc268_acer_capture_source = {
11098 { "Internal Mic", 0x6 },
11103 #ifdef CONFIG_SND_DEBUG
11104 static struct snd_kcontrol_new alc268_test_mixer[] = {
11105 /* Volume widgets */
11106 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11107 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11108 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11109 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11110 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11111 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11112 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11113 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11114 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11115 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11116 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11117 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11118 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11119 /* The below appears problematic on some hardwares */
11120 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11121 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11122 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11123 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11124 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11126 /* Modes for retasking pin widgets */
11127 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11128 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11129 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11130 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11132 /* Controls for GPIO pins, assuming they are configured as outputs */
11133 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11134 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11135 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11136 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11138 /* Switches to allow the digital SPDIF output pin to be enabled.
11139 * The ALC268 does not have an SPDIF input.
11141 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11143 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11144 * this output to turn on an external amplifier.
11146 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11147 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11153 /* create input playback/capture controls for the given pin */
11154 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11155 const char *ctlname, int idx)
11160 sprintf(name, "%s Playback Volume", ctlname);
11162 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11163 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11167 } else if (nid == 0x15) {
11168 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11169 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11175 sprintf(name, "%s Playback Switch", ctlname);
11176 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11177 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11183 /* add playback controls from the parsed DAC table */
11184 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11185 const struct auto_pin_cfg *cfg)
11190 spec->multiout.num_dacs = 2; /* only use one dac */
11191 spec->multiout.dac_nids = spec->private_dac_nids;
11192 spec->multiout.dac_nids[0] = 2;
11193 spec->multiout.dac_nids[1] = 3;
11195 nid = cfg->line_out_pins[0];
11197 alc268_new_analog_output(spec, nid, "Front", 0);
11199 nid = cfg->speaker_pins[0];
11201 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11202 "Speaker Playback Volume",
11203 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11207 nid = cfg->hp_pins[0];
11209 alc268_new_analog_output(spec, nid, "Headphone", 0);
11211 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11213 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11214 "Mono Playback Switch",
11215 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11222 /* create playback/capture controls for input pins */
11223 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11224 const struct auto_pin_cfg *cfg)
11226 struct hda_input_mux *imux = &spec->private_imux;
11229 for (i = 0; i < AUTO_PIN_LAST; i++) {
11230 switch(cfg->input_pins[i]) {
11232 idx1 = 0; /* Mic 1 */
11235 idx1 = 1; /* Mic 2 */
11238 idx1 = 2; /* Line In */
11245 idx1 = 6; /* digital mics */
11250 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11251 imux->items[imux->num_items].index = idx1;
11257 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11259 struct alc_spec *spec = codec->spec;
11260 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11261 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11262 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11263 unsigned int dac_vol1, dac_vol2;
11266 snd_hda_codec_write(codec, speaker_nid, 0,
11267 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11268 snd_hda_codec_write(codec, 0x0f, 0,
11269 AC_VERB_SET_AMP_GAIN_MUTE,
11271 snd_hda_codec_write(codec, 0x10, 0,
11272 AC_VERB_SET_AMP_GAIN_MUTE,
11275 snd_hda_codec_write(codec, 0x0f, 0,
11276 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11277 snd_hda_codec_write(codec, 0x10, 0,
11278 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11281 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11282 if (line_nid == 0x14)
11283 dac_vol2 = AMP_OUT_ZERO;
11284 else if (line_nid == 0x15)
11285 dac_vol1 = AMP_OUT_ZERO;
11286 if (hp_nid == 0x14)
11287 dac_vol2 = AMP_OUT_ZERO;
11288 else if (hp_nid == 0x15)
11289 dac_vol1 = AMP_OUT_ZERO;
11290 if (line_nid != 0x16 || hp_nid != 0x16 ||
11291 spec->autocfg.line_out_pins[1] != 0x16 ||
11292 spec->autocfg.line_out_pins[2] != 0x16)
11293 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11295 snd_hda_codec_write(codec, 0x02, 0,
11296 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11297 snd_hda_codec_write(codec, 0x03, 0,
11298 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11301 /* pcm configuration: identiacal with ALC880 */
11302 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11303 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11304 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11305 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11308 * BIOS auto configuration
11310 static int alc268_parse_auto_config(struct hda_codec *codec)
11312 struct alc_spec *spec = codec->spec;
11314 static hda_nid_t alc268_ignore[] = { 0 };
11316 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11320 if (!spec->autocfg.line_outs)
11321 return 0; /* can't find valid BIOS pin config */
11323 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11326 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11330 spec->multiout.max_channels = 2;
11332 /* digital only support output */
11333 if (spec->autocfg.dig_out_pin)
11334 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11336 if (spec->kctl_alloc)
11337 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11339 if (spec->autocfg.speaker_pins[0] != 0x1d)
11340 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11342 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11343 spec->num_mux_defs = 1;
11344 spec->input_mux = &spec->private_imux;
11346 err = alc_auto_add_mic_boost(codec);
11353 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11354 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11355 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11357 /* init callback for auto-configuration model -- overriding the default init */
11358 static void alc268_auto_init(struct hda_codec *codec)
11360 struct alc_spec *spec = codec->spec;
11361 alc268_auto_init_multi_out(codec);
11362 alc268_auto_init_hp_out(codec);
11363 alc268_auto_init_mono_speaker_out(codec);
11364 alc268_auto_init_analog_input(codec);
11365 if (spec->unsol_event)
11366 alc_sku_automute(codec);
11370 * configuration and preset
11372 static const char *alc268_models[ALC268_MODEL_LAST] = {
11373 [ALC267_QUANTA_IL1] = "quanta-il1",
11374 [ALC268_3ST] = "3stack",
11375 [ALC268_TOSHIBA] = "toshiba",
11376 [ALC268_ACER] = "acer",
11377 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11378 [ALC268_DELL] = "dell",
11379 [ALC268_ZEPTO] = "zepto",
11380 #ifdef CONFIG_SND_DEBUG
11381 [ALC268_TEST] = "test",
11383 [ALC268_AUTO] = "auto",
11386 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11387 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11388 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11389 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11390 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11391 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11392 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11393 ALC268_ACER_ASPIRE_ONE),
11394 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11395 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11396 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11397 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11398 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11399 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11400 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11401 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11402 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11406 static struct alc_config_preset alc268_presets[] = {
11407 [ALC267_QUANTA_IL1] = {
11408 .mixers = { alc267_quanta_il1_mixer },
11409 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11410 alc267_quanta_il1_verbs },
11411 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11412 .dac_nids = alc268_dac_nids,
11413 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11414 .adc_nids = alc268_adc_nids_alt,
11416 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11417 .channel_mode = alc268_modes,
11418 .input_mux = &alc268_capture_source,
11419 .unsol_event = alc267_quanta_il1_unsol_event,
11420 .init_hook = alc267_quanta_il1_automute,
11423 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11424 alc268_beep_mixer },
11425 .init_verbs = { alc268_base_init_verbs },
11426 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11427 .dac_nids = alc268_dac_nids,
11428 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11429 .adc_nids = alc268_adc_nids_alt,
11430 .capsrc_nids = alc268_capsrc_nids,
11432 .dig_out_nid = ALC268_DIGOUT_NID,
11433 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11434 .channel_mode = alc268_modes,
11435 .input_mux = &alc268_capture_source,
11437 [ALC268_TOSHIBA] = {
11438 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11439 alc268_beep_mixer },
11440 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11441 alc268_toshiba_verbs },
11442 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11443 .dac_nids = alc268_dac_nids,
11444 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11445 .adc_nids = alc268_adc_nids_alt,
11446 .capsrc_nids = alc268_capsrc_nids,
11448 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11449 .channel_mode = alc268_modes,
11450 .input_mux = &alc268_capture_source,
11451 .unsol_event = alc268_toshiba_unsol_event,
11452 .init_hook = alc268_toshiba_automute,
11455 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11456 alc268_beep_mixer },
11457 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11458 alc268_acer_verbs },
11459 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11460 .dac_nids = alc268_dac_nids,
11461 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11462 .adc_nids = alc268_adc_nids_alt,
11463 .capsrc_nids = alc268_capsrc_nids,
11465 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11466 .channel_mode = alc268_modes,
11467 .input_mux = &alc268_acer_capture_source,
11468 .unsol_event = alc268_acer_unsol_event,
11469 .init_hook = alc268_acer_init_hook,
11471 [ALC268_ACER_ASPIRE_ONE] = {
11472 .mixers = { alc268_acer_aspire_one_mixer,
11473 alc268_capture_alt_mixer },
11474 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11475 alc268_acer_aspire_one_verbs },
11476 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11477 .dac_nids = alc268_dac_nids,
11478 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11479 .adc_nids = alc268_adc_nids_alt,
11480 .capsrc_nids = alc268_capsrc_nids,
11482 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11483 .channel_mode = alc268_modes,
11484 .input_mux = &alc268_acer_lc_capture_source,
11485 .unsol_event = alc268_acer_lc_unsol_event,
11486 .init_hook = alc268_acer_lc_init_hook,
11489 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11490 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11491 alc268_dell_verbs },
11492 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11493 .dac_nids = alc268_dac_nids,
11495 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11496 .channel_mode = alc268_modes,
11497 .unsol_event = alc268_dell_unsol_event,
11498 .init_hook = alc268_dell_init_hook,
11499 .input_mux = &alc268_capture_source,
11502 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11503 alc268_beep_mixer },
11504 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11505 alc268_toshiba_verbs },
11506 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11507 .dac_nids = alc268_dac_nids,
11508 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11509 .adc_nids = alc268_adc_nids_alt,
11510 .capsrc_nids = alc268_capsrc_nids,
11512 .dig_out_nid = ALC268_DIGOUT_NID,
11513 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11514 .channel_mode = alc268_modes,
11515 .input_mux = &alc268_capture_source,
11516 .unsol_event = alc268_toshiba_unsol_event,
11517 .init_hook = alc268_toshiba_automute
11519 #ifdef CONFIG_SND_DEBUG
11521 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11522 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11523 alc268_volume_init_verbs },
11524 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11525 .dac_nids = alc268_dac_nids,
11526 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11527 .adc_nids = alc268_adc_nids_alt,
11528 .capsrc_nids = alc268_capsrc_nids,
11530 .dig_out_nid = ALC268_DIGOUT_NID,
11531 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11532 .channel_mode = alc268_modes,
11533 .input_mux = &alc268_capture_source,
11538 static int patch_alc268(struct hda_codec *codec)
11540 struct alc_spec *spec;
11544 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11548 codec->spec = spec;
11550 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11554 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11555 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11556 "trying auto-probe from BIOS...\n");
11557 board_config = ALC268_AUTO;
11560 if (board_config == ALC268_AUTO) {
11561 /* automatic parse from the BIOS config */
11562 err = alc268_parse_auto_config(codec);
11568 "hda_codec: Cannot set up configuration "
11569 "from BIOS. Using base mode...\n");
11570 board_config = ALC268_3ST;
11574 if (board_config != ALC268_AUTO)
11575 setup_preset(spec, &alc268_presets[board_config]);
11577 if (codec->vendor_id == 0x10ec0267) {
11578 spec->stream_name_analog = "ALC267 Analog";
11579 spec->stream_name_digital = "ALC267 Digital";
11581 spec->stream_name_analog = "ALC268 Analog";
11582 spec->stream_name_digital = "ALC268 Digital";
11585 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11586 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11587 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11589 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11591 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11592 /* override the amp caps for beep generator */
11593 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11594 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11595 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11596 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11597 (0 << AC_AMPCAP_MUTE_SHIFT));
11599 if (!spec->adc_nids && spec->input_mux) {
11600 /* check whether NID 0x07 is valid */
11601 unsigned int wcap = get_wcaps(codec, 0x07);
11605 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11606 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11607 spec->adc_nids = alc268_adc_nids_alt;
11608 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11609 spec->mixers[spec->num_mixers] =
11610 alc268_capture_alt_mixer;
11611 spec->num_mixers++;
11613 spec->adc_nids = alc268_adc_nids;
11614 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11615 spec->mixers[spec->num_mixers] =
11616 alc268_capture_mixer;
11617 spec->num_mixers++;
11619 spec->capsrc_nids = alc268_capsrc_nids;
11620 /* set default input source */
11621 for (i = 0; i < spec->num_adc_nids; i++)
11622 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11623 0, AC_VERB_SET_CONNECT_SEL,
11624 spec->input_mux->items[0].index);
11627 spec->vmaster_nid = 0x02;
11629 codec->patch_ops = alc_patch_ops;
11630 if (board_config == ALC268_AUTO)
11631 spec->init_hook = alc268_auto_init;
11637 * ALC269 channel source setting (2 channel)
11639 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11641 #define alc269_dac_nids alc260_dac_nids
11643 static hda_nid_t alc269_adc_nids[1] = {
11648 static hda_nid_t alc269_capsrc_nids[1] = {
11652 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11656 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11664 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11672 #define alc269_modes alc260_modes
11673 #define alc269_capture_source alc880_lg_lw_capture_source
11675 static struct snd_kcontrol_new alc269_base_mixer[] = {
11676 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11677 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11678 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11679 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11682 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11683 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11684 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11685 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11686 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11687 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11689 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11693 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11694 /* output mixer control */
11695 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11697 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11698 .name = "Master Playback Switch",
11699 .info = snd_hda_mixer_amp_switch_info,
11700 .get = snd_hda_mixer_amp_switch_get,
11701 .put = alc268_acer_master_sw_put,
11702 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11704 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11705 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11706 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11707 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11708 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11709 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11710 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11711 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11715 /* bind volumes of both NID 0x0c and 0x0d */
11716 static struct hda_bind_ctls alc269_epc_bind_vol = {
11717 .ops = &snd_hda_bind_vol,
11719 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11720 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11725 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11726 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11727 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11728 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11732 /* capture mixer elements */
11733 static struct snd_kcontrol_new alc269_capture_mixer[] = {
11734 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11735 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11738 /* The multiple "Capture Source" controls confuse alsamixer
11739 * So call somewhat different..
11741 /* .name = "Capture Source", */
11742 .name = "Input Source",
11744 .info = alc_mux_enum_info,
11745 .get = alc_mux_enum_get,
11746 .put = alc_mux_enum_put,
11751 /* capture mixer elements */
11752 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11753 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11754 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11759 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11760 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11761 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11765 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11766 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11767 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11768 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11769 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11770 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11771 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11775 /* toggle speaker-output according to the hp-jack state */
11776 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11778 unsigned int present;
11779 unsigned char bits;
11781 present = snd_hda_codec_read(codec, 0x15, 0,
11782 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11783 bits = present ? AMP_IN_MUTE(0) : 0;
11784 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11785 AMP_IN_MUTE(0), bits);
11786 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11787 AMP_IN_MUTE(0), bits);
11789 snd_hda_codec_write(codec, 0x20, 0,
11790 AC_VERB_SET_COEF_INDEX, 0x0c);
11791 snd_hda_codec_write(codec, 0x20, 0,
11792 AC_VERB_SET_PROC_COEF, 0x680);
11794 snd_hda_codec_write(codec, 0x20, 0,
11795 AC_VERB_SET_COEF_INDEX, 0x0c);
11796 snd_hda_codec_write(codec, 0x20, 0,
11797 AC_VERB_SET_PROC_COEF, 0x480);
11800 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11802 unsigned int present;
11804 present = snd_hda_codec_read(codec, 0x18, 0,
11805 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11806 snd_hda_codec_write(codec, 0x23, 0,
11807 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11810 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11813 if ((res >> 26) == ALC880_HP_EVENT)
11814 alc269_quanta_fl1_speaker_automute(codec);
11815 if ((res >> 26) == ALC880_MIC_EVENT)
11816 alc269_quanta_fl1_mic_automute(codec);
11819 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11821 alc269_quanta_fl1_speaker_automute(codec);
11822 alc269_quanta_fl1_mic_automute(codec);
11825 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11826 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11827 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11828 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11829 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11830 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11831 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11832 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11836 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11837 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11838 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11839 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11840 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11841 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11842 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11846 /* toggle speaker-output according to the hp-jack state */
11847 static void alc269_speaker_automute(struct hda_codec *codec)
11849 unsigned int present;
11850 unsigned char bits;
11852 present = snd_hda_codec_read(codec, 0x15, 0,
11853 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11854 bits = present ? AMP_IN_MUTE(0) : 0;
11855 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11856 AMP_IN_MUTE(0), bits);
11857 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11858 AMP_IN_MUTE(0), bits);
11861 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11863 unsigned int present;
11865 present = snd_hda_codec_read(codec, 0x18, 0,
11866 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11867 snd_hda_codec_write(codec, 0x23, 0,
11868 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
11871 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11873 unsigned int present;
11875 present = snd_hda_codec_read(codec, 0x18, 0,
11876 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11877 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11878 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11879 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11880 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11883 /* unsolicited event for HP jack sensing */
11884 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11887 if ((res >> 26) == ALC880_HP_EVENT)
11888 alc269_speaker_automute(codec);
11890 if ((res >> 26) == ALC880_MIC_EVENT)
11891 alc269_eeepc_dmic_automute(codec);
11894 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11896 alc269_speaker_automute(codec);
11897 alc269_eeepc_dmic_automute(codec);
11900 /* unsolicited event for HP jack sensing */
11901 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11904 if ((res >> 26) == ALC880_HP_EVENT)
11905 alc269_speaker_automute(codec);
11907 if ((res >> 26) == ALC880_MIC_EVENT)
11908 alc269_eeepc_amic_automute(codec);
11911 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11913 alc269_speaker_automute(codec);
11914 alc269_eeepc_amic_automute(codec);
11918 * generic initialization of ADC, input mixers and output mixers
11920 static struct hda_verb alc269_init_verbs[] = {
11922 * Unmute ADC0 and set the default input to mic-in
11924 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11926 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11927 * analog-loopback mixer widget
11928 * Note: PASD motherboards uses the Line In 2 as the input for
11929 * front panel mic (mic 2)
11931 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11933 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11934 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11935 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11936 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11939 * Set up output mixers (0x0c - 0x0e)
11941 /* set vol=0 to output mixers */
11942 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11943 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11945 /* set up input amps for analog loopback */
11946 /* Amp Indices: DAC = 0, mixer = 1 */
11947 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11949 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11950 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11951 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11952 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11954 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11955 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11956 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11957 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11958 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11959 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11962 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11963 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11964 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11965 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11966 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11967 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11968 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11970 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11971 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11973 /* FIXME: use matrix-type input source selection */
11974 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11975 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11978 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11979 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11982 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11983 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11987 /* add playback controls from the parsed DAC table */
11988 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11989 const struct auto_pin_cfg *cfg)
11994 spec->multiout.num_dacs = 1; /* only use one dac */
11995 spec->multiout.dac_nids = spec->private_dac_nids;
11996 spec->multiout.dac_nids[0] = 2;
11998 nid = cfg->line_out_pins[0];
12000 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12001 "Front Playback Volume",
12002 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12005 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12006 "Front Playback Switch",
12007 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12012 nid = cfg->speaker_pins[0];
12014 if (!cfg->line_out_pins[0]) {
12015 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12016 "Speaker Playback Volume",
12017 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12023 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12024 "Speaker Playback Switch",
12025 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12030 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12031 "Speaker Playback Switch",
12032 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12038 nid = cfg->hp_pins[0];
12040 /* spec->multiout.hp_nid = 2; */
12041 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12042 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12043 "Headphone Playback Volume",
12044 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12050 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12051 "Headphone Playback Switch",
12052 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12057 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12058 "Headphone Playback Switch",
12059 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12068 #define alc269_auto_create_analog_input_ctls \
12069 alc880_auto_create_analog_input_ctls
12071 #ifdef CONFIG_SND_HDA_POWER_SAVE
12072 #define alc269_loopbacks alc880_loopbacks
12075 /* pcm configuration: identiacal with ALC880 */
12076 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12077 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12078 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12079 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12082 * BIOS auto configuration
12084 static int alc269_parse_auto_config(struct hda_codec *codec)
12086 struct alc_spec *spec = codec->spec;
12088 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12090 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12095 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12098 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12102 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12104 if (spec->autocfg.dig_out_pin)
12105 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12107 if (spec->kctl_alloc)
12108 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12110 /* create a beep mixer control if the pin 0x1d isn't assigned */
12111 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12112 if (spec->autocfg.input_pins[i] == 0x1d)
12114 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12115 spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12117 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12118 spec->num_mux_defs = 1;
12119 spec->input_mux = &spec->private_imux;
12120 /* set default input source */
12121 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12122 0, AC_VERB_SET_CONNECT_SEL,
12123 spec->input_mux->items[0].index);
12125 err = alc_auto_add_mic_boost(codec);
12129 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12130 spec->num_mixers++;
12135 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12136 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12137 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12140 /* init callback for auto-configuration model -- overriding the default init */
12141 static void alc269_auto_init(struct hda_codec *codec)
12143 struct alc_spec *spec = codec->spec;
12144 alc269_auto_init_multi_out(codec);
12145 alc269_auto_init_hp_out(codec);
12146 alc269_auto_init_analog_input(codec);
12147 if (spec->unsol_event)
12148 alc_sku_automute(codec);
12152 * configuration and preset
12154 static const char *alc269_models[ALC269_MODEL_LAST] = {
12155 [ALC269_BASIC] = "basic",
12156 [ALC269_QUANTA_FL1] = "quanta",
12157 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12158 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901"
12161 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12162 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12163 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12164 ALC269_ASUS_EEEPC_P703),
12165 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12166 ALC269_ASUS_EEEPC_P901),
12167 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12168 ALC269_ASUS_EEEPC_P901),
12172 static struct alc_config_preset alc269_presets[] = {
12174 .mixers = { alc269_base_mixer, alc269_capture_mixer },
12175 .init_verbs = { alc269_init_verbs },
12176 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12177 .dac_nids = alc269_dac_nids,
12179 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12180 .channel_mode = alc269_modes,
12181 .input_mux = &alc269_capture_source,
12183 [ALC269_QUANTA_FL1] = {
12184 .mixers = { alc269_quanta_fl1_mixer },
12185 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12186 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12187 .dac_nids = alc269_dac_nids,
12189 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12190 .channel_mode = alc269_modes,
12191 .input_mux = &alc269_capture_source,
12192 .unsol_event = alc269_quanta_fl1_unsol_event,
12193 .init_hook = alc269_quanta_fl1_init_hook,
12195 [ALC269_ASUS_EEEPC_P703] = {
12196 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12197 .init_verbs = { alc269_init_verbs,
12198 alc269_eeepc_amic_init_verbs },
12199 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12200 .dac_nids = alc269_dac_nids,
12202 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12203 .channel_mode = alc269_modes,
12204 .input_mux = &alc269_eeepc_amic_capture_source,
12205 .unsol_event = alc269_eeepc_amic_unsol_event,
12206 .init_hook = alc269_eeepc_amic_inithook,
12208 [ALC269_ASUS_EEEPC_P901] = {
12209 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12210 .init_verbs = { alc269_init_verbs,
12211 alc269_eeepc_dmic_init_verbs },
12212 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12213 .dac_nids = alc269_dac_nids,
12215 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12216 .channel_mode = alc269_modes,
12217 .input_mux = &alc269_eeepc_dmic_capture_source,
12218 .unsol_event = alc269_eeepc_dmic_unsol_event,
12219 .init_hook = alc269_eeepc_dmic_inithook,
12223 static int patch_alc269(struct hda_codec *codec)
12225 struct alc_spec *spec;
12229 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12233 codec->spec = spec;
12235 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12237 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12241 if (board_config < 0) {
12242 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12243 "trying auto-probe from BIOS...\n");
12244 board_config = ALC269_AUTO;
12247 if (board_config == ALC269_AUTO) {
12248 /* automatic parse from the BIOS config */
12249 err = alc269_parse_auto_config(codec);
12255 "hda_codec: Cannot set up configuration "
12256 "from BIOS. Using base mode...\n");
12257 board_config = ALC269_BASIC;
12261 if (board_config != ALC269_AUTO)
12262 setup_preset(spec, &alc269_presets[board_config]);
12264 spec->stream_name_analog = "ALC269 Analog";
12265 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12266 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12268 spec->stream_name_digital = "ALC269 Digital";
12269 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12270 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12272 spec->adc_nids = alc269_adc_nids;
12273 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12274 spec->capsrc_nids = alc269_capsrc_nids;
12276 codec->patch_ops = alc_patch_ops;
12277 if (board_config == ALC269_AUTO)
12278 spec->init_hook = alc269_auto_init;
12279 #ifdef CONFIG_SND_HDA_POWER_SAVE
12280 if (!spec->loopback.amplist)
12281 spec->loopback.amplist = alc269_loopbacks;
12288 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12292 * set the path ways for 2 channel output
12293 * need to set the codec line out and mic 1 pin widgets to inputs
12295 static struct hda_verb alc861_threestack_ch2_init[] = {
12296 /* set pin widget 1Ah (line in) for input */
12297 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12298 /* set pin widget 18h (mic1/2) for input, for mic also enable
12301 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12303 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12305 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12306 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12312 * need to set the codec line out and mic 1 pin widgets to outputs
12314 static struct hda_verb alc861_threestack_ch6_init[] = {
12315 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12316 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12317 /* set pin widget 18h (mic1) for output (CLFE)*/
12318 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12320 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12321 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12323 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12325 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12326 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12331 static struct hda_channel_mode alc861_threestack_modes[2] = {
12332 { 2, alc861_threestack_ch2_init },
12333 { 6, alc861_threestack_ch6_init },
12335 /* Set mic1 as input and unmute the mixer */
12336 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12337 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12338 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12341 /* Set mic1 as output and mute mixer */
12342 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12343 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12344 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12348 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12349 { 2, alc861_uniwill_m31_ch2_init },
12350 { 4, alc861_uniwill_m31_ch4_init },
12353 /* Set mic1 and line-in as input and unmute the mixer */
12354 static struct hda_verb alc861_asus_ch2_init[] = {
12355 /* set pin widget 1Ah (line in) for input */
12356 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12357 /* set pin widget 18h (mic1/2) for input, for mic also enable
12360 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12362 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12364 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12365 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12369 /* Set mic1 nad line-in as output and mute mixer */
12370 static struct hda_verb alc861_asus_ch6_init[] = {
12371 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12372 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12373 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12374 /* set pin widget 18h (mic1) for output (CLFE)*/
12375 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12376 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12377 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12378 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12380 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12382 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12383 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12388 static struct hda_channel_mode alc861_asus_modes[2] = {
12389 { 2, alc861_asus_ch2_init },
12390 { 6, alc861_asus_ch6_init },
12395 static struct snd_kcontrol_new alc861_base_mixer[] = {
12396 /* output mixer control */
12397 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12398 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12399 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12400 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12401 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12403 /*Input mixer control */
12404 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12405 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12406 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12407 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12408 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12409 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12411 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12412 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12415 /* Capture mixer control */
12416 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12417 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12420 .name = "Capture Source",
12422 .info = alc_mux_enum_info,
12423 .get = alc_mux_enum_get,
12424 .put = alc_mux_enum_put,
12429 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12430 /* output mixer control */
12431 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12432 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12433 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12434 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12435 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12437 /* Input mixer control */
12438 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12439 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12440 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12441 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12442 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12443 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12444 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12445 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12446 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12447 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12449 /* Capture mixer control */
12450 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12451 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12453 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12454 .name = "Capture Source",
12456 .info = alc_mux_enum_info,
12457 .get = alc_mux_enum_get,
12458 .put = alc_mux_enum_put,
12461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12462 .name = "Channel Mode",
12463 .info = alc_ch_mode_info,
12464 .get = alc_ch_mode_get,
12465 .put = alc_ch_mode_put,
12466 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12471 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12472 /* output mixer control */
12473 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12474 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12475 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12477 /*Capture mixer control */
12478 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12479 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12482 .name = "Capture Source",
12484 .info = alc_mux_enum_info,
12485 .get = alc_mux_enum_get,
12486 .put = alc_mux_enum_put,
12492 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12493 /* output mixer control */
12494 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12495 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12496 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12497 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12498 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12500 /* Input mixer control */
12501 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12502 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12503 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12504 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12505 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12506 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12508 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12509 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12510 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12512 /* Capture mixer control */
12513 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12514 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12517 .name = "Capture Source",
12519 .info = alc_mux_enum_info,
12520 .get = alc_mux_enum_get,
12521 .put = alc_mux_enum_put,
12524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12525 .name = "Channel Mode",
12526 .info = alc_ch_mode_info,
12527 .get = alc_ch_mode_get,
12528 .put = alc_ch_mode_put,
12529 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12534 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12535 /* output mixer control */
12536 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12537 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12538 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12539 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12540 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12542 /* Input mixer control */
12543 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12544 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12545 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12546 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12547 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12548 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12549 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12550 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12552 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12554 /* Capture mixer control */
12555 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12556 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12558 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12559 .name = "Capture Source",
12561 .info = alc_mux_enum_info,
12562 .get = alc_mux_enum_get,
12563 .put = alc_mux_enum_put,
12566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12567 .name = "Channel Mode",
12568 .info = alc_ch_mode_info,
12569 .get = alc_ch_mode_get,
12570 .put = alc_ch_mode_put,
12571 .private_value = ARRAY_SIZE(alc861_asus_modes),
12576 /* additional mixer */
12577 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12578 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12579 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12580 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12581 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12586 * generic initialization of ADC, input mixers and output mixers
12588 static struct hda_verb alc861_base_init_verbs[] = {
12590 * Unmute ADC0 and set the default input to mic-in
12592 /* port-A for surround (rear panel) */
12593 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12594 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12595 /* port-B for mic-in (rear panel) with vref */
12596 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12597 /* port-C for line-in (rear panel) */
12598 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12599 /* port-D for Front */
12600 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12601 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12602 /* port-E for HP out (front panel) */
12603 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12604 /* route front PCM to HP */
12605 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12606 /* port-F for mic-in (front panel) with vref */
12607 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12608 /* port-G for CLFE (rear panel) */
12609 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12610 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12611 /* port-H for side (rear panel) */
12612 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12613 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12615 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12616 /* route front mic to ADC1*/
12617 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12620 /* Unmute DAC0~3 & spdif out*/
12621 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12622 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12623 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12624 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12627 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12628 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12629 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12630 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12631 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12633 /* Unmute Stereo Mixer 15 */
12634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12635 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12636 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12639 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12640 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12641 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12642 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12644 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12645 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12646 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12647 /* hp used DAC 3 (Front) */
12648 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12649 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12654 static struct hda_verb alc861_threestack_init_verbs[] = {
12656 * Unmute ADC0 and set the default input to mic-in
12658 /* port-A for surround (rear panel) */
12659 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12660 /* port-B for mic-in (rear panel) with vref */
12661 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12662 /* port-C for line-in (rear panel) */
12663 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12664 /* port-D for Front */
12665 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12666 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12667 /* port-E for HP out (front panel) */
12668 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12669 /* route front PCM to HP */
12670 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12671 /* port-F for mic-in (front panel) with vref */
12672 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12673 /* port-G for CLFE (rear panel) */
12674 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12675 /* port-H for side (rear panel) */
12676 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12678 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12679 /* route front mic to ADC1*/
12680 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12681 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12682 /* Unmute DAC0~3 & spdif out*/
12683 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12684 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12685 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12686 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12687 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12689 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12690 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12691 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12692 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12693 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12695 /* Unmute Stereo Mixer 15 */
12696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12697 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12698 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12699 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12701 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12702 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12703 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12704 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12705 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12706 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12707 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12708 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12709 /* hp used DAC 3 (Front) */
12710 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12711 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12715 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12717 * Unmute ADC0 and set the default input to mic-in
12719 /* port-A for surround (rear panel) */
12720 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12721 /* port-B for mic-in (rear panel) with vref */
12722 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12723 /* port-C for line-in (rear panel) */
12724 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12725 /* port-D for Front */
12726 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12727 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12728 /* port-E for HP out (front panel) */
12729 /* this has to be set to VREF80 */
12730 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12731 /* route front PCM to HP */
12732 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12733 /* port-F for mic-in (front panel) with vref */
12734 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12735 /* port-G for CLFE (rear panel) */
12736 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12737 /* port-H for side (rear panel) */
12738 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12740 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12741 /* route front mic to ADC1*/
12742 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12743 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12744 /* Unmute DAC0~3 & spdif out*/
12745 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12746 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12747 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12748 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12751 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12752 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12753 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12754 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12755 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12757 /* Unmute Stereo Mixer 15 */
12758 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12759 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12760 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12763 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12764 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12765 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12766 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12767 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12768 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12769 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12770 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12771 /* hp used DAC 3 (Front) */
12772 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12773 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12777 static struct hda_verb alc861_asus_init_verbs[] = {
12779 * Unmute ADC0 and set the default input to mic-in
12781 /* port-A for surround (rear panel)
12782 * according to codec#0 this is the HP jack
12784 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12785 /* route front PCM to HP */
12786 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12787 /* port-B for mic-in (rear panel) with vref */
12788 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12789 /* port-C for line-in (rear panel) */
12790 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12791 /* port-D for Front */
12792 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12793 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12794 /* port-E for HP out (front panel) */
12795 /* this has to be set to VREF80 */
12796 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12797 /* route front PCM to HP */
12798 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12799 /* port-F for mic-in (front panel) with vref */
12800 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12801 /* port-G for CLFE (rear panel) */
12802 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12803 /* port-H for side (rear panel) */
12804 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12806 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12807 /* route front mic to ADC1*/
12808 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12809 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12810 /* Unmute DAC0~3 & spdif out*/
12811 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12813 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12814 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12816 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12817 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12818 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12819 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12820 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12822 /* Unmute Stereo Mixer 15 */
12823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12828 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12830 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12831 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12832 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12834 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12836 /* hp used DAC 3 (Front) */
12837 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12842 /* additional init verbs for ASUS laptops */
12843 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12844 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12845 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12850 * generic initialization of ADC, input mixers and output mixers
12852 static struct hda_verb alc861_auto_init_verbs[] = {
12854 * Unmute ADC0 and set the default input to mic-in
12856 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12857 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12859 /* Unmute DAC0~3 & spdif out*/
12860 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12861 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12862 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12863 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12866 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12867 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12868 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12869 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12870 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12872 /* Unmute Stereo Mixer 15 */
12873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12874 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12875 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12876 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12878 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12879 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12880 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12881 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12882 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12883 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12884 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12885 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12887 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12888 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12889 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12890 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12891 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12892 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12893 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12894 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12896 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
12901 static struct hda_verb alc861_toshiba_init_verbs[] = {
12902 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12907 /* toggle speaker-output according to the hp-jack state */
12908 static void alc861_toshiba_automute(struct hda_codec *codec)
12910 unsigned int present;
12912 present = snd_hda_codec_read(codec, 0x0f, 0,
12913 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12914 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12915 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12916 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12917 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12920 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12923 if ((res >> 26) == ALC880_HP_EVENT)
12924 alc861_toshiba_automute(codec);
12927 /* pcm configuration: identiacal with ALC880 */
12928 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
12929 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
12930 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
12931 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
12934 #define ALC861_DIGOUT_NID 0x07
12936 static struct hda_channel_mode alc861_8ch_modes[1] = {
12940 static hda_nid_t alc861_dac_nids[4] = {
12941 /* front, surround, clfe, side */
12942 0x03, 0x06, 0x05, 0x04
12945 static hda_nid_t alc660_dac_nids[3] = {
12946 /* front, clfe, surround */
12950 static hda_nid_t alc861_adc_nids[1] = {
12955 static struct hda_input_mux alc861_capture_source = {
12959 { "Front Mic", 0x3 },
12966 /* fill in the dac_nids table from the parsed pin configuration */
12967 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12968 const struct auto_pin_cfg *cfg)
12973 spec->multiout.dac_nids = spec->private_dac_nids;
12974 for (i = 0; i < cfg->line_outs; i++) {
12975 nid = cfg->line_out_pins[i];
12977 if (i >= ARRAY_SIZE(alc861_dac_nids))
12979 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12982 spec->multiout.num_dacs = cfg->line_outs;
12986 /* add playback controls from the parsed DAC table */
12987 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12988 const struct auto_pin_cfg *cfg)
12991 static const char *chname[4] = {
12992 "Front", "Surround", NULL /*CLFE*/, "Side"
12997 for (i = 0; i < cfg->line_outs; i++) {
12998 nid = spec->multiout.dac_nids[i];
13003 err = add_control(spec, ALC_CTL_BIND_MUTE,
13004 "Center Playback Switch",
13005 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13009 err = add_control(spec, ALC_CTL_BIND_MUTE,
13010 "LFE Playback Switch",
13011 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13016 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13018 if (nid == alc861_dac_nids[idx])
13020 sprintf(name, "%s Playback Switch", chname[idx]);
13021 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13022 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13031 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13039 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13041 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13042 "Headphone Playback Switch",
13043 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13046 spec->multiout.hp_nid = nid;
13051 /* create playback/capture controls for input pins */
13052 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13053 const struct auto_pin_cfg *cfg)
13055 struct hda_input_mux *imux = &spec->private_imux;
13056 int i, err, idx, idx1;
13058 for (i = 0; i < AUTO_PIN_LAST; i++) {
13059 switch (cfg->input_pins[i]) {
13062 idx = 2; /* Line In */
13066 idx = 2; /* Line In */
13070 idx = 1; /* Mic In */
13074 idx = 1; /* Mic In */
13084 err = new_analog_input(spec, cfg->input_pins[i],
13085 auto_pin_cfg_labels[i], idx, 0x15);
13089 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13090 imux->items[imux->num_items].index = idx1;
13096 static struct snd_kcontrol_new alc861_capture_mixer[] = {
13097 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13098 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13101 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13102 /* The multiple "Capture Source" controls confuse alsamixer
13103 * So call somewhat different..
13105 /* .name = "Capture Source", */
13106 .name = "Input Source",
13108 .info = alc_mux_enum_info,
13109 .get = alc_mux_enum_get,
13110 .put = alc_mux_enum_put,
13115 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13117 int pin_type, int dac_idx)
13119 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13121 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13125 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13127 struct alc_spec *spec = codec->spec;
13130 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13131 for (i = 0; i < spec->autocfg.line_outs; i++) {
13132 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13133 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13135 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13136 spec->multiout.dac_nids[i]);
13140 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13142 struct alc_spec *spec = codec->spec;
13145 pin = spec->autocfg.hp_pins[0];
13146 if (pin) /* connect to front */
13147 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13148 spec->multiout.dac_nids[0]);
13149 pin = spec->autocfg.speaker_pins[0];
13151 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13154 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13156 struct alc_spec *spec = codec->spec;
13159 for (i = 0; i < AUTO_PIN_LAST; i++) {
13160 hda_nid_t nid = spec->autocfg.input_pins[i];
13161 if (nid >= 0x0c && nid <= 0x11) {
13162 snd_hda_codec_write(codec, nid, 0,
13163 AC_VERB_SET_PIN_WIDGET_CONTROL,
13164 i <= AUTO_PIN_FRONT_MIC ?
13165 PIN_VREF80 : PIN_IN);
13170 /* parse the BIOS configuration and set up the alc_spec */
13171 /* return 1 if successful, 0 if the proper config is not found,
13172 * or a negative error code
13174 static int alc861_parse_auto_config(struct hda_codec *codec)
13176 struct alc_spec *spec = codec->spec;
13178 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13180 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13184 if (!spec->autocfg.line_outs)
13185 return 0; /* can't find valid BIOS pin config */
13187 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13190 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13193 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13196 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13200 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13202 if (spec->autocfg.dig_out_pin)
13203 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13205 if (spec->kctl_alloc)
13206 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13208 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13210 spec->num_mux_defs = 1;
13211 spec->input_mux = &spec->private_imux;
13213 spec->adc_nids = alc861_adc_nids;
13214 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13215 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13216 spec->num_mixers++;
13221 /* additional initialization for auto-configuration model */
13222 static void alc861_auto_init(struct hda_codec *codec)
13224 struct alc_spec *spec = codec->spec;
13225 alc861_auto_init_multi_out(codec);
13226 alc861_auto_init_hp_out(codec);
13227 alc861_auto_init_analog_input(codec);
13228 if (spec->unsol_event)
13229 alc_sku_automute(codec);
13232 #ifdef CONFIG_SND_HDA_POWER_SAVE
13233 static struct hda_amp_list alc861_loopbacks[] = {
13234 { 0x15, HDA_INPUT, 0 },
13235 { 0x15, HDA_INPUT, 1 },
13236 { 0x15, HDA_INPUT, 2 },
13237 { 0x15, HDA_INPUT, 3 },
13244 * configuration and preset
13246 static const char *alc861_models[ALC861_MODEL_LAST] = {
13247 [ALC861_3ST] = "3stack",
13248 [ALC660_3ST] = "3stack-660",
13249 [ALC861_3ST_DIG] = "3stack-dig",
13250 [ALC861_6ST_DIG] = "6stack-dig",
13251 [ALC861_UNIWILL_M31] = "uniwill-m31",
13252 [ALC861_TOSHIBA] = "toshiba",
13253 [ALC861_ASUS] = "asus",
13254 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13255 [ALC861_AUTO] = "auto",
13258 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13259 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13260 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13261 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13262 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13263 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13264 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13265 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13266 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13267 * Any other models that need this preset?
13269 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13270 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13271 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13272 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13273 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13274 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13275 /* FIXME: the below seems conflict */
13276 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13277 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13278 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13282 static struct alc_config_preset alc861_presets[] = {
13284 .mixers = { alc861_3ST_mixer },
13285 .init_verbs = { alc861_threestack_init_verbs },
13286 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13287 .dac_nids = alc861_dac_nids,
13288 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13289 .channel_mode = alc861_threestack_modes,
13291 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13292 .adc_nids = alc861_adc_nids,
13293 .input_mux = &alc861_capture_source,
13295 [ALC861_3ST_DIG] = {
13296 .mixers = { alc861_base_mixer },
13297 .init_verbs = { alc861_threestack_init_verbs },
13298 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13299 .dac_nids = alc861_dac_nids,
13300 .dig_out_nid = ALC861_DIGOUT_NID,
13301 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13302 .channel_mode = alc861_threestack_modes,
13304 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13305 .adc_nids = alc861_adc_nids,
13306 .input_mux = &alc861_capture_source,
13308 [ALC861_6ST_DIG] = {
13309 .mixers = { alc861_base_mixer },
13310 .init_verbs = { alc861_base_init_verbs },
13311 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13312 .dac_nids = alc861_dac_nids,
13313 .dig_out_nid = ALC861_DIGOUT_NID,
13314 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13315 .channel_mode = alc861_8ch_modes,
13316 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13317 .adc_nids = alc861_adc_nids,
13318 .input_mux = &alc861_capture_source,
13321 .mixers = { alc861_3ST_mixer },
13322 .init_verbs = { alc861_threestack_init_verbs },
13323 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13324 .dac_nids = alc660_dac_nids,
13325 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13326 .channel_mode = alc861_threestack_modes,
13328 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13329 .adc_nids = alc861_adc_nids,
13330 .input_mux = &alc861_capture_source,
13332 [ALC861_UNIWILL_M31] = {
13333 .mixers = { alc861_uniwill_m31_mixer },
13334 .init_verbs = { alc861_uniwill_m31_init_verbs },
13335 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13336 .dac_nids = alc861_dac_nids,
13337 .dig_out_nid = ALC861_DIGOUT_NID,
13338 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13339 .channel_mode = alc861_uniwill_m31_modes,
13341 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13342 .adc_nids = alc861_adc_nids,
13343 .input_mux = &alc861_capture_source,
13345 [ALC861_TOSHIBA] = {
13346 .mixers = { alc861_toshiba_mixer },
13347 .init_verbs = { alc861_base_init_verbs,
13348 alc861_toshiba_init_verbs },
13349 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13350 .dac_nids = alc861_dac_nids,
13351 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13352 .channel_mode = alc883_3ST_2ch_modes,
13353 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13354 .adc_nids = alc861_adc_nids,
13355 .input_mux = &alc861_capture_source,
13356 .unsol_event = alc861_toshiba_unsol_event,
13357 .init_hook = alc861_toshiba_automute,
13360 .mixers = { alc861_asus_mixer },
13361 .init_verbs = { alc861_asus_init_verbs },
13362 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13363 .dac_nids = alc861_dac_nids,
13364 .dig_out_nid = ALC861_DIGOUT_NID,
13365 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13366 .channel_mode = alc861_asus_modes,
13369 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13370 .adc_nids = alc861_adc_nids,
13371 .input_mux = &alc861_capture_source,
13373 [ALC861_ASUS_LAPTOP] = {
13374 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13375 .init_verbs = { alc861_asus_init_verbs,
13376 alc861_asus_laptop_init_verbs },
13377 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13378 .dac_nids = alc861_dac_nids,
13379 .dig_out_nid = ALC861_DIGOUT_NID,
13380 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13381 .channel_mode = alc883_3ST_2ch_modes,
13383 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13384 .adc_nids = alc861_adc_nids,
13385 .input_mux = &alc861_capture_source,
13390 static int patch_alc861(struct hda_codec *codec)
13392 struct alc_spec *spec;
13396 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13400 codec->spec = spec;
13402 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13406 if (board_config < 0) {
13407 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13408 "trying auto-probe from BIOS...\n");
13409 board_config = ALC861_AUTO;
13412 if (board_config == ALC861_AUTO) {
13413 /* automatic parse from the BIOS config */
13414 err = alc861_parse_auto_config(codec);
13420 "hda_codec: Cannot set up configuration "
13421 "from BIOS. Using base mode...\n");
13422 board_config = ALC861_3ST_DIG;
13426 if (board_config != ALC861_AUTO)
13427 setup_preset(spec, &alc861_presets[board_config]);
13429 spec->stream_name_analog = "ALC861 Analog";
13430 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13431 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13433 spec->stream_name_digital = "ALC861 Digital";
13434 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13435 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13437 spec->vmaster_nid = 0x03;
13439 codec->patch_ops = alc_patch_ops;
13440 if (board_config == ALC861_AUTO)
13441 spec->init_hook = alc861_auto_init;
13442 #ifdef CONFIG_SND_HDA_POWER_SAVE
13443 if (!spec->loopback.amplist)
13444 spec->loopback.amplist = alc861_loopbacks;
13451 * ALC861-VD support
13455 * In addition, an independent DAC
13457 #define ALC861VD_DIGOUT_NID 0x06
13459 static hda_nid_t alc861vd_dac_nids[4] = {
13460 /* front, surr, clfe, side surr */
13461 0x02, 0x03, 0x04, 0x05
13464 /* dac_nids for ALC660vd are in a different order - according to
13465 * Realtek's driver.
13466 * This should probably tesult in a different mixer for 6stack models
13467 * of ALC660vd codecs, but for now there is only 3stack mixer
13468 * - and it is the same as in 861vd.
13469 * adc_nids in ALC660vd are (is) the same as in 861vd
13471 static hda_nid_t alc660vd_dac_nids[3] = {
13472 /* front, rear, clfe, rear_surr */
13476 static hda_nid_t alc861vd_adc_nids[1] = {
13481 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13484 /* FIXME: should be a matrix-type input source selection */
13485 static struct hda_input_mux alc861vd_capture_source = {
13489 { "Front Mic", 0x1 },
13495 static struct hda_input_mux alc861vd_dallas_capture_source = {
13498 { "Ext Mic", 0x0 },
13499 { "Int Mic", 0x1 },
13503 static struct hda_input_mux alc861vd_hp_capture_source = {
13506 { "Front Mic", 0x0 },
13507 { "ATAPI Mic", 0x1 },
13511 #define alc861vd_mux_enum_info alc_mux_enum_info
13512 #define alc861vd_mux_enum_get alc_mux_enum_get
13513 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13514 #define alc861vd_mux_enum_put alc882_mux_enum_put
13519 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13526 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13527 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13528 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13529 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13530 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13537 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13538 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13540 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13541 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13545 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13546 { 6, alc861vd_6stack_ch6_init },
13547 { 8, alc861vd_6stack_ch8_init },
13550 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13553 .name = "Channel Mode",
13554 .info = alc_ch_mode_info,
13555 .get = alc_ch_mode_get,
13556 .put = alc_ch_mode_put,
13561 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13562 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13563 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13567 /* The multiple "Capture Source" controls confuse alsamixer
13568 * So call somewhat different..
13570 /* .name = "Capture Source", */
13571 .name = "Input Source",
13573 .info = alc861vd_mux_enum_info,
13574 .get = alc861vd_mux_enum_get,
13575 .put = alc861vd_mux_enum_put,
13580 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13581 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13583 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13584 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13585 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13587 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13588 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13590 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13592 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13594 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13595 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13597 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13598 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13600 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13602 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13604 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13606 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13607 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13608 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13610 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13611 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13613 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13614 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13616 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13617 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13622 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13623 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13624 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13626 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13628 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13632 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13633 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13634 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13636 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13637 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13639 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13640 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13642 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13643 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13648 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13649 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13650 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13651 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13655 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13659 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13660 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13661 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13669 /* Pin assignment: Speaker=0x14, HP = 0x15,
13670 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13672 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13673 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13674 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13675 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13676 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13677 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13678 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13679 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13680 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13681 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13682 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13683 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13684 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13688 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13689 * Front Mic=0x18, ATAPI Mic = 0x19,
13691 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13692 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13693 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13694 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13695 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13696 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13698 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13699 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13705 * generic initialization of ADC, input mixers and output mixers
13707 static struct hda_verb alc861vd_volume_init_verbs[] = {
13709 * Unmute ADC0 and set the default input to mic-in
13711 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13712 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13714 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13715 * the analog-loopback mixer widget
13717 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13724 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13731 * Set up output mixers (0x02 - 0x05)
13733 /* set vol=0 to output mixers */
13734 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13735 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13736 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13737 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13739 /* set up input amps for analog loopback */
13740 /* Amp Indices: DAC = 0, mixer = 1 */
13741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13742 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13743 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13744 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13745 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13747 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13748 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13754 * 3-stack pin configuration:
13755 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13757 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13759 * Set pin mode and muting
13761 /* set front pin widgets 0x14 for output */
13762 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13764 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13766 /* Mic (rear) pin: input vref at 80% */
13767 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13768 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13769 /* Front Mic pin: input vref at 80% */
13770 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13771 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13772 /* Line In pin: input */
13773 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13774 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13775 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13776 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13777 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13778 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13779 /* CD pin widget for input */
13780 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13786 * 6-stack pin configuration:
13788 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13790 * Set pin mode and muting
13792 /* set front pin widgets 0x14 for output */
13793 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13795 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13797 /* Rear Pin: output 1 (0x0d) */
13798 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13800 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13801 /* CLFE Pin: output 2 (0x0e) */
13802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13804 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13805 /* Side Pin: output 3 (0x0f) */
13806 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13807 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13808 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13810 /* Mic (rear) pin: input vref at 80% */
13811 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13812 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13813 /* Front Mic pin: input vref at 80% */
13814 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13815 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13816 /* Line In pin: input */
13817 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13819 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13820 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13821 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13822 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13823 /* CD pin widget for input */
13824 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13829 static struct hda_verb alc861vd_eapd_verbs[] = {
13830 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13834 static struct hda_verb alc660vd_eapd_verbs[] = {
13835 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13836 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13840 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13843 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13844 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13845 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13849 /* toggle speaker-output according to the hp-jack state */
13850 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13852 unsigned int present;
13853 unsigned char bits;
13855 present = snd_hda_codec_read(codec, 0x1b, 0,
13856 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13857 bits = present ? HDA_AMP_MUTE : 0;
13858 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13859 HDA_AMP_MUTE, bits);
13862 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13864 unsigned int present;
13865 unsigned char bits;
13867 present = snd_hda_codec_read(codec, 0x18, 0,
13868 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13869 bits = present ? HDA_AMP_MUTE : 0;
13870 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13871 HDA_AMP_MUTE, bits);
13874 static void alc861vd_lenovo_automute(struct hda_codec *codec)
13876 alc861vd_lenovo_hp_automute(codec);
13877 alc861vd_lenovo_mic_automute(codec);
13880 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13883 switch (res >> 26) {
13884 case ALC880_HP_EVENT:
13885 alc861vd_lenovo_hp_automute(codec);
13887 case ALC880_MIC_EVENT:
13888 alc861vd_lenovo_mic_automute(codec);
13893 static struct hda_verb alc861vd_dallas_verbs[] = {
13894 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13895 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13896 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13897 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13899 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13900 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13901 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13902 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13903 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13905 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13906 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13908 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13910 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13912 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13913 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13915 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13917 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13918 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13919 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13920 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13921 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13922 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13923 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13924 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13931 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13932 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13933 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13938 /* toggle speaker-output according to the hp-jack state */
13939 static void alc861vd_dallas_automute(struct hda_codec *codec)
13941 unsigned int present;
13943 present = snd_hda_codec_read(codec, 0x15, 0,
13944 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13945 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13946 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13949 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13951 if ((res >> 26) == ALC880_HP_EVENT)
13952 alc861vd_dallas_automute(codec);
13955 #ifdef CONFIG_SND_HDA_POWER_SAVE
13956 #define alc861vd_loopbacks alc880_loopbacks
13959 /* pcm configuration: identiacal with ALC880 */
13960 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
13961 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
13962 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
13963 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
13966 * configuration and preset
13968 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13969 [ALC660VD_3ST] = "3stack-660",
13970 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13971 [ALC861VD_3ST] = "3stack",
13972 [ALC861VD_3ST_DIG] = "3stack-digout",
13973 [ALC861VD_6ST_DIG] = "6stack-digout",
13974 [ALC861VD_LENOVO] = "lenovo",
13975 [ALC861VD_DALLAS] = "dallas",
13976 [ALC861VD_HP] = "hp",
13977 [ALC861VD_AUTO] = "auto",
13980 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13981 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13982 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13983 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13984 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13985 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
13986 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13987 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13988 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13989 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13990 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13991 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13992 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13993 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13994 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13995 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13996 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13997 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14001 static struct alc_config_preset alc861vd_presets[] = {
14003 .mixers = { alc861vd_3st_mixer },
14004 .init_verbs = { alc861vd_volume_init_verbs,
14005 alc861vd_3stack_init_verbs },
14006 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14007 .dac_nids = alc660vd_dac_nids,
14008 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14009 .channel_mode = alc861vd_3stack_2ch_modes,
14010 .input_mux = &alc861vd_capture_source,
14012 [ALC660VD_3ST_DIG] = {
14013 .mixers = { alc861vd_3st_mixer },
14014 .init_verbs = { alc861vd_volume_init_verbs,
14015 alc861vd_3stack_init_verbs },
14016 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14017 .dac_nids = alc660vd_dac_nids,
14018 .dig_out_nid = ALC861VD_DIGOUT_NID,
14019 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14020 .channel_mode = alc861vd_3stack_2ch_modes,
14021 .input_mux = &alc861vd_capture_source,
14024 .mixers = { alc861vd_3st_mixer },
14025 .init_verbs = { alc861vd_volume_init_verbs,
14026 alc861vd_3stack_init_verbs },
14027 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14028 .dac_nids = alc861vd_dac_nids,
14029 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14030 .channel_mode = alc861vd_3stack_2ch_modes,
14031 .input_mux = &alc861vd_capture_source,
14033 [ALC861VD_3ST_DIG] = {
14034 .mixers = { alc861vd_3st_mixer },
14035 .init_verbs = { alc861vd_volume_init_verbs,
14036 alc861vd_3stack_init_verbs },
14037 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14038 .dac_nids = alc861vd_dac_nids,
14039 .dig_out_nid = ALC861VD_DIGOUT_NID,
14040 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14041 .channel_mode = alc861vd_3stack_2ch_modes,
14042 .input_mux = &alc861vd_capture_source,
14044 [ALC861VD_6ST_DIG] = {
14045 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14046 .init_verbs = { alc861vd_volume_init_verbs,
14047 alc861vd_6stack_init_verbs },
14048 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14049 .dac_nids = alc861vd_dac_nids,
14050 .dig_out_nid = ALC861VD_DIGOUT_NID,
14051 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14052 .channel_mode = alc861vd_6stack_modes,
14053 .input_mux = &alc861vd_capture_source,
14055 [ALC861VD_LENOVO] = {
14056 .mixers = { alc861vd_lenovo_mixer },
14057 .init_verbs = { alc861vd_volume_init_verbs,
14058 alc861vd_3stack_init_verbs,
14059 alc861vd_eapd_verbs,
14060 alc861vd_lenovo_unsol_verbs },
14061 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14062 .dac_nids = alc660vd_dac_nids,
14063 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14064 .channel_mode = alc861vd_3stack_2ch_modes,
14065 .input_mux = &alc861vd_capture_source,
14066 .unsol_event = alc861vd_lenovo_unsol_event,
14067 .init_hook = alc861vd_lenovo_automute,
14069 [ALC861VD_DALLAS] = {
14070 .mixers = { alc861vd_dallas_mixer },
14071 .init_verbs = { alc861vd_dallas_verbs },
14072 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14073 .dac_nids = alc861vd_dac_nids,
14074 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14075 .channel_mode = alc861vd_3stack_2ch_modes,
14076 .input_mux = &alc861vd_dallas_capture_source,
14077 .unsol_event = alc861vd_dallas_unsol_event,
14078 .init_hook = alc861vd_dallas_automute,
14081 .mixers = { alc861vd_hp_mixer },
14082 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14083 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14084 .dac_nids = alc861vd_dac_nids,
14085 .dig_out_nid = ALC861VD_DIGOUT_NID,
14086 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14087 .channel_mode = alc861vd_3stack_2ch_modes,
14088 .input_mux = &alc861vd_hp_capture_source,
14089 .unsol_event = alc861vd_dallas_unsol_event,
14090 .init_hook = alc861vd_dallas_automute,
14095 * BIOS auto configuration
14097 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14098 hda_nid_t nid, int pin_type, int dac_idx)
14100 alc_set_pin_output(codec, nid, pin_type);
14103 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14105 struct alc_spec *spec = codec->spec;
14108 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14109 for (i = 0; i <= HDA_SIDE; i++) {
14110 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14111 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14113 alc861vd_auto_set_output_and_unmute(codec, nid,
14119 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14121 struct alc_spec *spec = codec->spec;
14124 pin = spec->autocfg.hp_pins[0];
14125 if (pin) /* connect to front and use dac 0 */
14126 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14127 pin = spec->autocfg.speaker_pins[0];
14129 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14132 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14133 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14135 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14137 struct alc_spec *spec = codec->spec;
14140 for (i = 0; i < AUTO_PIN_LAST; i++) {
14141 hda_nid_t nid = spec->autocfg.input_pins[i];
14142 if (alc861vd_is_input_pin(nid)) {
14143 snd_hda_codec_write(codec, nid, 0,
14144 AC_VERB_SET_PIN_WIDGET_CONTROL,
14145 i <= AUTO_PIN_FRONT_MIC ?
14146 PIN_VREF80 : PIN_IN);
14147 if (nid != ALC861VD_PIN_CD_NID)
14148 snd_hda_codec_write(codec, nid, 0,
14149 AC_VERB_SET_AMP_GAIN_MUTE,
14155 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14157 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14158 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14160 /* add playback controls from the parsed DAC table */
14161 /* Based on ALC880 version. But ALC861VD has separate,
14162 * different NIDs for mute/unmute switch and volume control */
14163 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14164 const struct auto_pin_cfg *cfg)
14167 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14168 hda_nid_t nid_v, nid_s;
14171 for (i = 0; i < cfg->line_outs; i++) {
14172 if (!spec->multiout.dac_nids[i])
14174 nid_v = alc861vd_idx_to_mixer_vol(
14176 spec->multiout.dac_nids[i]));
14177 nid_s = alc861vd_idx_to_mixer_switch(
14179 spec->multiout.dac_nids[i]));
14183 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14184 "Center Playback Volume",
14185 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14189 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14190 "LFE Playback Volume",
14191 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14195 err = add_control(spec, ALC_CTL_BIND_MUTE,
14196 "Center Playback Switch",
14197 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14201 err = add_control(spec, ALC_CTL_BIND_MUTE,
14202 "LFE Playback Switch",
14203 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14208 sprintf(name, "%s Playback Volume", chname[i]);
14209 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14210 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14214 sprintf(name, "%s Playback Switch", chname[i]);
14215 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14216 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14225 /* add playback controls for speaker and HP outputs */
14226 /* Based on ALC880 version. But ALC861VD has separate,
14227 * different NIDs for mute/unmute switch and volume control */
14228 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14229 hda_nid_t pin, const char *pfx)
14231 hda_nid_t nid_v, nid_s;
14238 if (alc880_is_fixed_pin(pin)) {
14239 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14240 /* specify the DAC as the extra output */
14241 if (!spec->multiout.hp_nid)
14242 spec->multiout.hp_nid = nid_v;
14244 spec->multiout.extra_out_nid[0] = nid_v;
14245 /* control HP volume/switch on the output mixer amp */
14246 nid_v = alc861vd_idx_to_mixer_vol(
14247 alc880_fixed_pin_idx(pin));
14248 nid_s = alc861vd_idx_to_mixer_switch(
14249 alc880_fixed_pin_idx(pin));
14251 sprintf(name, "%s Playback Volume", pfx);
14252 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14253 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14256 sprintf(name, "%s Playback Switch", pfx);
14257 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14258 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14261 } else if (alc880_is_multi_pin(pin)) {
14262 /* set manual connection */
14263 /* we have only a switch on HP-out PIN */
14264 sprintf(name, "%s Playback Switch", pfx);
14265 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14266 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14273 /* parse the BIOS configuration and set up the alc_spec
14274 * return 1 if successful, 0 if the proper config is not found,
14275 * or a negative error code
14276 * Based on ALC880 version - had to change it to override
14277 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14278 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14280 struct alc_spec *spec = codec->spec;
14282 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14284 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14288 if (!spec->autocfg.line_outs)
14289 return 0; /* can't find valid BIOS pin config */
14291 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14294 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14297 err = alc861vd_auto_create_extra_out(spec,
14298 spec->autocfg.speaker_pins[0],
14302 err = alc861vd_auto_create_extra_out(spec,
14303 spec->autocfg.hp_pins[0],
14307 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14311 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14313 if (spec->autocfg.dig_out_pin)
14314 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14316 if (spec->kctl_alloc)
14317 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14319 spec->init_verbs[spec->num_init_verbs++]
14320 = alc861vd_volume_init_verbs;
14322 spec->num_mux_defs = 1;
14323 spec->input_mux = &spec->private_imux;
14325 err = alc_auto_add_mic_boost(codec);
14332 /* additional initialization for auto-configuration model */
14333 static void alc861vd_auto_init(struct hda_codec *codec)
14335 struct alc_spec *spec = codec->spec;
14336 alc861vd_auto_init_multi_out(codec);
14337 alc861vd_auto_init_hp_out(codec);
14338 alc861vd_auto_init_analog_input(codec);
14339 alc861vd_auto_init_input_src(codec);
14340 if (spec->unsol_event)
14341 alc_sku_automute(codec);
14344 static int patch_alc861vd(struct hda_codec *codec)
14346 struct alc_spec *spec;
14347 int err, board_config;
14349 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14353 codec->spec = spec;
14355 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14359 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14360 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14361 "ALC861VD, trying auto-probe from BIOS...\n");
14362 board_config = ALC861VD_AUTO;
14365 if (board_config == ALC861VD_AUTO) {
14366 /* automatic parse from the BIOS config */
14367 err = alc861vd_parse_auto_config(codec);
14373 "hda_codec: Cannot set up configuration "
14374 "from BIOS. Using base mode...\n");
14375 board_config = ALC861VD_3ST;
14379 if (board_config != ALC861VD_AUTO)
14380 setup_preset(spec, &alc861vd_presets[board_config]);
14382 if (codec->vendor_id == 0x10ec0660) {
14383 spec->stream_name_analog = "ALC660-VD Analog";
14384 spec->stream_name_digital = "ALC660-VD Digital";
14385 /* always turn on EAPD */
14386 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
14388 spec->stream_name_analog = "ALC861VD Analog";
14389 spec->stream_name_digital = "ALC861VD Digital";
14392 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14393 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14395 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14396 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14398 spec->adc_nids = alc861vd_adc_nids;
14399 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14400 spec->capsrc_nids = alc861vd_capsrc_nids;
14402 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14403 spec->num_mixers++;
14405 spec->vmaster_nid = 0x02;
14407 codec->patch_ops = alc_patch_ops;
14409 if (board_config == ALC861VD_AUTO)
14410 spec->init_hook = alc861vd_auto_init;
14411 #ifdef CONFIG_SND_HDA_POWER_SAVE
14412 if (!spec->loopback.amplist)
14413 spec->loopback.amplist = alc861vd_loopbacks;
14422 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14423 * configuration. Each pin widget can choose any input DACs and a mixer.
14424 * Each ADC is connected from a mixer of all inputs. This makes possible
14425 * 6-channel independent captures.
14427 * In addition, an independent DAC for the multi-playback (not used in this
14430 #define ALC662_DIGOUT_NID 0x06
14431 #define ALC662_DIGIN_NID 0x0a
14433 static hda_nid_t alc662_dac_nids[4] = {
14434 /* front, rear, clfe, rear_surr */
14438 static hda_nid_t alc662_adc_nids[1] = {
14443 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14446 /* FIXME: should be a matrix-type input source selection */
14447 static struct hda_input_mux alc662_capture_source = {
14451 { "Front Mic", 0x1 },
14457 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14465 static struct hda_input_mux alc662_eeepc_capture_source = {
14473 static struct hda_input_mux alc663_capture_source = {
14477 { "Front Mic", 0x1 },
14482 static struct hda_input_mux alc663_m51va_capture_source = {
14485 { "Ext-Mic", 0x0 },
14490 #define alc662_mux_enum_info alc_mux_enum_info
14491 #define alc662_mux_enum_get alc_mux_enum_get
14492 #define alc662_mux_enum_put alc882_mux_enum_put
14497 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14504 static struct hda_verb alc662_3ST_ch2_init[] = {
14505 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14506 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14507 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14508 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14515 static struct hda_verb alc662_3ST_ch6_init[] = {
14516 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14517 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14518 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14519 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14520 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14521 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14525 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14526 { 2, alc662_3ST_ch2_init },
14527 { 6, alc662_3ST_ch6_init },
14533 static struct hda_verb alc662_sixstack_ch6_init[] = {
14534 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14535 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14536 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14543 static struct hda_verb alc662_sixstack_ch8_init[] = {
14544 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14545 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14546 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14550 static struct hda_channel_mode alc662_5stack_modes[2] = {
14551 { 2, alc662_sixstack_ch6_init },
14552 { 6, alc662_sixstack_ch8_init },
14555 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14556 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14559 static struct snd_kcontrol_new alc662_base_mixer[] = {
14560 /* output mixer control */
14561 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14562 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14563 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14564 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14565 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14566 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14567 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14568 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14569 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14571 /*Input mixer control */
14572 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14573 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14574 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14575 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14576 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14577 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14578 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14579 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14583 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14584 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14585 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14587 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14588 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14589 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14590 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14592 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14593 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14594 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14595 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14596 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14600 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14601 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14602 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14603 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14604 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14605 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14606 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14607 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14608 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14609 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14610 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14611 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14612 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14613 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14615 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14616 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14617 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14618 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14619 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14623 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14624 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14625 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14626 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14627 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14628 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14636 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14637 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14639 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14640 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14642 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14643 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14644 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14646 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14647 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14648 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14652 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14653 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14654 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14655 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14656 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14657 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14658 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14659 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14660 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14661 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14662 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14663 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14664 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14665 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14666 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14670 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14671 .ops = &snd_hda_bind_vol,
14673 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14674 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14679 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14680 .ops = &snd_hda_bind_sw,
14682 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14683 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14688 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14689 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14690 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14696 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14697 .ops = &snd_hda_bind_sw,
14699 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14700 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14701 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14706 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14707 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14708 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14711 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14712 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14717 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14718 .ops = &snd_hda_bind_sw,
14720 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14721 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14722 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14727 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14728 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14729 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14731 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14732 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14733 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14737 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14738 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14739 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14740 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14742 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14743 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14744 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14748 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14749 .ops = &snd_hda_bind_vol,
14751 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14752 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14757 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14758 .ops = &snd_hda_bind_sw,
14760 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14761 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14766 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14767 HDA_BIND_VOL("Master Playback Volume",
14768 &alc663_asus_two_bind_master_vol),
14769 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14770 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14771 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14773 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14777 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14778 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14779 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14780 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14781 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14782 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14787 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14788 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14789 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14790 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14791 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14792 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14795 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14796 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14797 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14801 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14802 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14803 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14807 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14808 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14809 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14810 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14811 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14815 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14818 .name = "Channel Mode",
14819 .info = alc_ch_mode_info,
14820 .get = alc_ch_mode_get,
14821 .put = alc_ch_mode_put,
14826 static struct hda_verb alc662_init_verbs[] = {
14827 /* ADC: mute amp left and right */
14828 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14829 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14830 /* Front mixer: unmute input/output amp left and right (volume = 0) */
14832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14834 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14836 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14840 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14841 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14842 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14843 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14845 /* Front Pin: output 0 (0x0c) */
14846 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14849 /* Rear Pin: output 1 (0x0d) */
14850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14853 /* CLFE Pin: output 2 (0x0e) */
14854 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14855 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14857 /* Mic (rear) pin: input vref at 80% */
14858 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14859 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14860 /* Front Mic pin: input vref at 80% */
14861 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14862 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14863 /* Line In pin: input */
14864 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14865 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14866 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14867 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14868 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14869 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14870 /* CD pin widget for input */
14871 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14873 /* FIXME: use matrix-type input source selection */
14874 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14877 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14878 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14881 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14882 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14883 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14884 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14886 /* always trun on EAPD */
14887 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14888 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14893 static struct hda_verb alc662_sue_init_verbs[] = {
14894 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14895 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14899 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14900 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14901 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14905 /* Set Unsolicited Event*/
14906 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14907 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14908 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14913 * generic initialization of ADC, input mixers and output mixers
14915 static struct hda_verb alc662_auto_init_verbs[] = {
14917 * Unmute ADC and set the default input to mic-in
14919 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14922 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14924 * Note: PASD motherboards uses the Line In 2 as the input for front
14925 * panel mic (mic 2)
14927 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14935 * Set up output mixers (0x0c - 0x0f)
14937 /* set vol=0 to output mixers */
14938 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14939 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14940 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14942 /* set up input amps for analog loopback */
14943 /* Amp Indices: DAC = 0, mixer = 1 */
14944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14946 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14947 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14948 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14949 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14952 /* FIXME: use matrix-type input source selection */
14953 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14960 /* additional verbs for ALC663 */
14961 static struct hda_verb alc663_auto_init_verbs[] = {
14962 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14963 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14967 static struct hda_verb alc663_m51va_init_verbs[] = {
14968 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14969 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14970 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14971 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14972 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14973 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14974 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14975 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14976 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14980 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
14981 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14982 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14983 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14986 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14987 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14991 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
14992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14993 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14994 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14995 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14996 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14997 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14998 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14999 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15003 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15005 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15006 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15010 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15014 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15015 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15016 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15017 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15018 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15019 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15020 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15021 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15022 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15024 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15025 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15026 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15030 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15031 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15032 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15033 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15034 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15036 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15037 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15038 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15039 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15040 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15041 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15042 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15046 static struct hda_verb alc663_g71v_init_verbs[] = {
15047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15048 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15049 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15051 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15052 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15053 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15055 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15056 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15057 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15061 static struct hda_verb alc663_g50v_init_verbs[] = {
15062 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15063 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15064 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15066 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15067 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15071 static struct hda_verb alc662_ecs_init_verbs[] = {
15072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15074 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15075 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15079 /* capture mixer elements */
15080 static struct snd_kcontrol_new alc662_capture_mixer[] = {
15081 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15082 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15084 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15085 /* The multiple "Capture Source" controls confuse alsamixer
15086 * So call somewhat different..
15088 /* .name = "Capture Source", */
15089 .name = "Input Source",
15091 .info = alc662_mux_enum_info,
15092 .get = alc662_mux_enum_get,
15093 .put = alc662_mux_enum_put,
15098 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15099 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15100 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15104 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15106 unsigned int present;
15107 unsigned char bits;
15109 present = snd_hda_codec_read(codec, 0x14, 0,
15110 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15111 bits = present ? HDA_AMP_MUTE : 0;
15112 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15113 HDA_AMP_MUTE, bits);
15116 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15118 unsigned int present;
15119 unsigned char bits;
15121 present = snd_hda_codec_read(codec, 0x1b, 0,
15122 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15123 bits = present ? HDA_AMP_MUTE : 0;
15124 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15125 HDA_AMP_MUTE, bits);
15126 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15127 HDA_AMP_MUTE, bits);
15130 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15133 if ((res >> 26) == ALC880_HP_EVENT)
15134 alc662_lenovo_101e_all_automute(codec);
15135 if ((res >> 26) == ALC880_FRONT_EVENT)
15136 alc662_lenovo_101e_ispeaker_automute(codec);
15139 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15141 unsigned int present;
15143 present = snd_hda_codec_read(codec, 0x18, 0,
15144 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15145 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15146 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15147 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15148 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15149 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15150 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15151 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15152 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15155 /* unsolicited event for HP jack sensing */
15156 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15159 if ((res >> 26) == ALC880_HP_EVENT)
15160 alc262_hippo1_automute( codec );
15162 if ((res >> 26) == ALC880_MIC_EVENT)
15163 alc662_eeepc_mic_automute(codec);
15166 static void alc662_eeepc_inithook(struct hda_codec *codec)
15168 alc262_hippo1_automute( codec );
15169 alc662_eeepc_mic_automute(codec);
15172 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15175 unsigned int present;
15177 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15178 present = snd_hda_codec_read(codec, 0x14, 0,
15179 AC_VERB_GET_PIN_SENSE, 0);
15180 present = (present & 0x80000000) != 0;
15182 /* mute internal speaker */
15183 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15184 HDA_AMP_MUTE, HDA_AMP_MUTE);
15186 /* unmute internal speaker if necessary */
15187 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15188 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15189 HDA_AMP_MUTE, mute);
15193 /* unsolicited event for HP jack sensing */
15194 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15197 if ((res >> 26) == ALC880_HP_EVENT)
15198 alc662_eeepc_ep20_automute(codec);
15201 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15203 alc662_eeepc_ep20_automute(codec);
15206 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15208 unsigned int present;
15209 unsigned char bits;
15211 present = snd_hda_codec_read(codec, 0x21, 0,
15212 AC_VERB_GET_PIN_SENSE, 0)
15213 & AC_PINSENSE_PRESENCE;
15214 bits = present ? HDA_AMP_MUTE : 0;
15215 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15216 AMP_IN_MUTE(0), bits);
15217 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15218 AMP_IN_MUTE(0), bits);
15221 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15223 unsigned int present;
15224 unsigned char bits;
15226 present = snd_hda_codec_read(codec, 0x21, 0,
15227 AC_VERB_GET_PIN_SENSE, 0)
15228 & AC_PINSENSE_PRESENCE;
15229 bits = present ? HDA_AMP_MUTE : 0;
15230 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15231 AMP_IN_MUTE(0), bits);
15232 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15233 AMP_IN_MUTE(0), bits);
15234 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15235 AMP_IN_MUTE(0), bits);
15236 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15237 AMP_IN_MUTE(0), bits);
15240 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15242 unsigned int present;
15243 unsigned char bits;
15245 present = snd_hda_codec_read(codec, 0x15, 0,
15246 AC_VERB_GET_PIN_SENSE, 0)
15247 & AC_PINSENSE_PRESENCE;
15248 bits = present ? HDA_AMP_MUTE : 0;
15249 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15250 AMP_IN_MUTE(0), bits);
15251 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15252 AMP_IN_MUTE(0), bits);
15253 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15254 AMP_IN_MUTE(0), bits);
15255 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15256 AMP_IN_MUTE(0), bits);
15259 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15261 unsigned int present;
15262 unsigned char bits;
15264 present = snd_hda_codec_read(codec, 0x1b, 0,
15265 AC_VERB_GET_PIN_SENSE, 0)
15266 & AC_PINSENSE_PRESENCE;
15267 bits = present ? 0 : PIN_OUT;
15268 snd_hda_codec_write(codec, 0x14, 0,
15269 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15272 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15274 unsigned int present1, present2;
15276 present1 = snd_hda_codec_read(codec, 0x21, 0,
15277 AC_VERB_GET_PIN_SENSE, 0)
15278 & AC_PINSENSE_PRESENCE;
15279 present2 = snd_hda_codec_read(codec, 0x15, 0,
15280 AC_VERB_GET_PIN_SENSE, 0)
15281 & AC_PINSENSE_PRESENCE;
15283 if (present1 || present2) {
15284 snd_hda_codec_write_cache(codec, 0x14, 0,
15285 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15287 snd_hda_codec_write_cache(codec, 0x14, 0,
15288 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15292 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15294 unsigned int present1, present2;
15296 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15297 AC_VERB_GET_PIN_SENSE, 0)
15298 & AC_PINSENSE_PRESENCE;
15299 present2 = snd_hda_codec_read(codec, 0x15, 0,
15300 AC_VERB_GET_PIN_SENSE, 0)
15301 & AC_PINSENSE_PRESENCE;
15303 if (present1 || present2) {
15304 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15305 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15306 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15307 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15309 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15310 AMP_IN_MUTE(0), 0);
15311 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15312 AMP_IN_MUTE(0), 0);
15316 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15318 unsigned int present;
15320 present = snd_hda_codec_read(codec, 0x18, 0,
15321 AC_VERB_GET_PIN_SENSE, 0)
15322 & AC_PINSENSE_PRESENCE;
15323 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15324 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15325 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15326 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15327 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15328 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15329 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15330 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15333 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15336 switch (res >> 26) {
15337 case ALC880_HP_EVENT:
15338 alc663_m51va_speaker_automute(codec);
15340 case ALC880_MIC_EVENT:
15341 alc663_m51va_mic_automute(codec);
15346 static void alc663_m51va_inithook(struct hda_codec *codec)
15348 alc663_m51va_speaker_automute(codec);
15349 alc663_m51va_mic_automute(codec);
15352 /* ***************** Mode1 ******************************/
15353 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15356 switch (res >> 26) {
15357 case ALC880_HP_EVENT:
15358 alc663_m51va_speaker_automute(codec);
15360 case ALC880_MIC_EVENT:
15361 alc662_eeepc_mic_automute(codec);
15366 static void alc663_mode1_inithook(struct hda_codec *codec)
15368 alc663_m51va_speaker_automute(codec);
15369 alc662_eeepc_mic_automute(codec);
15371 /* ***************** Mode2 ******************************/
15372 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15375 switch (res >> 26) {
15376 case ALC880_HP_EVENT:
15377 alc662_f5z_speaker_automute(codec);
15379 case ALC880_MIC_EVENT:
15380 alc662_eeepc_mic_automute(codec);
15385 static void alc662_mode2_inithook(struct hda_codec *codec)
15387 alc662_f5z_speaker_automute(codec);
15388 alc662_eeepc_mic_automute(codec);
15390 /* ***************** Mode3 ******************************/
15391 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15394 switch (res >> 26) {
15395 case ALC880_HP_EVENT:
15396 alc663_two_hp_m1_speaker_automute(codec);
15398 case ALC880_MIC_EVENT:
15399 alc662_eeepc_mic_automute(codec);
15404 static void alc663_mode3_inithook(struct hda_codec *codec)
15406 alc663_two_hp_m1_speaker_automute(codec);
15407 alc662_eeepc_mic_automute(codec);
15409 /* ***************** Mode4 ******************************/
15410 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15413 switch (res >> 26) {
15414 case ALC880_HP_EVENT:
15415 alc663_21jd_two_speaker_automute(codec);
15417 case ALC880_MIC_EVENT:
15418 alc662_eeepc_mic_automute(codec);
15423 static void alc663_mode4_inithook(struct hda_codec *codec)
15425 alc663_21jd_two_speaker_automute(codec);
15426 alc662_eeepc_mic_automute(codec);
15428 /* ***************** Mode5 ******************************/
15429 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15432 switch (res >> 26) {
15433 case ALC880_HP_EVENT:
15434 alc663_15jd_two_speaker_automute(codec);
15436 case ALC880_MIC_EVENT:
15437 alc662_eeepc_mic_automute(codec);
15442 static void alc663_mode5_inithook(struct hda_codec *codec)
15444 alc663_15jd_two_speaker_automute(codec);
15445 alc662_eeepc_mic_automute(codec);
15447 /* ***************** Mode6 ******************************/
15448 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15451 switch (res >> 26) {
15452 case ALC880_HP_EVENT:
15453 alc663_two_hp_m2_speaker_automute(codec);
15455 case ALC880_MIC_EVENT:
15456 alc662_eeepc_mic_automute(codec);
15461 static void alc663_mode6_inithook(struct hda_codec *codec)
15463 alc663_two_hp_m2_speaker_automute(codec);
15464 alc662_eeepc_mic_automute(codec);
15467 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15469 unsigned int present;
15470 unsigned char bits;
15472 present = snd_hda_codec_read(codec, 0x21, 0,
15473 AC_VERB_GET_PIN_SENSE, 0)
15474 & AC_PINSENSE_PRESENCE;
15475 bits = present ? HDA_AMP_MUTE : 0;
15476 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15477 HDA_AMP_MUTE, bits);
15478 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15479 HDA_AMP_MUTE, bits);
15482 static void alc663_g71v_front_automute(struct hda_codec *codec)
15484 unsigned int present;
15485 unsigned char bits;
15487 present = snd_hda_codec_read(codec, 0x15, 0,
15488 AC_VERB_GET_PIN_SENSE, 0)
15489 & AC_PINSENSE_PRESENCE;
15490 bits = present ? HDA_AMP_MUTE : 0;
15491 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15492 HDA_AMP_MUTE, bits);
15495 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15498 switch (res >> 26) {
15499 case ALC880_HP_EVENT:
15500 alc663_g71v_hp_automute(codec);
15502 case ALC880_FRONT_EVENT:
15503 alc663_g71v_front_automute(codec);
15505 case ALC880_MIC_EVENT:
15506 alc662_eeepc_mic_automute(codec);
15511 static void alc663_g71v_inithook(struct hda_codec *codec)
15513 alc663_g71v_front_automute(codec);
15514 alc663_g71v_hp_automute(codec);
15515 alc662_eeepc_mic_automute(codec);
15518 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15521 switch (res >> 26) {
15522 case ALC880_HP_EVENT:
15523 alc663_m51va_speaker_automute(codec);
15525 case ALC880_MIC_EVENT:
15526 alc662_eeepc_mic_automute(codec);
15531 static void alc663_g50v_inithook(struct hda_codec *codec)
15533 alc663_m51va_speaker_automute(codec);
15534 alc662_eeepc_mic_automute(codec);
15537 /* bind hp and internal speaker mute (with plug check) */
15538 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15539 struct snd_ctl_elem_value *ucontrol)
15541 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15542 long *valp = ucontrol->value.integer.value;
15545 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15547 valp[0] ? 0 : HDA_AMP_MUTE);
15548 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15550 valp[1] ? 0 : HDA_AMP_MUTE);
15552 alc262_hippo1_automute(codec);
15556 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15557 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15560 .name = "Master Playback Switch",
15561 .info = snd_hda_mixer_amp_switch_info,
15562 .get = snd_hda_mixer_amp_switch_get,
15563 .put = alc662_ecs_master_sw_put,
15564 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15567 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15568 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15569 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15571 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15572 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15573 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15577 #ifdef CONFIG_SND_HDA_POWER_SAVE
15578 #define alc662_loopbacks alc880_loopbacks
15582 /* pcm configuration: identiacal with ALC880 */
15583 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15584 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15585 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15586 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15589 * configuration and preset
15591 static const char *alc662_models[ALC662_MODEL_LAST] = {
15592 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15593 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15594 [ALC662_3ST_6ch] = "3stack-6ch",
15595 [ALC662_5ST_DIG] = "6stack-dig",
15596 [ALC662_LENOVO_101E] = "lenovo-101e",
15597 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15598 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15599 [ALC662_ECS] = "ecs",
15600 [ALC663_ASUS_M51VA] = "m51va",
15601 [ALC663_ASUS_G71V] = "g71v",
15602 [ALC663_ASUS_H13] = "h13",
15603 [ALC663_ASUS_G50V] = "g50v",
15604 [ALC663_ASUS_MODE1] = "asus-mode1",
15605 [ALC662_ASUS_MODE2] = "asus-mode2",
15606 [ALC663_ASUS_MODE3] = "asus-mode3",
15607 [ALC663_ASUS_MODE4] = "asus-mode4",
15608 [ALC663_ASUS_MODE5] = "asus-mode5",
15609 [ALC663_ASUS_MODE6] = "asus-mode6",
15610 [ALC662_AUTO] = "auto",
15613 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15614 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15615 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
15616 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15617 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15618 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15619 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15620 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15621 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15622 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15623 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15624 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15625 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15626 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15627 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15628 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15629 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15630 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15631 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15632 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15633 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15634 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15635 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15636 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15637 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15638 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15639 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15640 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15641 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15642 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15643 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15644 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15645 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15646 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15647 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15648 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15649 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15650 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15651 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15652 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15653 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15654 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15655 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15659 static struct alc_config_preset alc662_presets[] = {
15660 [ALC662_3ST_2ch_DIG] = {
15661 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15662 .init_verbs = { alc662_init_verbs },
15663 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15664 .dac_nids = alc662_dac_nids,
15665 .dig_out_nid = ALC662_DIGOUT_NID,
15666 .dig_in_nid = ALC662_DIGIN_NID,
15667 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15668 .channel_mode = alc662_3ST_2ch_modes,
15669 .input_mux = &alc662_capture_source,
15671 [ALC662_3ST_6ch_DIG] = {
15672 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15673 alc662_capture_mixer },
15674 .init_verbs = { alc662_init_verbs },
15675 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15676 .dac_nids = alc662_dac_nids,
15677 .dig_out_nid = ALC662_DIGOUT_NID,
15678 .dig_in_nid = ALC662_DIGIN_NID,
15679 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15680 .channel_mode = alc662_3ST_6ch_modes,
15682 .input_mux = &alc662_capture_source,
15684 [ALC662_3ST_6ch] = {
15685 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15686 alc662_capture_mixer },
15687 .init_verbs = { alc662_init_verbs },
15688 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15689 .dac_nids = alc662_dac_nids,
15690 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15691 .channel_mode = alc662_3ST_6ch_modes,
15693 .input_mux = &alc662_capture_source,
15695 [ALC662_5ST_DIG] = {
15696 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15697 alc662_capture_mixer },
15698 .init_verbs = { alc662_init_verbs },
15699 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15700 .dac_nids = alc662_dac_nids,
15701 .dig_out_nid = ALC662_DIGOUT_NID,
15702 .dig_in_nid = ALC662_DIGIN_NID,
15703 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15704 .channel_mode = alc662_5stack_modes,
15705 .input_mux = &alc662_capture_source,
15707 [ALC662_LENOVO_101E] = {
15708 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15709 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15710 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15711 .dac_nids = alc662_dac_nids,
15712 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15713 .channel_mode = alc662_3ST_2ch_modes,
15714 .input_mux = &alc662_lenovo_101e_capture_source,
15715 .unsol_event = alc662_lenovo_101e_unsol_event,
15716 .init_hook = alc662_lenovo_101e_all_automute,
15718 [ALC662_ASUS_EEEPC_P701] = {
15719 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15720 .init_verbs = { alc662_init_verbs,
15721 alc662_eeepc_sue_init_verbs },
15722 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15723 .dac_nids = alc662_dac_nids,
15724 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15725 .channel_mode = alc662_3ST_2ch_modes,
15726 .input_mux = &alc662_eeepc_capture_source,
15727 .unsol_event = alc662_eeepc_unsol_event,
15728 .init_hook = alc662_eeepc_inithook,
15730 [ALC662_ASUS_EEEPC_EP20] = {
15731 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15732 alc662_chmode_mixer },
15733 .init_verbs = { alc662_init_verbs,
15734 alc662_eeepc_ep20_sue_init_verbs },
15735 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15736 .dac_nids = alc662_dac_nids,
15737 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15738 .channel_mode = alc662_3ST_6ch_modes,
15739 .input_mux = &alc662_lenovo_101e_capture_source,
15740 .unsol_event = alc662_eeepc_ep20_unsol_event,
15741 .init_hook = alc662_eeepc_ep20_inithook,
15744 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15745 .init_verbs = { alc662_init_verbs,
15746 alc662_ecs_init_verbs },
15747 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15748 .dac_nids = alc662_dac_nids,
15749 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15750 .channel_mode = alc662_3ST_2ch_modes,
15751 .input_mux = &alc662_eeepc_capture_source,
15752 .unsol_event = alc662_eeepc_unsol_event,
15753 .init_hook = alc662_eeepc_inithook,
15755 [ALC663_ASUS_M51VA] = {
15756 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15757 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15758 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15759 .dac_nids = alc662_dac_nids,
15760 .dig_out_nid = ALC662_DIGOUT_NID,
15761 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15762 .channel_mode = alc662_3ST_2ch_modes,
15763 .input_mux = &alc663_m51va_capture_source,
15764 .unsol_event = alc663_m51va_unsol_event,
15765 .init_hook = alc663_m51va_inithook,
15767 [ALC663_ASUS_G71V] = {
15768 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15769 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15770 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15771 .dac_nids = alc662_dac_nids,
15772 .dig_out_nid = ALC662_DIGOUT_NID,
15773 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15774 .channel_mode = alc662_3ST_2ch_modes,
15775 .input_mux = &alc662_eeepc_capture_source,
15776 .unsol_event = alc663_g71v_unsol_event,
15777 .init_hook = alc663_g71v_inithook,
15779 [ALC663_ASUS_H13] = {
15780 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15781 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15782 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15783 .dac_nids = alc662_dac_nids,
15784 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15785 .channel_mode = alc662_3ST_2ch_modes,
15786 .input_mux = &alc663_m51va_capture_source,
15787 .unsol_event = alc663_m51va_unsol_event,
15788 .init_hook = alc663_m51va_inithook,
15790 [ALC663_ASUS_G50V] = {
15791 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15792 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15793 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15794 .dac_nids = alc662_dac_nids,
15795 .dig_out_nid = ALC662_DIGOUT_NID,
15796 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15797 .channel_mode = alc662_3ST_6ch_modes,
15798 .input_mux = &alc663_capture_source,
15799 .unsol_event = alc663_g50v_unsol_event,
15800 .init_hook = alc663_g50v_inithook,
15802 [ALC663_ASUS_MODE1] = {
15803 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
15804 .init_verbs = { alc662_init_verbs,
15805 alc663_21jd_amic_init_verbs },
15806 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15808 .dac_nids = alc662_dac_nids,
15809 .dig_out_nid = ALC662_DIGOUT_NID,
15810 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15811 .channel_mode = alc662_3ST_2ch_modes,
15812 .input_mux = &alc662_eeepc_capture_source,
15813 .unsol_event = alc663_mode1_unsol_event,
15814 .init_hook = alc663_mode1_inithook,
15816 [ALC662_ASUS_MODE2] = {
15817 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
15818 .init_verbs = { alc662_init_verbs,
15819 alc662_1bjd_amic_init_verbs },
15820 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15821 .dac_nids = alc662_dac_nids,
15822 .dig_out_nid = ALC662_DIGOUT_NID,
15823 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15824 .channel_mode = alc662_3ST_2ch_modes,
15825 .input_mux = &alc662_eeepc_capture_source,
15826 .unsol_event = alc662_mode2_unsol_event,
15827 .init_hook = alc662_mode2_inithook,
15829 [ALC663_ASUS_MODE3] = {
15830 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
15831 .init_verbs = { alc662_init_verbs,
15832 alc663_two_hp_amic_m1_init_verbs },
15833 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15835 .dac_nids = alc662_dac_nids,
15836 .dig_out_nid = ALC662_DIGOUT_NID,
15837 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15838 .channel_mode = alc662_3ST_2ch_modes,
15839 .input_mux = &alc662_eeepc_capture_source,
15840 .unsol_event = alc663_mode3_unsol_event,
15841 .init_hook = alc663_mode3_inithook,
15843 [ALC663_ASUS_MODE4] = {
15844 .mixers = { alc663_asus_21jd_clfe_mixer,
15845 alc662_auto_capture_mixer},
15846 .init_verbs = { alc662_init_verbs,
15847 alc663_21jd_amic_init_verbs},
15848 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15850 .dac_nids = alc662_dac_nids,
15851 .dig_out_nid = ALC662_DIGOUT_NID,
15852 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15853 .channel_mode = alc662_3ST_2ch_modes,
15854 .input_mux = &alc662_eeepc_capture_source,
15855 .unsol_event = alc663_mode4_unsol_event,
15856 .init_hook = alc663_mode4_inithook,
15858 [ALC663_ASUS_MODE5] = {
15859 .mixers = { alc663_asus_15jd_clfe_mixer,
15860 alc662_auto_capture_mixer },
15861 .init_verbs = { alc662_init_verbs,
15862 alc663_15jd_amic_init_verbs },
15863 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15865 .dac_nids = alc662_dac_nids,
15866 .dig_out_nid = ALC662_DIGOUT_NID,
15867 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15868 .channel_mode = alc662_3ST_2ch_modes,
15869 .input_mux = &alc662_eeepc_capture_source,
15870 .unsol_event = alc663_mode5_unsol_event,
15871 .init_hook = alc663_mode5_inithook,
15873 [ALC663_ASUS_MODE6] = {
15874 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
15875 .init_verbs = { alc662_init_verbs,
15876 alc663_two_hp_amic_m2_init_verbs },
15877 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15879 .dac_nids = alc662_dac_nids,
15880 .dig_out_nid = ALC662_DIGOUT_NID,
15881 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15882 .channel_mode = alc662_3ST_2ch_modes,
15883 .input_mux = &alc662_eeepc_capture_source,
15884 .unsol_event = alc663_mode6_unsol_event,
15885 .init_hook = alc663_mode6_inithook,
15891 * BIOS auto configuration
15894 /* add playback controls from the parsed DAC table */
15895 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15896 const struct auto_pin_cfg *cfg)
15899 static const char *chname[4] = {
15900 "Front", "Surround", NULL /*CLFE*/, "Side"
15905 for (i = 0; i < cfg->line_outs; i++) {
15906 if (!spec->multiout.dac_nids[i])
15908 nid = alc880_idx_to_dac(i);
15911 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15912 "Center Playback Volume",
15913 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15917 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15918 "LFE Playback Volume",
15919 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15923 err = add_control(spec, ALC_CTL_BIND_MUTE,
15924 "Center Playback Switch",
15925 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
15929 err = add_control(spec, ALC_CTL_BIND_MUTE,
15930 "LFE Playback Switch",
15931 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
15936 sprintf(name, "%s Playback Volume", chname[i]);
15937 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15938 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
15942 sprintf(name, "%s Playback Switch", chname[i]);
15943 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15944 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
15953 /* add playback controls for speaker and HP outputs */
15954 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
15965 /* ALC663 has a mono output pin on 0x17 */
15966 sprintf(name, "%s Playback Switch", pfx);
15967 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15968 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
15972 if (alc880_is_fixed_pin(pin)) {
15973 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15974 /* printk("DAC nid=%x\n",nid); */
15975 /* specify the DAC as the extra output */
15976 if (!spec->multiout.hp_nid)
15977 spec->multiout.hp_nid = nid;
15979 spec->multiout.extra_out_nid[0] = nid;
15980 /* control HP volume/switch on the output mixer amp */
15981 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15982 sprintf(name, "%s Playback Volume", pfx);
15983 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15984 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
15987 sprintf(name, "%s Playback Switch", pfx);
15988 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15989 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
15992 } else if (alc880_is_multi_pin(pin)) {
15993 /* set manual connection */
15994 /* we have only a switch on HP-out PIN */
15995 sprintf(name, "%s Playback Switch", pfx);
15996 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15997 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16004 /* create playback/capture controls for input pins */
16005 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16006 const struct auto_pin_cfg *cfg)
16008 struct hda_input_mux *imux = &spec->private_imux;
16011 for (i = 0; i < AUTO_PIN_LAST; i++) {
16012 if (alc880_is_input_pin(cfg->input_pins[i])) {
16013 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16014 err = new_analog_input(spec, cfg->input_pins[i],
16015 auto_pin_cfg_labels[i],
16019 imux->items[imux->num_items].label =
16020 auto_pin_cfg_labels[i];
16021 imux->items[imux->num_items].index =
16022 alc880_input_pin_idx(cfg->input_pins[i]);
16029 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16030 hda_nid_t nid, int pin_type,
16033 alc_set_pin_output(codec, nid, pin_type);
16034 /* need the manual connection? */
16035 if (alc880_is_multi_pin(nid)) {
16036 struct alc_spec *spec = codec->spec;
16037 int idx = alc880_multi_pin_idx(nid);
16038 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16039 AC_VERB_SET_CONNECT_SEL,
16040 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16044 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16046 struct alc_spec *spec = codec->spec;
16049 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16050 for (i = 0; i <= HDA_SIDE; i++) {
16051 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16052 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16054 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16059 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16061 struct alc_spec *spec = codec->spec;
16064 pin = spec->autocfg.hp_pins[0];
16065 if (pin) /* connect to front */
16067 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16068 pin = spec->autocfg.speaker_pins[0];
16070 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16073 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16074 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16076 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16078 struct alc_spec *spec = codec->spec;
16081 for (i = 0; i < AUTO_PIN_LAST; i++) {
16082 hda_nid_t nid = spec->autocfg.input_pins[i];
16083 if (alc662_is_input_pin(nid)) {
16084 snd_hda_codec_write(codec, nid, 0,
16085 AC_VERB_SET_PIN_WIDGET_CONTROL,
16086 (i <= AUTO_PIN_FRONT_MIC ?
16087 PIN_VREF80 : PIN_IN));
16088 if (nid != ALC662_PIN_CD_NID)
16089 snd_hda_codec_write(codec, nid, 0,
16090 AC_VERB_SET_AMP_GAIN_MUTE,
16096 #define alc662_auto_init_input_src alc882_auto_init_input_src
16098 static int alc662_parse_auto_config(struct hda_codec *codec)
16100 struct alc_spec *spec = codec->spec;
16102 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16104 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16108 if (!spec->autocfg.line_outs)
16109 return 0; /* can't find valid BIOS pin config */
16111 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16114 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16117 err = alc662_auto_create_extra_out(spec,
16118 spec->autocfg.speaker_pins[0],
16122 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16126 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16130 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16132 if (spec->autocfg.dig_out_pin)
16133 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16135 if (spec->kctl_alloc)
16136 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
16138 spec->num_mux_defs = 1;
16139 spec->input_mux = &spec->private_imux;
16141 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
16142 if (codec->vendor_id == 0x10ec0663)
16143 spec->init_verbs[spec->num_init_verbs++] =
16144 alc663_auto_init_verbs;
16146 err = alc_auto_add_mic_boost(codec);
16150 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16151 spec->num_mixers++;
16155 /* additional initialization for auto-configuration model */
16156 static void alc662_auto_init(struct hda_codec *codec)
16158 struct alc_spec *spec = codec->spec;
16159 alc662_auto_init_multi_out(codec);
16160 alc662_auto_init_hp_out(codec);
16161 alc662_auto_init_analog_input(codec);
16162 alc662_auto_init_input_src(codec);
16163 if (spec->unsol_event)
16164 alc_sku_automute(codec);
16167 static int patch_alc662(struct hda_codec *codec)
16169 struct alc_spec *spec;
16170 int err, board_config;
16172 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16176 codec->spec = spec;
16178 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16180 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16183 if (board_config < 0) {
16184 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16185 "trying auto-probe from BIOS...\n");
16186 board_config = ALC662_AUTO;
16189 if (board_config == ALC662_AUTO) {
16190 /* automatic parse from the BIOS config */
16191 err = alc662_parse_auto_config(codec);
16197 "hda_codec: Cannot set up configuration "
16198 "from BIOS. Using base mode...\n");
16199 board_config = ALC662_3ST_2ch_DIG;
16203 if (board_config != ALC662_AUTO)
16204 setup_preset(spec, &alc662_presets[board_config]);
16206 if (codec->vendor_id == 0x10ec0663) {
16207 spec->stream_name_analog = "ALC663 Analog";
16208 spec->stream_name_digital = "ALC663 Digital";
16210 spec->stream_name_analog = "ALC662 Analog";
16211 spec->stream_name_digital = "ALC662 Digital";
16214 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16215 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16217 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16218 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16220 spec->adc_nids = alc662_adc_nids;
16221 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16222 spec->capsrc_nids = alc662_capsrc_nids;
16224 spec->vmaster_nid = 0x02;
16226 codec->patch_ops = alc_patch_ops;
16227 if (board_config == ALC662_AUTO)
16228 spec->init_hook = alc662_auto_init;
16229 #ifdef CONFIG_SND_HDA_POWER_SAVE
16230 if (!spec->loopback.amplist)
16231 spec->loopback.amplist = alc662_loopbacks;
16240 struct hda_codec_preset snd_hda_preset_realtek[] = {
16241 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16242 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16243 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16244 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16245 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16246 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16247 .patch = patch_alc861 },
16248 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16249 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16250 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16251 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16252 .patch = patch_alc883 },
16253 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16254 .patch = patch_alc662 },
16255 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16256 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16257 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16258 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16259 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16260 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16261 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16262 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16263 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16264 {} /* terminator */