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 */
129 ALC269_ASUS_EEEPC_P703,
130 ALC269_ASUS_EEEPC_P901,
132 ALC269_MODEL_LAST /* last tag */
149 /* ALC861-VD models */
170 ALC662_ASUS_EEEPC_P701,
171 ALC662_ASUS_EEEPC_EP20,
203 ALC883_TARGA_2ch_DIG,
209 ALC883_LENOVO_101E_2ch,
210 ALC883_LENOVO_NB0763,
211 ALC888_LENOVO_MS7195_DIG,
217 ALC883_FUJITSU_PI2515,
218 ALC883_3ST_6ch_INTEL,
224 #define GPIO_MASK 0x03
227 /* codec parameterization */
228 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
229 unsigned int num_mixers;
231 const struct hda_verb *init_verbs[5]; /* initialization verbs
235 unsigned int num_init_verbs;
237 char *stream_name_analog; /* analog PCM stream */
238 struct hda_pcm_stream *stream_analog_playback;
239 struct hda_pcm_stream *stream_analog_capture;
240 struct hda_pcm_stream *stream_analog_alt_playback;
241 struct hda_pcm_stream *stream_analog_alt_capture;
243 char *stream_name_digital; /* digital PCM stream */
244 struct hda_pcm_stream *stream_digital_playback;
245 struct hda_pcm_stream *stream_digital_capture;
248 struct hda_multi_out multiout; /* playback set-up
249 * max_channels, dacs must be set
250 * dig_out_nid and hp_nid are optional
252 hda_nid_t alt_dac_nid;
255 unsigned int num_adc_nids;
257 hda_nid_t *capsrc_nids;
258 hda_nid_t dig_in_nid; /* digital-in NID; optional */
261 unsigned int num_mux_defs;
262 const struct hda_input_mux *input_mux;
263 unsigned int cur_mux[3];
266 const struct hda_channel_mode *channel_mode;
267 int num_channel_mode;
270 /* PCM information */
271 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
273 /* dynamic controls, init_verbs and input_mux */
274 struct auto_pin_cfg autocfg;
275 unsigned int num_kctl_alloc, num_kctl_used;
276 struct snd_kcontrol_new *kctl_alloc;
277 struct hda_input_mux private_imux;
278 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
281 void (*init_hook)(struct hda_codec *codec);
282 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
284 /* for pin sensing */
285 unsigned int sense_updated: 1;
286 unsigned int jack_present: 1;
287 unsigned int master_sw: 1;
289 /* for virtual master */
290 hda_nid_t vmaster_nid;
291 #ifdef CONFIG_SND_HDA_POWER_SAVE
292 struct hda_loopback_check loopback;
297 unsigned int pll_coef_idx, pll_coef_bit;
301 * configuration template - to be copied to the spec instance
303 struct alc_config_preset {
304 struct snd_kcontrol_new *mixers[5]; /* should be identical size
307 const struct hda_verb *init_verbs[5];
308 unsigned int num_dacs;
310 hda_nid_t dig_out_nid; /* optional */
311 hda_nid_t hp_nid; /* optional */
312 unsigned int num_adc_nids;
314 hda_nid_t *capsrc_nids;
315 hda_nid_t dig_in_nid;
316 unsigned int num_channel_mode;
317 const struct hda_channel_mode *channel_mode;
319 unsigned int num_mux_defs;
320 const struct hda_input_mux *input_mux;
321 void (*unsol_event)(struct hda_codec *, unsigned int);
322 void (*init_hook)(struct hda_codec *);
323 #ifdef CONFIG_SND_HDA_POWER_SAVE
324 struct hda_amp_list *loopbacks;
332 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
333 struct snd_ctl_elem_info *uinfo)
335 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
336 struct alc_spec *spec = codec->spec;
337 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
338 if (mux_idx >= spec->num_mux_defs)
340 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
343 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347 struct alc_spec *spec = codec->spec;
348 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
350 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
354 static int alc_mux_enum_put(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);
360 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
361 hda_nid_t nid = spec->capsrc_nids ?
362 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
363 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
364 nid, &spec->cur_mux[adc_idx]);
369 * channel mode setting
371 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
372 struct snd_ctl_elem_info *uinfo)
374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
375 struct alc_spec *spec = codec->spec;
376 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
377 spec->num_channel_mode);
380 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
384 struct alc_spec *spec = codec->spec;
385 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
386 spec->num_channel_mode,
387 spec->multiout.max_channels);
390 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol)
393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
394 struct alc_spec *spec = codec->spec;
395 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
396 spec->num_channel_mode,
397 &spec->multiout.max_channels);
398 if (err >= 0 && spec->need_dac_fix)
399 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
404 * Control the mode of pin widget settings via the mixer. "pc" is used
405 * instead of "%" to avoid consequences of accidently treating the % as
406 * being part of a format specifier. Maximum allowed length of a value is
407 * 63 characters plus NULL terminator.
409 * Note: some retasking pin complexes seem to ignore requests for input
410 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
411 * are requested. Therefore order this list so that this behaviour will not
412 * cause problems when mixer clients move through the enum sequentially.
413 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
416 static char *alc_pin_mode_names[] = {
417 "Mic 50pc bias", "Mic 80pc bias",
418 "Line in", "Line out", "Headphone out",
420 static unsigned char alc_pin_mode_values[] = {
421 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
423 /* The control can present all 5 options, or it can limit the options based
424 * in the pin being assumed to be exclusively an input or an output pin. In
425 * addition, "input" pins may or may not process the mic bias option
426 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
427 * accept requests for bias as of chip versions up to March 2006) and/or
428 * wiring in the computer.
430 #define ALC_PIN_DIR_IN 0x00
431 #define ALC_PIN_DIR_OUT 0x01
432 #define ALC_PIN_DIR_INOUT 0x02
433 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
434 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
436 /* Info about the pin modes supported by the different pin direction modes.
437 * For each direction the minimum and maximum values are given.
439 static signed char alc_pin_mode_dir_info[5][2] = {
440 { 0, 2 }, /* ALC_PIN_DIR_IN */
441 { 3, 4 }, /* ALC_PIN_DIR_OUT */
442 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
443 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
444 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
446 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
447 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
448 #define alc_pin_mode_n_items(_dir) \
449 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
451 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
452 struct snd_ctl_elem_info *uinfo)
454 unsigned int item_num = uinfo->value.enumerated.item;
455 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
457 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
459 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
461 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
462 item_num = alc_pin_mode_min(dir);
463 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
467 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_value *ucontrol)
471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
472 hda_nid_t nid = kcontrol->private_value & 0xffff;
473 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
474 long *valp = ucontrol->value.integer.value;
475 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
476 AC_VERB_GET_PIN_WIDGET_CONTROL,
479 /* Find enumerated value for current pinctl setting */
480 i = alc_pin_mode_min(dir);
481 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
483 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
487 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
488 struct snd_ctl_elem_value *ucontrol)
491 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
492 hda_nid_t nid = kcontrol->private_value & 0xffff;
493 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
494 long val = *ucontrol->value.integer.value;
495 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
496 AC_VERB_GET_PIN_WIDGET_CONTROL,
499 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
500 val = alc_pin_mode_min(dir);
502 change = pinctl != alc_pin_mode_values[val];
504 /* Set pin mode to that requested */
505 snd_hda_codec_write_cache(codec, nid, 0,
506 AC_VERB_SET_PIN_WIDGET_CONTROL,
507 alc_pin_mode_values[val]);
509 /* Also enable the retasking pin's input/output as required
510 * for the requested pin mode. Enum values of 2 or less are
513 * Dynamically switching the input/output buffers probably
514 * reduces noise slightly (particularly on input) so we'll
515 * do it. However, having both input and output buffers
516 * enabled simultaneously doesn't seem to be problematic if
517 * this turns out to be necessary in the future.
520 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
521 HDA_AMP_MUTE, HDA_AMP_MUTE);
522 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
525 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
526 HDA_AMP_MUTE, HDA_AMP_MUTE);
527 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
534 #define ALC_PIN_MODE(xname, nid, dir) \
535 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
536 .info = alc_pin_mode_info, \
537 .get = alc_pin_mode_get, \
538 .put = alc_pin_mode_put, \
539 .private_value = nid | (dir<<16) }
541 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
542 * together using a mask with more than one bit set. This control is
543 * currently used only by the ALC260 test model. At this stage they are not
544 * needed for any "production" models.
546 #ifdef CONFIG_SND_DEBUG
547 #define alc_gpio_data_info snd_ctl_boolean_mono_info
549 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *ucontrol)
552 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
553 hda_nid_t nid = kcontrol->private_value & 0xffff;
554 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
555 long *valp = ucontrol->value.integer.value;
556 unsigned int val = snd_hda_codec_read(codec, nid, 0,
557 AC_VERB_GET_GPIO_DATA, 0x00);
559 *valp = (val & mask) != 0;
562 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
566 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
567 hda_nid_t nid = kcontrol->private_value & 0xffff;
568 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
569 long val = *ucontrol->value.integer.value;
570 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
571 AC_VERB_GET_GPIO_DATA,
574 /* Set/unset the masked GPIO bit(s) as needed */
575 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
580 snd_hda_codec_write_cache(codec, nid, 0,
581 AC_VERB_SET_GPIO_DATA, gpio_data);
585 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
586 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
587 .info = alc_gpio_data_info, \
588 .get = alc_gpio_data_get, \
589 .put = alc_gpio_data_put, \
590 .private_value = nid | (mask<<16) }
591 #endif /* CONFIG_SND_DEBUG */
593 /* A switch control to allow the enabling of the digital IO pins on the
594 * ALC260. This is incredibly simplistic; the intention of this control is
595 * to provide something in the test model allowing digital outputs to be
596 * identified if present. If models are found which can utilise these
597 * outputs a more complete mixer control can be devised for those models if
600 #ifdef CONFIG_SND_DEBUG
601 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
603 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
607 hda_nid_t nid = kcontrol->private_value & 0xffff;
608 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
609 long *valp = ucontrol->value.integer.value;
610 unsigned int val = snd_hda_codec_read(codec, nid, 0,
611 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
613 *valp = (val & mask) != 0;
616 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
617 struct snd_ctl_elem_value *ucontrol)
620 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
621 hda_nid_t nid = kcontrol->private_value & 0xffff;
622 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
623 long val = *ucontrol->value.integer.value;
624 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
625 AC_VERB_GET_DIGI_CONVERT_1,
628 /* Set/unset the masked control bit(s) as needed */
629 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
634 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
639 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
640 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
641 .info = alc_spdif_ctrl_info, \
642 .get = alc_spdif_ctrl_get, \
643 .put = alc_spdif_ctrl_put, \
644 .private_value = nid | (mask<<16) }
645 #endif /* CONFIG_SND_DEBUG */
647 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
648 * Again, this is only used in the ALC26x test models to help identify when
649 * the EAPD line must be asserted for features to work.
651 #ifdef CONFIG_SND_DEBUG
652 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
654 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
658 hda_nid_t nid = kcontrol->private_value & 0xffff;
659 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
660 long *valp = ucontrol->value.integer.value;
661 unsigned int val = snd_hda_codec_read(codec, nid, 0,
662 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
664 *valp = (val & mask) != 0;
668 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_value *ucontrol)
672 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
673 hda_nid_t nid = kcontrol->private_value & 0xffff;
674 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
675 long val = *ucontrol->value.integer.value;
676 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
677 AC_VERB_GET_EAPD_BTLENABLE,
680 /* Set/unset the masked control bit(s) as needed */
681 change = (!val ? 0 : mask) != (ctrl_data & mask);
686 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
692 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
693 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
694 .info = alc_eapd_ctrl_info, \
695 .get = alc_eapd_ctrl_get, \
696 .put = alc_eapd_ctrl_put, \
697 .private_value = nid | (mask<<16) }
698 #endif /* CONFIG_SND_DEBUG */
701 * set up from the preset table
703 static void setup_preset(struct alc_spec *spec,
704 const struct alc_config_preset *preset)
708 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
709 spec->mixers[spec->num_mixers++] = preset->mixers[i];
710 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
712 spec->init_verbs[spec->num_init_verbs++] =
713 preset->init_verbs[i];
715 spec->channel_mode = preset->channel_mode;
716 spec->num_channel_mode = preset->num_channel_mode;
717 spec->need_dac_fix = preset->need_dac_fix;
719 spec->multiout.max_channels = spec->channel_mode[0].channels;
721 spec->multiout.num_dacs = preset->num_dacs;
722 spec->multiout.dac_nids = preset->dac_nids;
723 spec->multiout.dig_out_nid = preset->dig_out_nid;
724 spec->multiout.hp_nid = preset->hp_nid;
726 spec->num_mux_defs = preset->num_mux_defs;
727 if (!spec->num_mux_defs)
728 spec->num_mux_defs = 1;
729 spec->input_mux = preset->input_mux;
731 spec->num_adc_nids = preset->num_adc_nids;
732 spec->adc_nids = preset->adc_nids;
733 spec->capsrc_nids = preset->capsrc_nids;
734 spec->dig_in_nid = preset->dig_in_nid;
736 spec->unsol_event = preset->unsol_event;
737 spec->init_hook = preset->init_hook;
738 #ifdef CONFIG_SND_HDA_POWER_SAVE
739 spec->loopback.amplist = preset->loopbacks;
743 /* Enable GPIO mask and set output */
744 static struct hda_verb alc_gpio1_init_verbs[] = {
745 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
746 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
747 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
751 static struct hda_verb alc_gpio2_init_verbs[] = {
752 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
753 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
754 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
758 static struct hda_verb alc_gpio3_init_verbs[] = {
759 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
760 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
761 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
766 * Fix hardware PLL issue
767 * On some codecs, the analog PLL gating control must be off while
768 * the default value is 1.
770 static void alc_fix_pll(struct hda_codec *codec)
772 struct alc_spec *spec = codec->spec;
777 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
779 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
780 AC_VERB_GET_PROC_COEF, 0);
781 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
783 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
784 val & ~(1 << spec->pll_coef_bit));
787 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
788 unsigned int coef_idx, unsigned int coef_bit)
790 struct alc_spec *spec = codec->spec;
792 spec->pll_coef_idx = coef_idx;
793 spec->pll_coef_bit = coef_bit;
797 static void alc_sku_automute(struct hda_codec *codec)
799 struct alc_spec *spec = codec->spec;
800 unsigned int present;
801 unsigned int hp_nid = spec->autocfg.hp_pins[0];
802 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
804 /* need to execute and sync at first */
805 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
806 present = snd_hda_codec_read(codec, hp_nid, 0,
807 AC_VERB_GET_PIN_SENSE, 0);
808 spec->jack_present = (present & 0x80000000) != 0;
809 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
810 spec->jack_present ? 0 : PIN_OUT);
813 /* unsolicited event for HP jack sensing */
814 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
816 if (codec->vendor_id == 0x10ec0880)
820 if (res != ALC880_HP_EVENT)
823 alc_sku_automute(codec);
826 /* additional initialization for ALC888 variants */
827 static void alc888_coef_init(struct hda_codec *codec)
831 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
832 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
833 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
834 if ((tmp & 0xf0) == 2)
836 snd_hda_codec_read(codec, 0x20, 0,
837 AC_VERB_SET_PROC_COEF, 0x830);
840 snd_hda_codec_read(codec, 0x20, 0,
841 AC_VERB_SET_PROC_COEF, 0x3030);
844 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
845 * 31 ~ 16 : Manufacture ID
847 * 7 ~ 0 : Assembly ID
848 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
850 static void alc_subsystem_id(struct hda_codec *codec,
851 unsigned int porta, unsigned int porte,
854 unsigned int ass, tmp, i;
856 struct alc_spec *spec = codec->spec;
858 ass = codec->subsystem_id & 0xffff;
859 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
863 * 31~30 : port conetcivity
866 * 19~16 : Check sum (15:1)
871 if (codec->vendor_id == 0x10ec0260)
873 ass = snd_hda_codec_read(codec, nid, 0,
874 AC_VERB_GET_CONFIG_DEFAULT, 0);
875 if (!(ass & 1) && !(ass & 0x100000))
877 if ((ass >> 30) != 1) /* no physical connection */
882 for (i = 1; i < 16; i++) {
886 if (((ass >> 16) & 0xf) != tmp)
892 * 2 : 0 --> Desktop, 1 --> Laptop
893 * 3~5 : External Amplifier control
896 tmp = (ass & 0x38) >> 3; /* external Amp control */
899 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
902 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
905 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
907 case 5: /* set EAPD output high */
908 switch (codec->vendor_id) {
910 snd_hda_codec_write(codec, 0x0f, 0,
911 AC_VERB_SET_EAPD_BTLENABLE, 2);
912 snd_hda_codec_write(codec, 0x10, 0,
913 AC_VERB_SET_EAPD_BTLENABLE, 2);
924 snd_hda_codec_write(codec, 0x14, 0,
925 AC_VERB_SET_EAPD_BTLENABLE, 2);
926 snd_hda_codec_write(codec, 0x15, 0,
927 AC_VERB_SET_EAPD_BTLENABLE, 2);
930 switch (codec->vendor_id) {
932 snd_hda_codec_write(codec, 0x1a, 0,
933 AC_VERB_SET_COEF_INDEX, 7);
934 tmp = snd_hda_codec_read(codec, 0x1a, 0,
935 AC_VERB_GET_PROC_COEF, 0);
936 snd_hda_codec_write(codec, 0x1a, 0,
937 AC_VERB_SET_COEF_INDEX, 7);
938 snd_hda_codec_write(codec, 0x1a, 0,
939 AC_VERB_SET_PROC_COEF,
948 snd_hda_codec_write(codec, 0x20, 0,
949 AC_VERB_SET_COEF_INDEX, 7);
950 tmp = snd_hda_codec_read(codec, 0x20, 0,
951 AC_VERB_GET_PROC_COEF, 0);
952 snd_hda_codec_write(codec, 0x20, 0,
953 AC_VERB_SET_COEF_INDEX, 7);
954 snd_hda_codec_write(codec, 0x20, 0,
955 AC_VERB_SET_PROC_COEF,
959 /*alc888_coef_init(codec);*/ /* called in alc_init() */
963 snd_hda_codec_write(codec, 0x20, 0,
964 AC_VERB_SET_COEF_INDEX, 7);
965 tmp = snd_hda_codec_read(codec, 0x20, 0,
966 AC_VERB_GET_PROC_COEF, 0);
967 snd_hda_codec_write(codec, 0x20, 0,
968 AC_VERB_SET_COEF_INDEX, 7);
969 snd_hda_codec_write(codec, 0x20, 0,
970 AC_VERB_SET_PROC_COEF,
978 /* is laptop or Desktop and enable the function "Mute internal speaker
979 * when the external headphone out jack is plugged"
984 * 10~8 : Jack location
985 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
987 * 15 : 1 --> enable the function "Mute internal speaker
988 * when the external headphone out jack is plugged"
990 if (!spec->autocfg.speaker_pins[0]) {
991 if (spec->autocfg.line_out_pins[0])
992 spec->autocfg.speaker_pins[0] =
993 spec->autocfg.line_out_pins[0];
998 if (!spec->autocfg.hp_pins[0]) {
999 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1001 spec->autocfg.hp_pins[0] = porta;
1003 spec->autocfg.hp_pins[0] = porte;
1005 spec->autocfg.hp_pins[0] = portd;
1010 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1011 AC_VERB_SET_UNSOLICITED_ENABLE,
1012 AC_USRSP_EN | ALC880_HP_EVENT);
1014 spec->unsol_event = alc_sku_unsol_event;
1018 * Fix-up pin default configurations
1026 static void alc_fix_pincfg(struct hda_codec *codec,
1027 const struct snd_pci_quirk *quirk,
1028 const struct alc_pincfg **pinfix)
1030 const struct alc_pincfg *cfg;
1032 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1036 cfg = pinfix[quirk->value];
1037 for (; cfg->nid; cfg++) {
1040 for (i = 0; i < 4; i++) {
1041 snd_hda_codec_write(codec, cfg->nid, 0,
1042 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1050 * ALC880 3-stack model
1052 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1053 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1054 * F-Mic = 0x1b, HP = 0x19
1057 static hda_nid_t alc880_dac_nids[4] = {
1058 /* front, rear, clfe, rear_surr */
1059 0x02, 0x05, 0x04, 0x03
1062 static hda_nid_t alc880_adc_nids[3] = {
1067 /* The datasheet says the node 0x07 is connected from inputs,
1068 * but it shows zero connection in the real implementation on some devices.
1069 * Note: this is a 915GAV bug, fixed on 915GLV
1071 static hda_nid_t alc880_adc_nids_alt[2] = {
1076 #define ALC880_DIGOUT_NID 0x06
1077 #define ALC880_DIGIN_NID 0x0a
1079 static struct hda_input_mux alc880_capture_source = {
1083 { "Front Mic", 0x3 },
1089 /* channel source setting (2/6 channel selection for 3-stack) */
1091 static struct hda_verb alc880_threestack_ch2_init[] = {
1092 /* set line-in to input, mute it */
1093 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1094 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1095 /* set mic-in to input vref 80%, mute it */
1096 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1097 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1102 static struct hda_verb alc880_threestack_ch6_init[] = {
1103 /* set line-in to output, unmute it */
1104 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1105 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1106 /* set mic-in to output, unmute it */
1107 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1108 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1112 static struct hda_channel_mode alc880_threestack_modes[2] = {
1113 { 2, alc880_threestack_ch2_init },
1114 { 6, alc880_threestack_ch6_init },
1117 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1118 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1119 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1120 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1121 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1122 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1123 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1124 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1125 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1126 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1127 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1128 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1129 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1130 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1131 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1132 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1133 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1134 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1135 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1139 .name = "Channel Mode",
1140 .info = alc_ch_mode_info,
1141 .get = alc_ch_mode_get,
1142 .put = alc_ch_mode_put,
1147 /* capture mixer elements */
1148 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1149 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1150 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1151 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1152 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1153 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1154 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1156 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1157 /* The multiple "Capture Source" controls confuse alsamixer
1158 * So call somewhat different..
1160 /* .name = "Capture Source", */
1161 .name = "Input Source",
1163 .info = alc_mux_enum_info,
1164 .get = alc_mux_enum_get,
1165 .put = alc_mux_enum_put,
1170 /* capture mixer elements (in case NID 0x07 not available) */
1171 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1172 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1173 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1174 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1175 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1178 /* The multiple "Capture Source" controls confuse alsamixer
1179 * So call somewhat different..
1181 /* .name = "Capture Source", */
1182 .name = "Input Source",
1184 .info = alc_mux_enum_info,
1185 .get = alc_mux_enum_get,
1186 .put = alc_mux_enum_put,
1194 * ALC880 5-stack model
1196 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1198 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1199 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1202 /* additional mixers to alc880_three_stack_mixer */
1203 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1204 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1205 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1209 /* channel source setting (6/8 channel selection for 5-stack) */
1211 static struct hda_verb alc880_fivestack_ch6_init[] = {
1212 /* set line-in to input, mute it */
1213 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1214 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1219 static struct hda_verb alc880_fivestack_ch8_init[] = {
1220 /* set line-in to output, unmute it */
1221 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1222 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1226 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1227 { 6, alc880_fivestack_ch6_init },
1228 { 8, alc880_fivestack_ch8_init },
1233 * ALC880 6-stack model
1235 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1236 * Side = 0x05 (0x0f)
1237 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1238 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1241 static hda_nid_t alc880_6st_dac_nids[4] = {
1242 /* front, rear, clfe, rear_surr */
1243 0x02, 0x03, 0x04, 0x05
1246 static struct hda_input_mux alc880_6stack_capture_source = {
1250 { "Front Mic", 0x1 },
1256 /* fixed 8-channels */
1257 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1261 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1262 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1263 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1264 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1265 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1266 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1267 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1268 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1269 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1270 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1271 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1272 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1273 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1274 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1275 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1278 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1279 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1280 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1281 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1284 .name = "Channel Mode",
1285 .info = alc_ch_mode_info,
1286 .get = alc_ch_mode_get,
1287 .put = alc_ch_mode_put,
1296 * W810 has rear IO for:
1299 * Center/LFE (DAC 04)
1302 * The system also has a pair of internal speakers, and a headphone jack.
1303 * These are both connected to Line2 on the codec, hence to DAC 02.
1305 * There is a variable resistor to control the speaker or headphone
1306 * volume. This is a hardware-only device without a software API.
1308 * Plugging headphones in will disable the internal speakers. This is
1309 * implemented in hardware, not via the driver using jack sense. In
1310 * a similar fashion, plugging into the rear socket marked "front" will
1311 * disable both the speakers and headphones.
1313 * For input, there's a microphone jack, and an "audio in" jack.
1314 * These may not do anything useful with this driver yet, because I
1315 * haven't setup any initialization verbs for these yet...
1318 static hda_nid_t alc880_w810_dac_nids[3] = {
1319 /* front, rear/surround, clfe */
1323 /* fixed 6 channels */
1324 static struct hda_channel_mode alc880_w810_modes[1] = {
1328 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1329 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1330 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1331 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1332 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1333 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1334 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1335 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1336 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1337 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1338 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1346 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1347 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1351 static hda_nid_t alc880_z71v_dac_nids[1] = {
1354 #define ALC880_Z71V_HP_DAC 0x03
1356 /* fixed 2 channels */
1357 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1361 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1362 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1363 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1364 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1365 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1366 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1367 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1369 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1375 * ALC880 F1734 model
1377 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1378 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1381 static hda_nid_t alc880_f1734_dac_nids[1] = {
1384 #define ALC880_F1734_HP_DAC 0x02
1386 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1387 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1388 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1389 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1390 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1391 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1392 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1393 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1394 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1398 static struct hda_input_mux alc880_f1734_capture_source = {
1410 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1411 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1412 * Mic = 0x18, Line = 0x1a
1415 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1416 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1418 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1419 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1420 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1421 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1422 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1423 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1424 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1425 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1426 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1427 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1428 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 .name = "Channel Mode",
1436 .info = alc_ch_mode_info,
1437 .get = alc_ch_mode_get,
1438 .put = alc_ch_mode_put,
1444 * ALC880 ASUS W1V model
1446 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1447 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1448 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1451 /* additional mixers to alc880_asus_mixer */
1452 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1453 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1454 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1458 /* additional mixers to alc880_asus_mixer */
1459 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1460 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1461 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1466 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1467 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1468 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1469 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1470 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1471 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1473 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1474 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1475 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1478 /* The multiple "Capture Source" controls confuse alsamixer
1479 * So call somewhat different..
1481 /* .name = "Capture Source", */
1482 .name = "Input Source",
1484 .info = alc_mux_enum_info,
1485 .get = alc_mux_enum_get,
1486 .put = alc_mux_enum_put,
1492 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1493 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1494 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1495 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1496 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1497 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1498 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1499 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1500 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1501 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1502 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1503 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1504 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1506 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1507 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1508 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1509 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1510 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1512 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1513 .name = "Channel Mode",
1514 .info = alc_ch_mode_info,
1515 .get = alc_ch_mode_get,
1516 .put = alc_ch_mode_put,
1521 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1522 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1523 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1524 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1525 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1526 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1527 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1528 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1529 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1530 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1531 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1535 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1536 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1537 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1538 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1539 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1540 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1541 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1546 * virtual master controls
1550 * slave controls for virtual master
1552 static const char *alc_slave_vols[] = {
1553 "Front Playback Volume",
1554 "Surround Playback Volume",
1555 "Center Playback Volume",
1556 "LFE Playback Volume",
1557 "Side Playback Volume",
1558 "Headphone Playback Volume",
1559 "Speaker Playback Volume",
1560 "Mono Playback Volume",
1561 "Line-Out Playback Volume",
1565 static const char *alc_slave_sws[] = {
1566 "Front Playback Switch",
1567 "Surround Playback Switch",
1568 "Center Playback Switch",
1569 "LFE Playback Switch",
1570 "Side Playback Switch",
1571 "Headphone Playback Switch",
1572 "Speaker Playback Switch",
1573 "Mono Playback Switch",
1574 "IEC958 Playback Switch",
1579 * build control elements
1581 static int alc_build_controls(struct hda_codec *codec)
1583 struct alc_spec *spec = codec->spec;
1587 for (i = 0; i < spec->num_mixers; i++) {
1588 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1593 if (spec->multiout.dig_out_nid) {
1594 err = snd_hda_create_spdif_out_ctls(codec,
1595 spec->multiout.dig_out_nid);
1598 err = snd_hda_create_spdif_share_sw(codec,
1602 spec->multiout.share_spdif = 1;
1604 if (spec->dig_in_nid) {
1605 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1610 /* if we have no master control, let's create it */
1611 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1612 unsigned int vmaster_tlv[4];
1613 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1614 HDA_OUTPUT, vmaster_tlv);
1615 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1616 vmaster_tlv, alc_slave_vols);
1620 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1621 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1622 NULL, alc_slave_sws);
1632 * initialize the codec volumes, etc
1636 * generic initialization of ADC, input mixers and output mixers
1638 static struct hda_verb alc880_volume_init_verbs[] = {
1640 * Unmute ADC0-2 and set the default input to mic-in
1642 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1644 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1645 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1646 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1647 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1649 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1651 * Note: PASD motherboards uses the Line In 2 as the input for front
1654 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1655 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1656 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1657 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1658 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1659 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1660 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1661 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1664 * Set up output mixers (0x0c - 0x0f)
1666 /* set vol=0 to output mixers */
1667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1668 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1670 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1671 /* set up input amps for analog loopback */
1672 /* Amp Indices: DAC = 0, mixer = 1 */
1673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1675 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1676 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1677 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1678 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1679 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1680 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1686 * 3-stack pin configuration:
1687 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1689 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1691 * preset connection lists of input pins
1692 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1694 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1695 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1696 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1699 * Set pin mode and muting
1701 /* set front pin widgets 0x14 for output */
1702 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1705 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1706 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1707 /* Mic2 (as headphone out) for HP output */
1708 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1709 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710 /* Line In pin widget for input */
1711 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1712 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1713 /* Line2 (as front mic) pin widget for input and vref at 80% */
1714 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1715 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1716 /* CD pin widget for input */
1717 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1723 * 5-stack pin configuration:
1724 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1725 * line-in/side = 0x1a, f-mic = 0x1b
1727 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1729 * preset connection lists of input pins
1730 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1732 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1733 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1736 * Set pin mode and muting
1738 /* set pin widgets 0x14-0x17 for output */
1739 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1741 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1742 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1743 /* unmute pins for output (no gain on this amp) */
1744 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1745 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1746 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1747 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1749 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1750 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1751 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1752 /* Mic2 (as headphone out) for HP output */
1753 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1754 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1755 /* Line In pin widget for input */
1756 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1757 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1758 /* Line2 (as front mic) pin widget for input and vref at 80% */
1759 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1760 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1761 /* CD pin widget for input */
1762 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1768 * W810 pin configuration:
1769 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1771 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1772 /* hphone/speaker input selector: front DAC */
1773 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1775 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1776 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1777 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1778 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1779 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1780 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1782 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1783 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1789 * Z71V pin configuration:
1790 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1792 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1793 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1795 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1798 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1799 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1800 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1801 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1807 * 6-stack pin configuration:
1808 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1809 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1811 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1812 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1815 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1816 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1817 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1820 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1821 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1823 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1824 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1825 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1826 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1827 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1829 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1830 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1831 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1837 * Uniwill pin configuration:
1838 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1841 static struct hda_verb alc880_uniwill_init_verbs[] = {
1842 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1844 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1847 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1848 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1849 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1850 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1851 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1852 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1853 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1854 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1855 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1856 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1857 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1859 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1860 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1861 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1862 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1863 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1864 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1865 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1866 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1867 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1869 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1870 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1877 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1879 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1880 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1882 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1883 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1885 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1886 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1887 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1890 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1891 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1892 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1893 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1895 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1896 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1897 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1898 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1899 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1902 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1903 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1908 static struct hda_verb alc880_beep_init_verbs[] = {
1909 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1913 /* toggle speaker-output according to the hp-jack state */
1914 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1916 unsigned int present;
1919 present = snd_hda_codec_read(codec, 0x14, 0,
1920 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1921 bits = present ? HDA_AMP_MUTE : 0;
1922 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1923 HDA_AMP_MUTE, bits);
1924 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1925 HDA_AMP_MUTE, bits);
1928 /* auto-toggle front mic */
1929 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1931 unsigned int present;
1934 present = snd_hda_codec_read(codec, 0x18, 0,
1935 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1936 bits = present ? HDA_AMP_MUTE : 0;
1937 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1940 static void alc880_uniwill_automute(struct hda_codec *codec)
1942 alc880_uniwill_hp_automute(codec);
1943 alc880_uniwill_mic_automute(codec);
1946 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1949 /* Looks like the unsol event is incompatible with the standard
1950 * definition. 4bit tag is placed at 28 bit!
1952 switch (res >> 28) {
1953 case ALC880_HP_EVENT:
1954 alc880_uniwill_hp_automute(codec);
1956 case ALC880_MIC_EVENT:
1957 alc880_uniwill_mic_automute(codec);
1962 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1964 unsigned int present;
1967 present = snd_hda_codec_read(codec, 0x14, 0,
1968 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1969 bits = present ? HDA_AMP_MUTE : 0;
1970 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
1973 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1975 unsigned int present;
1977 present = snd_hda_codec_read(codec, 0x21, 0,
1978 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1979 present &= HDA_AMP_VOLMASK;
1980 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1981 HDA_AMP_VOLMASK, present);
1982 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1983 HDA_AMP_VOLMASK, present);
1986 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1989 /* Looks like the unsol event is incompatible with the standard
1990 * definition. 4bit tag is placed at 28 bit!
1992 if ((res >> 28) == ALC880_HP_EVENT)
1993 alc880_uniwill_p53_hp_automute(codec);
1994 if ((res >> 28) == ALC880_DCVOL_EVENT)
1995 alc880_uniwill_p53_dcvol_automute(codec);
1999 * F1734 pin configuration:
2000 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2002 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2003 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2004 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2005 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2006 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2007 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2009 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2010 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2011 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2014 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2015 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2016 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2017 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2018 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2019 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2020 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2021 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2022 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2024 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2025 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2031 * ASUS pin configuration:
2032 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2034 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2035 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2036 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2037 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2038 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2040 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2041 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2042 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2043 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2044 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2045 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2046 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2047 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2049 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2050 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2051 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2052 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2053 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2054 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2055 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2057 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2062 /* Enable GPIO mask and set output */
2063 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2064 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2066 /* Clevo m520g init */
2067 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2068 /* headphone output */
2069 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2072 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2074 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2075 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2077 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2078 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2079 /* Mic1 (rear panel) */
2080 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2081 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2082 /* Mic2 (front panel) */
2083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2087 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2088 /* change to EAPD mode */
2089 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2090 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2095 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2096 /* change to EAPD mode */
2097 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2098 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2100 /* Headphone output */
2101 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2103 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2104 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2106 /* Line In pin widget for input */
2107 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2108 /* CD pin widget for input */
2109 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2110 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2111 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2113 /* change to EAPD mode */
2114 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2115 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2121 * LG m1 express dual
2124 * Rear Line-In/Out (blue): 0x14
2125 * Build-in Mic-In: 0x15
2127 * HP-Out (green): 0x1b
2128 * Mic-In/Out (red): 0x19
2132 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2133 static hda_nid_t alc880_lg_dac_nids[3] = {
2137 /* seems analog CD is not working */
2138 static struct hda_input_mux alc880_lg_capture_source = {
2143 { "Internal Mic", 0x6 },
2147 /* 2,4,6 channel modes */
2148 static struct hda_verb alc880_lg_ch2_init[] = {
2149 /* set line-in and mic-in to input */
2150 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2151 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2155 static struct hda_verb alc880_lg_ch4_init[] = {
2156 /* set line-in to out and mic-in to input */
2157 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2158 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2162 static struct hda_verb alc880_lg_ch6_init[] = {
2163 /* set line-in and mic-in to output */
2164 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2165 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2169 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2170 { 2, alc880_lg_ch2_init },
2171 { 4, alc880_lg_ch4_init },
2172 { 6, alc880_lg_ch6_init },
2175 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2176 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2177 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2178 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2179 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2180 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2181 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2182 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2183 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2184 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2185 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2188 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2189 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2192 .name = "Channel Mode",
2193 .info = alc_ch_mode_info,
2194 .get = alc_ch_mode_get,
2195 .put = alc_ch_mode_put,
2200 static struct hda_verb alc880_lg_init_verbs[] = {
2201 /* set capture source to mic-in */
2202 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2203 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2204 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2205 /* mute all amp mixer inputs */
2206 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2207 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2208 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2209 /* line-in to input */
2210 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2211 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2213 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2214 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2216 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2217 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2218 /* mic-in to input */
2219 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2220 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2221 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2224 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2225 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2231 /* toggle speaker-output according to the hp-jack state */
2232 static void alc880_lg_automute(struct hda_codec *codec)
2234 unsigned int present;
2237 present = snd_hda_codec_read(codec, 0x1b, 0,
2238 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2239 bits = present ? HDA_AMP_MUTE : 0;
2240 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2241 HDA_AMP_MUTE, bits);
2244 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2246 /* Looks like the unsol event is incompatible with the standard
2247 * definition. 4bit tag is placed at 28 bit!
2249 if ((res >> 28) == 0x01)
2250 alc880_lg_automute(codec);
2259 * Built-in Mic-In: 0x19
2265 static struct hda_input_mux alc880_lg_lw_capture_source = {
2269 { "Internal Mic", 0x1 },
2274 #define alc880_lg_lw_modes alc880_threestack_modes
2276 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2277 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2278 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2279 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2280 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2281 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2282 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2283 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2284 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2286 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2288 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2289 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2290 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2293 .name = "Channel Mode",
2294 .info = alc_ch_mode_info,
2295 .get = alc_ch_mode_get,
2296 .put = alc_ch_mode_put,
2301 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2302 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2303 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2304 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2306 /* set capture source to mic-in */
2307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2308 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2309 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2310 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2312 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2313 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2315 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2316 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2317 /* mic-in to input */
2318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2321 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2322 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2324 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2328 /* toggle speaker-output according to the hp-jack state */
2329 static void alc880_lg_lw_automute(struct hda_codec *codec)
2331 unsigned int present;
2334 present = snd_hda_codec_read(codec, 0x1b, 0,
2335 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2336 bits = present ? HDA_AMP_MUTE : 0;
2337 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2338 HDA_AMP_MUTE, bits);
2341 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2343 /* Looks like the unsol event is incompatible with the standard
2344 * definition. 4bit tag is placed at 28 bit!
2346 if ((res >> 28) == 0x01)
2347 alc880_lg_lw_automute(codec);
2350 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2351 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2352 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2355 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2356 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2360 static struct hda_input_mux alc880_medion_rim_capture_source = {
2364 { "Internal Mic", 0x1 },
2368 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2369 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2371 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2372 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2374 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2376 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2377 /* Mic2 (as headphone out) for HP output */
2378 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2379 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2380 /* Internal Speaker */
2381 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2382 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2384 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2385 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2387 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2391 /* toggle speaker-output according to the hp-jack state */
2392 static void alc880_medion_rim_automute(struct hda_codec *codec)
2394 unsigned int present;
2397 present = snd_hda_codec_read(codec, 0x14, 0,
2398 AC_VERB_GET_PIN_SENSE, 0)
2399 & AC_PINSENSE_PRESENCE;
2400 bits = present ? HDA_AMP_MUTE : 0;
2401 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2402 HDA_AMP_MUTE, bits);
2404 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2406 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2409 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2412 /* Looks like the unsol event is incompatible with the standard
2413 * definition. 4bit tag is placed at 28 bit!
2415 if ((res >> 28) == ALC880_HP_EVENT)
2416 alc880_medion_rim_automute(codec);
2419 #ifdef CONFIG_SND_HDA_POWER_SAVE
2420 static struct hda_amp_list alc880_loopbacks[] = {
2421 { 0x0b, HDA_INPUT, 0 },
2422 { 0x0b, HDA_INPUT, 1 },
2423 { 0x0b, HDA_INPUT, 2 },
2424 { 0x0b, HDA_INPUT, 3 },
2425 { 0x0b, HDA_INPUT, 4 },
2429 static struct hda_amp_list alc880_lg_loopbacks[] = {
2430 { 0x0b, HDA_INPUT, 1 },
2431 { 0x0b, HDA_INPUT, 6 },
2432 { 0x0b, HDA_INPUT, 7 },
2441 static int alc_init(struct hda_codec *codec)
2443 struct alc_spec *spec = codec->spec;
2447 if (codec->vendor_id == 0x10ec0888)
2448 alc888_coef_init(codec);
2450 for (i = 0; i < spec->num_init_verbs; i++)
2451 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2453 if (spec->init_hook)
2454 spec->init_hook(codec);
2459 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2461 struct alc_spec *spec = codec->spec;
2463 if (spec->unsol_event)
2464 spec->unsol_event(codec, res);
2467 #ifdef CONFIG_SND_HDA_POWER_SAVE
2468 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2470 struct alc_spec *spec = codec->spec;
2471 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2476 * Analog playback callbacks
2478 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2479 struct hda_codec *codec,
2480 struct snd_pcm_substream *substream)
2482 struct alc_spec *spec = codec->spec;
2483 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2487 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2488 struct hda_codec *codec,
2489 unsigned int stream_tag,
2490 unsigned int format,
2491 struct snd_pcm_substream *substream)
2493 struct alc_spec *spec = codec->spec;
2494 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2495 stream_tag, format, substream);
2498 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2499 struct hda_codec *codec,
2500 struct snd_pcm_substream *substream)
2502 struct alc_spec *spec = codec->spec;
2503 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2509 static int alc880_dig_playback_pcm_open(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_dig_open(codec, &spec->multiout);
2517 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2518 struct hda_codec *codec,
2519 unsigned int stream_tag,
2520 unsigned int format,
2521 struct snd_pcm_substream *substream)
2523 struct alc_spec *spec = codec->spec;
2524 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2525 stream_tag, format, substream);
2528 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2529 struct hda_codec *codec,
2530 struct snd_pcm_substream *substream)
2532 struct alc_spec *spec = codec->spec;
2533 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2539 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2540 struct hda_codec *codec,
2541 unsigned int stream_tag,
2542 unsigned int format,
2543 struct snd_pcm_substream *substream)
2545 struct alc_spec *spec = codec->spec;
2547 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2548 stream_tag, 0, format);
2552 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2553 struct hda_codec *codec,
2554 struct snd_pcm_substream *substream)
2556 struct alc_spec *spec = codec->spec;
2558 snd_hda_codec_cleanup_stream(codec,
2559 spec->adc_nids[substream->number + 1]);
2566 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2570 /* NID is set in alc_build_pcms */
2572 .open = alc880_playback_pcm_open,
2573 .prepare = alc880_playback_pcm_prepare,
2574 .cleanup = alc880_playback_pcm_cleanup
2578 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2582 /* NID is set in alc_build_pcms */
2585 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2589 /* NID is set in alc_build_pcms */
2592 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2593 .substreams = 2, /* can be overridden */
2596 /* NID is set in alc_build_pcms */
2598 .prepare = alc880_alt_capture_pcm_prepare,
2599 .cleanup = alc880_alt_capture_pcm_cleanup
2603 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2607 /* NID is set in alc_build_pcms */
2609 .open = alc880_dig_playback_pcm_open,
2610 .close = alc880_dig_playback_pcm_close,
2611 .prepare = alc880_dig_playback_pcm_prepare
2615 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2619 /* NID is set in alc_build_pcms */
2622 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2623 static struct hda_pcm_stream alc_pcm_null_stream = {
2629 static int alc_build_pcms(struct hda_codec *codec)
2631 struct alc_spec *spec = codec->spec;
2632 struct hda_pcm *info = spec->pcm_rec;
2635 codec->num_pcms = 1;
2636 codec->pcm_info = info;
2638 info->name = spec->stream_name_analog;
2639 if (spec->stream_analog_playback) {
2640 if (snd_BUG_ON(!spec->multiout.dac_nids))
2642 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2643 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2645 if (spec->stream_analog_capture) {
2646 if (snd_BUG_ON(!spec->adc_nids))
2648 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2649 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2652 if (spec->channel_mode) {
2653 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2654 for (i = 0; i < spec->num_channel_mode; i++) {
2655 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2656 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2661 /* SPDIF for stream index #1 */
2662 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2663 codec->num_pcms = 2;
2664 info = spec->pcm_rec + 1;
2665 info->name = spec->stream_name_digital;
2666 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2667 if (spec->multiout.dig_out_nid &&
2668 spec->stream_digital_playback) {
2669 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2670 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2672 if (spec->dig_in_nid &&
2673 spec->stream_digital_capture) {
2674 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2675 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2677 /* FIXME: do we need this for all Realtek codec models? */
2678 codec->spdif_status_reset = 1;
2681 /* If the use of more than one ADC is requested for the current
2682 * model, configure a second analog capture-only PCM.
2684 /* Additional Analaog capture for index #2 */
2685 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2686 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2687 codec->num_pcms = 3;
2688 info = spec->pcm_rec + 2;
2689 info->name = spec->stream_name_analog;
2690 if (spec->alt_dac_nid) {
2691 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2692 *spec->stream_analog_alt_playback;
2693 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2696 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2697 alc_pcm_null_stream;
2698 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2700 if (spec->num_adc_nids > 1) {
2701 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2702 *spec->stream_analog_alt_capture;
2703 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2705 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2706 spec->num_adc_nids - 1;
2708 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2709 alc_pcm_null_stream;
2710 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2717 static void alc_free(struct hda_codec *codec)
2719 struct alc_spec *spec = codec->spec;
2725 if (spec->kctl_alloc) {
2726 for (i = 0; i < spec->num_kctl_used; i++)
2727 kfree(spec->kctl_alloc[i].name);
2728 kfree(spec->kctl_alloc);
2731 codec->spec = NULL; /* to be sure */
2736 static struct hda_codec_ops alc_patch_ops = {
2737 .build_controls = alc_build_controls,
2738 .build_pcms = alc_build_pcms,
2741 .unsol_event = alc_unsol_event,
2742 #ifdef CONFIG_SND_HDA_POWER_SAVE
2743 .check_power_status = alc_check_power_status,
2749 * Test configuration for debugging
2751 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2754 #ifdef CONFIG_SND_DEBUG
2755 static hda_nid_t alc880_test_dac_nids[4] = {
2756 0x02, 0x03, 0x04, 0x05
2759 static struct hda_input_mux alc880_test_capture_source = {
2768 { "Surround", 0x6 },
2772 static struct hda_channel_mode alc880_test_modes[4] = {
2779 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2780 struct snd_ctl_elem_info *uinfo)
2782 static char *texts[] = {
2783 "N/A", "Line Out", "HP Out",
2784 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2786 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2788 uinfo->value.enumerated.items = 8;
2789 if (uinfo->value.enumerated.item >= 8)
2790 uinfo->value.enumerated.item = 7;
2791 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2795 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2796 struct snd_ctl_elem_value *ucontrol)
2798 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2799 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2800 unsigned int pin_ctl, item = 0;
2802 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2803 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2804 if (pin_ctl & AC_PINCTL_OUT_EN) {
2805 if (pin_ctl & AC_PINCTL_HP_EN)
2809 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2810 switch (pin_ctl & AC_PINCTL_VREFEN) {
2811 case AC_PINCTL_VREF_HIZ: item = 3; break;
2812 case AC_PINCTL_VREF_50: item = 4; break;
2813 case AC_PINCTL_VREF_GRD: item = 5; break;
2814 case AC_PINCTL_VREF_80: item = 6; break;
2815 case AC_PINCTL_VREF_100: item = 7; break;
2818 ucontrol->value.enumerated.item[0] = item;
2822 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2823 struct snd_ctl_elem_value *ucontrol)
2825 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2826 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2827 static unsigned int ctls[] = {
2828 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2829 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2830 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2831 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2832 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2833 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2835 unsigned int old_ctl, new_ctl;
2837 old_ctl = snd_hda_codec_read(codec, nid, 0,
2838 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2839 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2840 if (old_ctl != new_ctl) {
2842 snd_hda_codec_write_cache(codec, nid, 0,
2843 AC_VERB_SET_PIN_WIDGET_CONTROL,
2845 val = ucontrol->value.enumerated.item[0] >= 3 ?
2847 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2854 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2855 struct snd_ctl_elem_info *uinfo)
2857 static char *texts[] = {
2858 "Front", "Surround", "CLFE", "Side"
2860 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2862 uinfo->value.enumerated.items = 4;
2863 if (uinfo->value.enumerated.item >= 4)
2864 uinfo->value.enumerated.item = 3;
2865 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2869 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2870 struct snd_ctl_elem_value *ucontrol)
2872 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2873 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2876 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2877 ucontrol->value.enumerated.item[0] = sel & 3;
2881 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2882 struct snd_ctl_elem_value *ucontrol)
2884 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2885 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2888 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2889 if (ucontrol->value.enumerated.item[0] != sel) {
2890 sel = ucontrol->value.enumerated.item[0] & 3;
2891 snd_hda_codec_write_cache(codec, nid, 0,
2892 AC_VERB_SET_CONNECT_SEL, sel);
2898 #define PIN_CTL_TEST(xname,nid) { \
2899 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2901 .info = alc_test_pin_ctl_info, \
2902 .get = alc_test_pin_ctl_get, \
2903 .put = alc_test_pin_ctl_put, \
2904 .private_value = nid \
2907 #define PIN_SRC_TEST(xname,nid) { \
2908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2910 .info = alc_test_pin_src_info, \
2911 .get = alc_test_pin_src_get, \
2912 .put = alc_test_pin_src_put, \
2913 .private_value = nid \
2916 static struct snd_kcontrol_new alc880_test_mixer[] = {
2917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2918 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2919 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2920 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2921 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2922 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2923 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2924 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2925 PIN_CTL_TEST("Front Pin Mode", 0x14),
2926 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2927 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2928 PIN_CTL_TEST("Side Pin Mode", 0x17),
2929 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2930 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2931 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2932 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2933 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2934 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2935 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2936 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2937 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2938 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2939 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2940 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2941 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2942 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2943 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2944 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2945 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2946 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2948 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2949 .name = "Channel Mode",
2950 .info = alc_ch_mode_info,
2951 .get = alc_ch_mode_get,
2952 .put = alc_ch_mode_put,
2957 static struct hda_verb alc880_test_init_verbs[] = {
2958 /* Unmute inputs of 0x0c - 0x0f */
2959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2962 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2965 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2966 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2967 /* Vol output for 0x0c-0x0f */
2968 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2969 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2971 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2972 /* Set output pins 0x14-0x17 */
2973 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2974 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2975 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2976 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2977 /* Unmute output pins 0x14-0x17 */
2978 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2979 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2980 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2981 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2982 /* Set input pins 0x18-0x1c */
2983 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2984 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2985 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2987 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2988 /* Mute input pins 0x18-0x1b */
2989 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2990 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2991 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2992 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2995 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2996 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2997 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2998 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2999 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3000 /* Analog input/passthru */
3001 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3002 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3003 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3004 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3005 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3013 static const char *alc880_models[ALC880_MODEL_LAST] = {
3014 [ALC880_3ST] = "3stack",
3015 [ALC880_TCL_S700] = "tcl",
3016 [ALC880_3ST_DIG] = "3stack-digout",
3017 [ALC880_CLEVO] = "clevo",
3018 [ALC880_5ST] = "5stack",
3019 [ALC880_5ST_DIG] = "5stack-digout",
3020 [ALC880_W810] = "w810",
3021 [ALC880_Z71V] = "z71v",
3022 [ALC880_6ST] = "6stack",
3023 [ALC880_6ST_DIG] = "6stack-digout",
3024 [ALC880_ASUS] = "asus",
3025 [ALC880_ASUS_W1V] = "asus-w1v",
3026 [ALC880_ASUS_DIG] = "asus-dig",
3027 [ALC880_ASUS_DIG2] = "asus-dig2",
3028 [ALC880_UNIWILL_DIG] = "uniwill",
3029 [ALC880_UNIWILL_P53] = "uniwill-p53",
3030 [ALC880_FUJITSU] = "fujitsu",
3031 [ALC880_F1734] = "F1734",
3033 [ALC880_LG_LW] = "lg-lw",
3034 [ALC880_MEDION_RIM] = "medion",
3035 #ifdef CONFIG_SND_DEBUG
3036 [ALC880_TEST] = "test",
3038 [ALC880_AUTO] = "auto",
3041 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3042 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3043 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3044 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3045 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3046 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3047 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3048 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3049 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3050 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3051 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3052 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3053 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3054 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3055 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3056 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3057 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3058 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3059 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3060 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3061 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3062 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3063 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3064 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3065 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3066 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3067 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3068 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3069 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3070 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3071 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3072 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3073 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3074 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3075 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3076 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3077 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3078 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3079 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3080 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3081 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3082 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3083 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3084 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3085 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3086 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3087 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3088 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3089 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3090 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3091 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3092 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3093 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3094 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3095 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3096 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3097 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3098 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3099 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3100 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3101 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3102 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3103 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3104 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3105 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3106 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3107 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3108 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3109 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3110 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3111 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3112 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3117 * ALC880 codec presets
3119 static struct alc_config_preset alc880_presets[] = {
3121 .mixers = { alc880_three_stack_mixer },
3122 .init_verbs = { alc880_volume_init_verbs,
3123 alc880_pin_3stack_init_verbs },
3124 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3125 .dac_nids = alc880_dac_nids,
3126 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3127 .channel_mode = alc880_threestack_modes,
3129 .input_mux = &alc880_capture_source,
3131 [ALC880_3ST_DIG] = {
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 .dig_out_nid = ALC880_DIGOUT_NID,
3138 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3139 .channel_mode = alc880_threestack_modes,
3141 .input_mux = &alc880_capture_source,
3143 [ALC880_TCL_S700] = {
3144 .mixers = { alc880_tcl_s700_mixer },
3145 .init_verbs = { alc880_volume_init_verbs,
3146 alc880_pin_tcl_S700_init_verbs,
3147 alc880_gpio2_init_verbs },
3148 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3149 .dac_nids = alc880_dac_nids,
3151 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3152 .channel_mode = alc880_2_jack_modes,
3153 .input_mux = &alc880_capture_source,
3156 .mixers = { alc880_three_stack_mixer,
3157 alc880_five_stack_mixer},
3158 .init_verbs = { alc880_volume_init_verbs,
3159 alc880_pin_5stack_init_verbs },
3160 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3161 .dac_nids = alc880_dac_nids,
3162 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3163 .channel_mode = alc880_fivestack_modes,
3164 .input_mux = &alc880_capture_source,
3166 [ALC880_5ST_DIG] = {
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 .dig_out_nid = ALC880_DIGOUT_NID,
3174 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3175 .channel_mode = alc880_fivestack_modes,
3176 .input_mux = &alc880_capture_source,
3179 .mixers = { alc880_six_stack_mixer },
3180 .init_verbs = { alc880_volume_init_verbs,
3181 alc880_pin_6stack_init_verbs },
3182 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3183 .dac_nids = alc880_6st_dac_nids,
3184 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3185 .channel_mode = alc880_sixstack_modes,
3186 .input_mux = &alc880_6stack_capture_source,
3188 [ALC880_6ST_DIG] = {
3189 .mixers = { alc880_six_stack_mixer },
3190 .init_verbs = { alc880_volume_init_verbs,
3191 alc880_pin_6stack_init_verbs },
3192 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3193 .dac_nids = alc880_6st_dac_nids,
3194 .dig_out_nid = ALC880_DIGOUT_NID,
3195 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3196 .channel_mode = alc880_sixstack_modes,
3197 .input_mux = &alc880_6stack_capture_source,
3200 .mixers = { alc880_w810_base_mixer },
3201 .init_verbs = { alc880_volume_init_verbs,
3202 alc880_pin_w810_init_verbs,
3203 alc880_gpio2_init_verbs },
3204 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3205 .dac_nids = alc880_w810_dac_nids,
3206 .dig_out_nid = ALC880_DIGOUT_NID,
3207 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3208 .channel_mode = alc880_w810_modes,
3209 .input_mux = &alc880_capture_source,
3212 .mixers = { alc880_z71v_mixer },
3213 .init_verbs = { alc880_volume_init_verbs,
3214 alc880_pin_z71v_init_verbs },
3215 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3216 .dac_nids = alc880_z71v_dac_nids,
3217 .dig_out_nid = ALC880_DIGOUT_NID,
3219 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3220 .channel_mode = alc880_2_jack_modes,
3221 .input_mux = &alc880_capture_source,
3224 .mixers = { alc880_f1734_mixer },
3225 .init_verbs = { alc880_volume_init_verbs,
3226 alc880_pin_f1734_init_verbs },
3227 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3228 .dac_nids = alc880_f1734_dac_nids,
3230 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3231 .channel_mode = alc880_2_jack_modes,
3232 .input_mux = &alc880_f1734_capture_source,
3233 .unsol_event = alc880_uniwill_p53_unsol_event,
3234 .init_hook = alc880_uniwill_p53_hp_automute,
3237 .mixers = { alc880_asus_mixer },
3238 .init_verbs = { alc880_volume_init_verbs,
3239 alc880_pin_asus_init_verbs,
3240 alc880_gpio1_init_verbs },
3241 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3242 .dac_nids = alc880_asus_dac_nids,
3243 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3244 .channel_mode = alc880_asus_modes,
3246 .input_mux = &alc880_capture_source,
3248 [ALC880_ASUS_DIG] = {
3249 .mixers = { alc880_asus_mixer },
3250 .init_verbs = { alc880_volume_init_verbs,
3251 alc880_pin_asus_init_verbs,
3252 alc880_gpio1_init_verbs },
3253 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3254 .dac_nids = alc880_asus_dac_nids,
3255 .dig_out_nid = ALC880_DIGOUT_NID,
3256 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3257 .channel_mode = alc880_asus_modes,
3259 .input_mux = &alc880_capture_source,
3261 [ALC880_ASUS_DIG2] = {
3262 .mixers = { alc880_asus_mixer },
3263 .init_verbs = { alc880_volume_init_verbs,
3264 alc880_pin_asus_init_verbs,
3265 alc880_gpio2_init_verbs }, /* use GPIO2 */
3266 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3267 .dac_nids = alc880_asus_dac_nids,
3268 .dig_out_nid = ALC880_DIGOUT_NID,
3269 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3270 .channel_mode = alc880_asus_modes,
3272 .input_mux = &alc880_capture_source,
3274 [ALC880_ASUS_W1V] = {
3275 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3276 .init_verbs = { alc880_volume_init_verbs,
3277 alc880_pin_asus_init_verbs,
3278 alc880_gpio1_init_verbs },
3279 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3280 .dac_nids = alc880_asus_dac_nids,
3281 .dig_out_nid = ALC880_DIGOUT_NID,
3282 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3283 .channel_mode = alc880_asus_modes,
3285 .input_mux = &alc880_capture_source,
3287 [ALC880_UNIWILL_DIG] = {
3288 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3289 .init_verbs = { alc880_volume_init_verbs,
3290 alc880_pin_asus_init_verbs },
3291 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3292 .dac_nids = alc880_asus_dac_nids,
3293 .dig_out_nid = ALC880_DIGOUT_NID,
3294 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3295 .channel_mode = alc880_asus_modes,
3297 .input_mux = &alc880_capture_source,
3299 [ALC880_UNIWILL] = {
3300 .mixers = { alc880_uniwill_mixer },
3301 .init_verbs = { alc880_volume_init_verbs,
3302 alc880_uniwill_init_verbs },
3303 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3304 .dac_nids = alc880_asus_dac_nids,
3305 .dig_out_nid = ALC880_DIGOUT_NID,
3306 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3307 .channel_mode = alc880_threestack_modes,
3309 .input_mux = &alc880_capture_source,
3310 .unsol_event = alc880_uniwill_unsol_event,
3311 .init_hook = alc880_uniwill_automute,
3313 [ALC880_UNIWILL_P53] = {
3314 .mixers = { alc880_uniwill_p53_mixer },
3315 .init_verbs = { alc880_volume_init_verbs,
3316 alc880_uniwill_p53_init_verbs },
3317 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3318 .dac_nids = alc880_asus_dac_nids,
3319 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3320 .channel_mode = alc880_threestack_modes,
3321 .input_mux = &alc880_capture_source,
3322 .unsol_event = alc880_uniwill_p53_unsol_event,
3323 .init_hook = alc880_uniwill_p53_hp_automute,
3325 [ALC880_FUJITSU] = {
3326 .mixers = { alc880_fujitsu_mixer,
3327 alc880_pcbeep_mixer, },
3328 .init_verbs = { alc880_volume_init_verbs,
3329 alc880_uniwill_p53_init_verbs,
3330 alc880_beep_init_verbs },
3331 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3332 .dac_nids = alc880_dac_nids,
3333 .dig_out_nid = ALC880_DIGOUT_NID,
3334 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3335 .channel_mode = alc880_2_jack_modes,
3336 .input_mux = &alc880_capture_source,
3337 .unsol_event = alc880_uniwill_p53_unsol_event,
3338 .init_hook = alc880_uniwill_p53_hp_automute,
3341 .mixers = { alc880_three_stack_mixer },
3342 .init_verbs = { alc880_volume_init_verbs,
3343 alc880_pin_clevo_init_verbs },
3344 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3345 .dac_nids = alc880_dac_nids,
3347 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3348 .channel_mode = alc880_threestack_modes,
3350 .input_mux = &alc880_capture_source,
3353 .mixers = { alc880_lg_mixer },
3354 .init_verbs = { alc880_volume_init_verbs,
3355 alc880_lg_init_verbs },
3356 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3357 .dac_nids = alc880_lg_dac_nids,
3358 .dig_out_nid = ALC880_DIGOUT_NID,
3359 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3360 .channel_mode = alc880_lg_ch_modes,
3362 .input_mux = &alc880_lg_capture_source,
3363 .unsol_event = alc880_lg_unsol_event,
3364 .init_hook = alc880_lg_automute,
3365 #ifdef CONFIG_SND_HDA_POWER_SAVE
3366 .loopbacks = alc880_lg_loopbacks,
3370 .mixers = { alc880_lg_lw_mixer },
3371 .init_verbs = { alc880_volume_init_verbs,
3372 alc880_lg_lw_init_verbs },
3373 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3374 .dac_nids = alc880_dac_nids,
3375 .dig_out_nid = ALC880_DIGOUT_NID,
3376 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3377 .channel_mode = alc880_lg_lw_modes,
3378 .input_mux = &alc880_lg_lw_capture_source,
3379 .unsol_event = alc880_lg_lw_unsol_event,
3380 .init_hook = alc880_lg_lw_automute,
3382 [ALC880_MEDION_RIM] = {
3383 .mixers = { alc880_medion_rim_mixer },
3384 .init_verbs = { alc880_volume_init_verbs,
3385 alc880_medion_rim_init_verbs,
3386 alc_gpio2_init_verbs },
3387 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3388 .dac_nids = alc880_dac_nids,
3389 .dig_out_nid = ALC880_DIGOUT_NID,
3390 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3391 .channel_mode = alc880_2_jack_modes,
3392 .input_mux = &alc880_medion_rim_capture_source,
3393 .unsol_event = alc880_medion_rim_unsol_event,
3394 .init_hook = alc880_medion_rim_automute,
3396 #ifdef CONFIG_SND_DEBUG
3398 .mixers = { alc880_test_mixer },
3399 .init_verbs = { alc880_test_init_verbs },
3400 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3401 .dac_nids = alc880_test_dac_nids,
3402 .dig_out_nid = ALC880_DIGOUT_NID,
3403 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3404 .channel_mode = alc880_test_modes,
3405 .input_mux = &alc880_test_capture_source,
3411 * Automatic parse of I/O pins from the BIOS configuration
3414 #define NUM_CONTROL_ALLOC 32
3415 #define NUM_VERB_ALLOC 32
3419 ALC_CTL_WIDGET_MUTE,
3422 static struct snd_kcontrol_new alc880_control_templates[] = {
3423 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3424 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3425 HDA_BIND_MUTE(NULL, 0, 0, 0),
3428 /* add dynamic controls */
3429 static int add_control(struct alc_spec *spec, int type, const char *name,
3432 struct snd_kcontrol_new *knew;
3434 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3435 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3437 /* array + terminator */
3438 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3441 if (spec->kctl_alloc) {
3442 memcpy(knew, spec->kctl_alloc,
3443 sizeof(*knew) * spec->num_kctl_alloc);
3444 kfree(spec->kctl_alloc);
3446 spec->kctl_alloc = knew;
3447 spec->num_kctl_alloc = num;
3450 knew = &spec->kctl_alloc[spec->num_kctl_used];
3451 *knew = alc880_control_templates[type];
3452 knew->name = kstrdup(name, GFP_KERNEL);
3455 knew->private_value = val;
3456 spec->num_kctl_used++;
3460 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3461 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3462 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3463 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3464 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3465 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3466 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3467 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3468 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3469 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3470 #define ALC880_PIN_CD_NID 0x1c
3472 /* fill in the dac_nids table from the parsed pin configuration */
3473 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3474 const struct auto_pin_cfg *cfg)
3480 memset(assigned, 0, sizeof(assigned));
3481 spec->multiout.dac_nids = spec->private_dac_nids;
3483 /* check the pins hardwired to audio widget */
3484 for (i = 0; i < cfg->line_outs; i++) {
3485 nid = cfg->line_out_pins[i];
3486 if (alc880_is_fixed_pin(nid)) {
3487 int idx = alc880_fixed_pin_idx(nid);
3488 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3492 /* left pins can be connect to any audio widget */
3493 for (i = 0; i < cfg->line_outs; i++) {
3494 nid = cfg->line_out_pins[i];
3495 if (alc880_is_fixed_pin(nid))
3497 /* search for an empty channel */
3498 for (j = 0; j < cfg->line_outs; j++) {
3500 spec->multiout.dac_nids[i] =
3501 alc880_idx_to_dac(j);
3507 spec->multiout.num_dacs = cfg->line_outs;
3511 /* add playback controls from the parsed DAC table */
3512 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3513 const struct auto_pin_cfg *cfg)
3516 static const char *chname[4] = {
3517 "Front", "Surround", NULL /*CLFE*/, "Side"
3522 for (i = 0; i < cfg->line_outs; i++) {
3523 if (!spec->multiout.dac_nids[i])
3525 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3528 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3529 "Center Playback Volume",
3530 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3534 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3535 "LFE Playback Volume",
3536 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3540 err = add_control(spec, ALC_CTL_BIND_MUTE,
3541 "Center Playback Switch",
3542 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3546 err = add_control(spec, ALC_CTL_BIND_MUTE,
3547 "LFE Playback Switch",
3548 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3553 sprintf(name, "%s Playback Volume", chname[i]);
3554 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3555 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3559 sprintf(name, "%s Playback Switch", chname[i]);
3560 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3561 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3570 /* add playback controls for speaker and HP outputs */
3571 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3581 if (alc880_is_fixed_pin(pin)) {
3582 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3583 /* specify the DAC as the extra output */
3584 if (!spec->multiout.hp_nid)
3585 spec->multiout.hp_nid = nid;
3587 spec->multiout.extra_out_nid[0] = nid;
3588 /* control HP volume/switch on the output mixer amp */
3589 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3590 sprintf(name, "%s Playback Volume", pfx);
3591 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3592 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3595 sprintf(name, "%s Playback Switch", pfx);
3596 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3597 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3600 } else if (alc880_is_multi_pin(pin)) {
3601 /* set manual connection */
3602 /* we have only a switch on HP-out PIN */
3603 sprintf(name, "%s Playback Switch", pfx);
3604 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3605 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3612 /* create input playback/capture controls for the given pin */
3613 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3614 const char *ctlname,
3615 int idx, hda_nid_t mix_nid)
3620 sprintf(name, "%s Playback Volume", ctlname);
3621 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3622 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3625 sprintf(name, "%s Playback Switch", ctlname);
3626 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3627 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3633 /* create playback/capture controls for input pins */
3634 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3635 const struct auto_pin_cfg *cfg)
3637 struct hda_input_mux *imux = &spec->private_imux;
3640 for (i = 0; i < AUTO_PIN_LAST; i++) {
3641 if (alc880_is_input_pin(cfg->input_pins[i])) {
3642 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3643 err = new_analog_input(spec, cfg->input_pins[i],
3644 auto_pin_cfg_labels[i],
3648 imux->items[imux->num_items].label =
3649 auto_pin_cfg_labels[i];
3650 imux->items[imux->num_items].index =
3651 alc880_input_pin_idx(cfg->input_pins[i]);
3658 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3659 unsigned int pin_type)
3661 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3664 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3668 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3669 hda_nid_t nid, int pin_type,
3672 alc_set_pin_output(codec, nid, pin_type);
3673 /* need the manual connection? */
3674 if (alc880_is_multi_pin(nid)) {
3675 struct alc_spec *spec = codec->spec;
3676 int idx = alc880_multi_pin_idx(nid);
3677 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3678 AC_VERB_SET_CONNECT_SEL,
3679 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3683 static int get_pin_type(int line_out_type)
3685 if (line_out_type == AUTO_PIN_HP_OUT)
3691 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3693 struct alc_spec *spec = codec->spec;
3696 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3697 for (i = 0; i < spec->autocfg.line_outs; i++) {
3698 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3699 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3700 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3704 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3706 struct alc_spec *spec = codec->spec;
3709 pin = spec->autocfg.speaker_pins[0];
3710 if (pin) /* connect to front */
3711 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3712 pin = spec->autocfg.hp_pins[0];
3713 if (pin) /* connect to front */
3714 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3717 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3719 struct alc_spec *spec = codec->spec;
3722 for (i = 0; i < AUTO_PIN_LAST; i++) {
3723 hda_nid_t nid = spec->autocfg.input_pins[i];
3724 if (alc880_is_input_pin(nid)) {
3725 snd_hda_codec_write(codec, nid, 0,
3726 AC_VERB_SET_PIN_WIDGET_CONTROL,
3727 i <= AUTO_PIN_FRONT_MIC ?
3728 PIN_VREF80 : PIN_IN);
3729 if (nid != ALC880_PIN_CD_NID)
3730 snd_hda_codec_write(codec, nid, 0,
3731 AC_VERB_SET_AMP_GAIN_MUTE,
3737 /* parse the BIOS configuration and set up the alc_spec */
3738 /* return 1 if successful, 0 if the proper config is not found,
3739 * or a negative error code
3741 static int alc880_parse_auto_config(struct hda_codec *codec)
3743 struct alc_spec *spec = codec->spec;
3745 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3747 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3751 if (!spec->autocfg.line_outs)
3752 return 0; /* can't find valid BIOS pin config */
3754 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3757 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3760 err = alc880_auto_create_extra_out(spec,
3761 spec->autocfg.speaker_pins[0],
3765 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3769 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3773 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3775 if (spec->autocfg.dig_out_pin)
3776 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3777 if (spec->autocfg.dig_in_pin)
3778 spec->dig_in_nid = ALC880_DIGIN_NID;
3780 if (spec->kctl_alloc)
3781 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3783 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3785 spec->num_mux_defs = 1;
3786 spec->input_mux = &spec->private_imux;
3791 /* additional initialization for auto-configuration model */
3792 static void alc880_auto_init(struct hda_codec *codec)
3794 struct alc_spec *spec = codec->spec;
3795 alc880_auto_init_multi_out(codec);
3796 alc880_auto_init_extra_out(codec);
3797 alc880_auto_init_analog_input(codec);
3798 if (spec->unsol_event)
3799 alc_sku_automute(codec);
3803 * OK, here we have finally the patch for ALC880
3806 static int patch_alc880(struct hda_codec *codec)
3808 struct alc_spec *spec;
3812 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3818 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3821 if (board_config < 0) {
3822 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3823 "trying auto-probe from BIOS...\n");
3824 board_config = ALC880_AUTO;
3827 if (board_config == ALC880_AUTO) {
3828 /* automatic parse from the BIOS config */
3829 err = alc880_parse_auto_config(codec);
3835 "hda_codec: Cannot set up configuration "
3836 "from BIOS. Using 3-stack mode...\n");
3837 board_config = ALC880_3ST;
3841 if (board_config != ALC880_AUTO)
3842 setup_preset(spec, &alc880_presets[board_config]);
3844 spec->stream_name_analog = "ALC880 Analog";
3845 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3846 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3847 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3849 spec->stream_name_digital = "ALC880 Digital";
3850 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3851 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3853 if (!spec->adc_nids && spec->input_mux) {
3854 /* check whether NID 0x07 is valid */
3855 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3857 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3858 if (wcap != AC_WID_AUD_IN) {
3859 spec->adc_nids = alc880_adc_nids_alt;
3860 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3861 spec->mixers[spec->num_mixers] =
3862 alc880_capture_alt_mixer;
3865 spec->adc_nids = alc880_adc_nids;
3866 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3867 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3872 spec->vmaster_nid = 0x0c;
3874 codec->patch_ops = alc_patch_ops;
3875 if (board_config == ALC880_AUTO)
3876 spec->init_hook = alc880_auto_init;
3877 #ifdef CONFIG_SND_HDA_POWER_SAVE
3878 if (!spec->loopback.amplist)
3879 spec->loopback.amplist = alc880_loopbacks;
3890 static hda_nid_t alc260_dac_nids[1] = {
3895 static hda_nid_t alc260_adc_nids[1] = {
3900 static hda_nid_t alc260_adc_nids_alt[1] = {
3905 static hda_nid_t alc260_hp_adc_nids[2] = {
3910 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3911 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3913 static hda_nid_t alc260_dual_adc_nids[2] = {
3918 #define ALC260_DIGOUT_NID 0x03
3919 #define ALC260_DIGIN_NID 0x06
3921 static struct hda_input_mux alc260_capture_source = {
3925 { "Front Mic", 0x1 },
3931 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3932 * headphone jack and the internal CD lines since these are the only pins at
3933 * which audio can appear. For flexibility, also allow the option of
3934 * recording the mixer output on the second ADC (ADC0 doesn't have a
3935 * connection to the mixer output).
3937 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3941 { "Mic/Line", 0x0 },
3943 { "Headphone", 0x2 },
3949 { "Mic/Line", 0x0 },
3951 { "Headphone", 0x2 },
3958 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3959 * the Fujitsu S702x, but jacks are marked differently.
3961 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3968 { "Headphone", 0x5 },
3977 { "Headphone", 0x6 },
3983 * This is just place-holder, so there's something for alc_build_pcms to look
3984 * at when it calculates the maximum number of channels. ALC260 has no mixer
3985 * element which allows changing the channel mode, so the verb list is
3988 static struct hda_channel_mode alc260_modes[1] = {
3993 /* Mixer combinations
3995 * basic: base_output + input + pc_beep + capture
3996 * HP: base_output + input + capture_alt
3997 * HP_3013: hp_3013 + input + capture
3998 * fujitsu: fujitsu + capture
3999 * acer: acer + capture
4002 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4003 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4004 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4005 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4006 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4007 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4008 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4012 static struct snd_kcontrol_new alc260_input_mixer[] = {
4013 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4014 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4015 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4016 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4018 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4019 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4020 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4024 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4025 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4026 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4030 /* update HP, line and mono out pins according to the master switch */
4031 static void alc260_hp_master_update(struct hda_codec *codec,
4032 hda_nid_t hp, hda_nid_t line,
4035 struct alc_spec *spec = codec->spec;
4036 unsigned int val = spec->master_sw ? PIN_HP : 0;
4037 /* change HP and line-out pins */
4038 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4040 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4042 /* mono (speaker) depending on the HP jack sense */
4043 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4044 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4048 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4049 struct snd_ctl_elem_value *ucontrol)
4051 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4052 struct alc_spec *spec = codec->spec;
4053 *ucontrol->value.integer.value = spec->master_sw;
4057 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4058 struct snd_ctl_elem_value *ucontrol)
4060 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4061 struct alc_spec *spec = codec->spec;
4062 int val = !!*ucontrol->value.integer.value;
4063 hda_nid_t hp, line, mono;
4065 if (val == spec->master_sw)
4067 spec->master_sw = val;
4068 hp = (kcontrol->private_value >> 16) & 0xff;
4069 line = (kcontrol->private_value >> 8) & 0xff;
4070 mono = kcontrol->private_value & 0xff;
4071 alc260_hp_master_update(codec, hp, line, mono);
4075 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4077 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4078 .name = "Master Playback Switch",
4079 .info = snd_ctl_boolean_mono_info,
4080 .get = alc260_hp_master_sw_get,
4081 .put = alc260_hp_master_sw_put,
4082 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4084 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4085 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4086 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4087 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4088 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4090 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4094 static struct hda_verb alc260_hp_unsol_verbs[] = {
4095 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4099 static void alc260_hp_automute(struct hda_codec *codec)
4101 struct alc_spec *spec = codec->spec;
4102 unsigned int present;
4104 present = snd_hda_codec_read(codec, 0x10, 0,
4105 AC_VERB_GET_PIN_SENSE, 0);
4106 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4107 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4110 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4112 if ((res >> 26) == ALC880_HP_EVENT)
4113 alc260_hp_automute(codec);
4116 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4119 .name = "Master Playback Switch",
4120 .info = snd_ctl_boolean_mono_info,
4121 .get = alc260_hp_master_sw_get,
4122 .put = alc260_hp_master_sw_put,
4123 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4125 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4126 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4127 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4128 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4129 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4130 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4131 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4132 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4136 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4137 .ops = &snd_hda_bind_vol,
4139 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4140 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4141 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4146 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4147 .ops = &snd_hda_bind_sw,
4149 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4150 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4155 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4156 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4157 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4158 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4163 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4164 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4168 static void alc260_hp_3013_automute(struct hda_codec *codec)
4170 struct alc_spec *spec = codec->spec;
4171 unsigned int present;
4173 present = snd_hda_codec_read(codec, 0x15, 0,
4174 AC_VERB_GET_PIN_SENSE, 0);
4175 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4176 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4179 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4182 if ((res >> 26) == ALC880_HP_EVENT)
4183 alc260_hp_3013_automute(codec);
4186 static void alc260_hp_3012_automute(struct hda_codec *codec)
4188 unsigned int present, bits;
4190 present = snd_hda_codec_read(codec, 0x10, 0,
4191 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4193 bits = present ? 0 : PIN_OUT;
4194 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4196 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4198 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4202 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4205 if ((res >> 26) == ALC880_HP_EVENT)
4206 alc260_hp_3012_automute(codec);
4209 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4210 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4212 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4214 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4215 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4216 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4217 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4218 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4219 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4220 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4221 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4222 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4223 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4224 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4228 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4229 * versions of the ALC260 don't act on requests to enable mic bias from NID
4230 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4231 * datasheet doesn't mention this restriction. At this stage it's not clear
4232 * whether this behaviour is intentional or is a hardware bug in chip
4233 * revisions available in early 2006. Therefore for now allow the
4234 * "Headphone Jack Mode" control to span all choices, but if it turns out
4235 * that the lack of mic bias for this NID is intentional we could change the
4236 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4238 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4239 * don't appear to make the mic bias available from the "line" jack, even
4240 * though the NID used for this jack (0x14) can supply it. The theory is
4241 * that perhaps Acer have included blocking capacitors between the ALC260
4242 * and the output jack. If this turns out to be the case for all such
4243 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4244 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4246 * The C20x Tablet series have a mono internal speaker which is controlled
4247 * via the chip's Mono sum widget and pin complex, so include the necessary
4248 * controls for such models. On models without a "mono speaker" the control
4249 * won't do anything.
4251 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4252 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4253 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4254 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4255 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4257 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4259 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4260 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4261 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4262 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4263 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4264 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4265 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4266 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4267 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4268 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4272 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4273 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4275 static struct snd_kcontrol_new alc260_will_mixer[] = {
4276 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4277 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4279 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4280 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4281 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4282 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4283 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4284 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4285 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4286 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4287 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4291 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4292 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4294 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4295 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4296 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4297 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4298 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4299 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4300 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4301 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4302 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4303 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4304 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4308 /* capture mixer elements */
4309 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4310 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4311 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4312 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4313 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4316 /* The multiple "Capture Source" controls confuse alsamixer
4317 * So call somewhat different..
4319 /* .name = "Capture Source", */
4320 .name = "Input Source",
4322 .info = alc_mux_enum_info,
4323 .get = alc_mux_enum_get,
4324 .put = alc_mux_enum_put,
4329 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4330 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4331 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4333 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4334 /* The multiple "Capture Source" controls confuse alsamixer
4335 * So call somewhat different..
4337 /* .name = "Capture Source", */
4338 .name = "Input Source",
4340 .info = alc_mux_enum_info,
4341 .get = alc_mux_enum_get,
4342 .put = alc_mux_enum_put,
4348 * initialization verbs
4350 static struct hda_verb alc260_init_verbs[] = {
4351 /* Line In pin widget for input */
4352 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4353 /* CD pin widget for input */
4354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4355 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4356 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4357 /* Mic2 (front panel) pin widget for input and vref at 80% */
4358 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4359 /* LINE-2 is used for line-out in rear */
4360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4361 /* select line-out */
4362 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4364 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4366 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4368 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4369 /* mute capture amp left and right */
4370 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4371 /* set connection select to line in (default select for this ADC) */
4372 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4373 /* mute capture amp left and right */
4374 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4375 /* set connection select to line in (default select for this ADC) */
4376 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4377 /* set vol=0 Line-Out mixer amp left and right */
4378 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4379 /* unmute pin widget amp left and right (no gain on this amp) */
4380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4381 /* set vol=0 HP mixer amp left and right */
4382 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4383 /* unmute pin widget amp left and right (no gain on this amp) */
4384 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4385 /* set vol=0 Mono mixer amp left and right */
4386 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4387 /* unmute pin widget amp left and right (no gain on this amp) */
4388 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4389 /* unmute LINE-2 out pin */
4390 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4391 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4394 /* mute analog inputs */
4395 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4400 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4401 /* mute Front out path */
4402 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4404 /* mute Headphone out path */
4405 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4406 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4407 /* mute Mono out path */
4408 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4409 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4413 #if 0 /* should be identical with alc260_init_verbs? */
4414 static struct hda_verb alc260_hp_init_verbs[] = {
4415 /* Headphone and output */
4416 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4418 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4419 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4420 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4421 /* Mic2 (front panel) pin widget for input and vref at 80% */
4422 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4423 /* Line In pin widget for input */
4424 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4425 /* Line-2 pin widget for output */
4426 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4427 /* CD pin widget for input */
4428 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4429 /* unmute amp left and right */
4430 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4431 /* set connection select to line in (default select for this ADC) */
4432 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4433 /* unmute Line-Out mixer amp left and right (volume = 0) */
4434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4435 /* mute pin widget amp left and right (no gain on this amp) */
4436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4437 /* unmute HP mixer amp left and right (volume = 0) */
4438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4439 /* mute pin widget amp left and right (no gain on this amp) */
4440 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4441 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4444 /* mute analog inputs */
4445 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4447 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4448 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4449 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4450 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4451 /* Unmute Front out path */
4452 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4453 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4454 /* Unmute Headphone out path */
4455 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4456 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4457 /* Unmute Mono out path */
4458 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4459 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4464 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4465 /* Line out and output */
4466 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4468 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4469 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4470 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4471 /* Mic2 (front panel) pin widget for input and vref at 80% */
4472 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4473 /* Line In pin widget for input */
4474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4475 /* Headphone pin widget for output */
4476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4477 /* CD pin widget for input */
4478 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4479 /* unmute amp left and right */
4480 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4481 /* set connection select to line in (default select for this ADC) */
4482 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4483 /* unmute Line-Out mixer amp left and right (volume = 0) */
4484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4485 /* mute pin widget amp left and right (no gain on this amp) */
4486 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4487 /* unmute HP mixer amp left and right (volume = 0) */
4488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4489 /* mute pin widget amp left and right (no gain on this amp) */
4490 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4491 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4494 /* mute analog inputs */
4495 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4496 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4497 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4498 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4500 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4501 /* Unmute Front out path */
4502 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4504 /* Unmute Headphone out path */
4505 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4506 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4507 /* Unmute Mono out path */
4508 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4509 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4513 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4514 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4515 * audio = 0x16, internal speaker = 0x10.
4517 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4518 /* Disable all GPIOs */
4519 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4520 /* Internal speaker is connected to headphone pin */
4521 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4522 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4524 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4525 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4526 /* Ensure all other unused pins are disabled and muted. */
4527 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4528 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4529 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4530 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4531 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4532 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4533 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4534 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4536 /* Disable digital (SPDIF) pins */
4537 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4538 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4540 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4541 * when acting as an output.
4543 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4545 /* Start with output sum widgets muted and their output gains at min */
4546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4547 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4548 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4549 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4551 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4552 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4553 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4554 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4556 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4557 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4558 /* Unmute Line1 pin widget output buffer since it starts as an output.
4559 * If the pin mode is changed by the user the pin mode control will
4560 * take care of enabling the pin's input/output buffers as needed.
4561 * Therefore there's no need to enable the input buffer at this
4564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4565 /* Unmute input buffer of pin widget used for Line-in (no equiv
4568 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4570 /* Mute capture amp left and right */
4571 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4572 /* Set ADC connection select to match default mixer setting - line
4575 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4577 /* Do the same for the second ADC: mute capture input amp and
4578 * set ADC connection to line in (on mic1 pin)
4580 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4581 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4583 /* Mute all inputs to mixer widget (even unconnected ones) */
4584 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4589 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4596 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4597 * similar laptops (adapted from Fujitsu init verbs).
4599 static struct hda_verb alc260_acer_init_verbs[] = {
4600 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4601 * the headphone jack. Turn this on and rely on the standard mute
4602 * methods whenever the user wants to turn these outputs off.
4604 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4605 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4606 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4607 /* Internal speaker/Headphone jack is connected to Line-out pin */
4608 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4609 /* Internal microphone/Mic jack is connected to Mic1 pin */
4610 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4611 /* Line In jack is connected to Line1 pin */
4612 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4613 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4614 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4615 /* Ensure all other unused pins are disabled and muted. */
4616 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4617 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4618 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4619 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4620 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4621 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4622 /* Disable digital (SPDIF) pins */
4623 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4624 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4626 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4627 * bus when acting as outputs.
4629 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4630 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4632 /* Start with output sum widgets muted and their output gains at min */
4633 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4634 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4635 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4636 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4637 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4638 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4639 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4640 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4641 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4643 /* Unmute Line-out pin widget amp left and right
4644 * (no equiv mixer ctrl)
4646 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4647 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4648 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4649 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4650 * inputs. If the pin mode is changed by the user the pin mode control
4651 * will take care of enabling the pin's input/output buffers as needed.
4652 * Therefore there's no need to enable the input buffer at this
4655 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4656 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4658 /* Mute capture amp left and right */
4659 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4660 /* Set ADC connection select to match default mixer setting - mic
4663 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4665 /* Do similar with the second ADC: mute capture input amp and
4666 * set ADC connection to mic to match ALSA's default state.
4668 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4669 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4671 /* Mute all inputs to mixer widget (even unconnected ones) */
4672 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4675 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4679 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4684 static struct hda_verb alc260_will_verbs[] = {
4685 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4686 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4687 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4688 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4689 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4690 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4694 static struct hda_verb alc260_replacer_672v_verbs[] = {
4695 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4696 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4697 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4699 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4700 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4701 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4703 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4707 /* toggle speaker-output according to the hp-jack state */
4708 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4710 unsigned int present;
4712 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4713 present = snd_hda_codec_read(codec, 0x0f, 0,
4714 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4716 snd_hda_codec_write_cache(codec, 0x01, 0,
4717 AC_VERB_SET_GPIO_DATA, 1);
4718 snd_hda_codec_write_cache(codec, 0x0f, 0,
4719 AC_VERB_SET_PIN_WIDGET_CONTROL,
4722 snd_hda_codec_write_cache(codec, 0x01, 0,
4723 AC_VERB_SET_GPIO_DATA, 0);
4724 snd_hda_codec_write_cache(codec, 0x0f, 0,
4725 AC_VERB_SET_PIN_WIDGET_CONTROL,
4730 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4733 if ((res >> 26) == ALC880_HP_EVENT)
4734 alc260_replacer_672v_automute(codec);
4737 static struct hda_verb alc260_hp_dc7600_verbs[] = {
4738 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4739 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4740 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4741 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4742 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4744 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4745 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4746 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4747 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4751 /* Test configuration for debugging, modelled after the ALC880 test
4754 #ifdef CONFIG_SND_DEBUG
4755 static hda_nid_t alc260_test_dac_nids[1] = {
4758 static hda_nid_t alc260_test_adc_nids[2] = {
4761 /* For testing the ALC260, each input MUX needs its own definition since
4762 * the signal assignments are different. This assumes that the first ADC
4765 static struct hda_input_mux alc260_test_capture_sources[2] = {
4769 { "MIC1 pin", 0x0 },
4770 { "MIC2 pin", 0x1 },
4771 { "LINE1 pin", 0x2 },
4772 { "LINE2 pin", 0x3 },
4774 { "LINE-OUT pin", 0x5 },
4775 { "HP-OUT pin", 0x6 },
4781 { "MIC1 pin", 0x0 },
4782 { "MIC2 pin", 0x1 },
4783 { "LINE1 pin", 0x2 },
4784 { "LINE2 pin", 0x3 },
4787 { "LINE-OUT pin", 0x6 },
4788 { "HP-OUT pin", 0x7 },
4792 static struct snd_kcontrol_new alc260_test_mixer[] = {
4793 /* Output driver widgets */
4794 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4795 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4796 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4797 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4798 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4799 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4801 /* Modes for retasking pin widgets
4802 * Note: the ALC260 doesn't seem to act on requests to enable mic
4803 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4804 * mention this restriction. At this stage it's not clear whether
4805 * this behaviour is intentional or is a hardware bug in chip
4806 * revisions available at least up until early 2006. Therefore for
4807 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4808 * choices, but if it turns out that the lack of mic bias for these
4809 * NIDs is intentional we could change their modes from
4810 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4812 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4813 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4814 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4815 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4816 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4817 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4819 /* Loopback mixer controls */
4820 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4821 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4822 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4823 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4824 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4825 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4826 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4827 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4828 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4829 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4830 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4831 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4832 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4833 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4834 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4835 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4837 /* Controls for GPIO pins, assuming they are configured as outputs */
4838 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4839 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4840 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4841 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4843 /* Switches to allow the digital IO pins to be enabled. The datasheet
4844 * is ambigious as to which NID is which; testing on laptops which
4845 * make this output available should provide clarification.
4847 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4848 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4850 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4851 * this output to turn on an external amplifier.
4853 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4854 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4858 static struct hda_verb alc260_test_init_verbs[] = {
4859 /* Enable all GPIOs as outputs with an initial value of 0 */
4860 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4861 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4862 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4864 /* Enable retasking pins as output, initially without power amp */
4865 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4866 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4868 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4869 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4870 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4872 /* Disable digital (SPDIF) pins initially, but users can enable
4873 * them via a mixer switch. In the case of SPDIF-out, this initverb
4874 * payload also sets the generation to 0, output to be in "consumer"
4875 * PCM format, copyright asserted, no pre-emphasis and no validity
4878 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4879 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4881 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4882 * OUT1 sum bus when acting as an output.
4884 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4885 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4886 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4887 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4889 /* Start with output sum widgets muted and their output gains at min */
4890 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4891 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4892 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4893 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4894 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4895 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4896 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4897 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4898 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4900 /* Unmute retasking pin widget output buffers since the default
4901 * state appears to be output. As the pin mode is changed by the
4902 * user the pin mode control will take care of enabling the pin's
4903 * input/output buffers as needed.
4905 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4906 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4907 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4909 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4910 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4911 /* Also unmute the mono-out pin widget */
4912 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4914 /* Mute capture amp left and right */
4915 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4916 /* Set ADC connection select to match default mixer setting (mic1
4919 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4921 /* Do the same for the second ADC: mute capture input amp and
4922 * set ADC connection to mic1 pin
4924 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4925 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4927 /* Mute all inputs to mixer widget (even unconnected ones) */
4928 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4929 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4930 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4931 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4932 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4933 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4934 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4935 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4941 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4942 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
4944 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4945 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4948 * for BIOS auto-configuration
4951 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4955 unsigned long vol_val, sw_val;
4959 if (nid >= 0x0f && nid < 0x11) {
4960 nid_vol = nid - 0x7;
4961 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4962 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4963 } else if (nid == 0x11) {
4964 nid_vol = nid - 0x7;
4965 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4966 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4967 } else if (nid >= 0x12 && nid <= 0x15) {
4969 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4970 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4974 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4975 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4978 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4979 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4985 /* add playback controls from the parsed DAC table */
4986 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4987 const struct auto_pin_cfg *cfg)
4992 spec->multiout.num_dacs = 1;
4993 spec->multiout.dac_nids = spec->private_dac_nids;
4994 spec->multiout.dac_nids[0] = 0x02;
4996 nid = cfg->line_out_pins[0];
4998 err = alc260_add_playback_controls(spec, nid, "Front");
5003 nid = cfg->speaker_pins[0];
5005 err = alc260_add_playback_controls(spec, nid, "Speaker");
5010 nid = cfg->hp_pins[0];
5012 err = alc260_add_playback_controls(spec, nid, "Headphone");
5019 /* create playback/capture controls for input pins */
5020 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5021 const struct auto_pin_cfg *cfg)
5023 struct hda_input_mux *imux = &spec->private_imux;
5026 for (i = 0; i < AUTO_PIN_LAST; i++) {
5027 if (cfg->input_pins[i] >= 0x12) {
5028 idx = cfg->input_pins[i] - 0x12;
5029 err = new_analog_input(spec, cfg->input_pins[i],
5030 auto_pin_cfg_labels[i], idx,
5034 imux->items[imux->num_items].label =
5035 auto_pin_cfg_labels[i];
5036 imux->items[imux->num_items].index = idx;
5039 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5040 idx = cfg->input_pins[i] - 0x09;
5041 err = new_analog_input(spec, cfg->input_pins[i],
5042 auto_pin_cfg_labels[i], idx,
5046 imux->items[imux->num_items].label =
5047 auto_pin_cfg_labels[i];
5048 imux->items[imux->num_items].index = idx;
5055 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5056 hda_nid_t nid, int pin_type,
5059 alc_set_pin_output(codec, nid, pin_type);
5060 /* need the manual connection? */
5062 int idx = nid - 0x12;
5063 snd_hda_codec_write(codec, idx + 0x0b, 0,
5064 AC_VERB_SET_CONNECT_SEL, sel_idx);
5068 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5070 struct alc_spec *spec = codec->spec;
5073 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5074 nid = spec->autocfg.line_out_pins[0];
5076 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5077 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5080 nid = spec->autocfg.speaker_pins[0];
5082 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5084 nid = spec->autocfg.hp_pins[0];
5086 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5089 #define ALC260_PIN_CD_NID 0x16
5090 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5092 struct alc_spec *spec = codec->spec;
5095 for (i = 0; i < AUTO_PIN_LAST; i++) {
5096 hda_nid_t nid = spec->autocfg.input_pins[i];
5098 snd_hda_codec_write(codec, nid, 0,
5099 AC_VERB_SET_PIN_WIDGET_CONTROL,
5100 i <= AUTO_PIN_FRONT_MIC ?
5101 PIN_VREF80 : PIN_IN);
5102 if (nid != ALC260_PIN_CD_NID)
5103 snd_hda_codec_write(codec, nid, 0,
5104 AC_VERB_SET_AMP_GAIN_MUTE,
5111 * generic initialization of ADC, input mixers and output mixers
5113 static struct hda_verb alc260_volume_init_verbs[] = {
5115 * Unmute ADC0-1 and set the default input to mic-in
5117 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5118 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5119 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5120 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5122 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5124 * Note: PASD motherboards uses the Line In 2 as the input for
5125 * front panel mic (mic 2)
5127 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5128 /* mute analog inputs */
5129 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5131 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5132 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5133 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5136 * Set up output mixers (0x08 - 0x0a)
5138 /* set vol=0 to output mixers */
5139 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5140 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5141 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5142 /* set up input amps for analog loopback */
5143 /* Amp Indices: DAC = 0, mixer = 1 */
5144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5145 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5146 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5147 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5148 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5149 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5154 static int alc260_parse_auto_config(struct hda_codec *codec)
5156 struct alc_spec *spec = codec->spec;
5159 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5161 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5165 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5168 if (!spec->kctl_alloc)
5169 return 0; /* can't find valid BIOS pin config */
5170 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5174 spec->multiout.max_channels = 2;
5176 if (spec->autocfg.dig_out_pin)
5177 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5178 if (spec->kctl_alloc)
5179 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5181 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5183 spec->num_mux_defs = 1;
5184 spec->input_mux = &spec->private_imux;
5186 /* check whether NID 0x04 is valid */
5187 wcap = get_wcaps(codec, 0x04);
5188 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5189 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5190 spec->adc_nids = alc260_adc_nids_alt;
5191 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5192 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5194 spec->adc_nids = alc260_adc_nids;
5195 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5196 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5203 /* additional initialization for auto-configuration model */
5204 static void alc260_auto_init(struct hda_codec *codec)
5206 struct alc_spec *spec = codec->spec;
5207 alc260_auto_init_multi_out(codec);
5208 alc260_auto_init_analog_input(codec);
5209 if (spec->unsol_event)
5210 alc_sku_automute(codec);
5213 #ifdef CONFIG_SND_HDA_POWER_SAVE
5214 static struct hda_amp_list alc260_loopbacks[] = {
5215 { 0x07, HDA_INPUT, 0 },
5216 { 0x07, HDA_INPUT, 1 },
5217 { 0x07, HDA_INPUT, 2 },
5218 { 0x07, HDA_INPUT, 3 },
5219 { 0x07, HDA_INPUT, 4 },
5225 * ALC260 configurations
5227 static const char *alc260_models[ALC260_MODEL_LAST] = {
5228 [ALC260_BASIC] = "basic",
5230 [ALC260_HP_3013] = "hp-3013",
5231 [ALC260_FUJITSU_S702X] = "fujitsu",
5232 [ALC260_ACER] = "acer",
5233 [ALC260_WILL] = "will",
5234 [ALC260_REPLACER_672V] = "replacer",
5235 #ifdef CONFIG_SND_DEBUG
5236 [ALC260_TEST] = "test",
5238 [ALC260_AUTO] = "auto",
5241 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5242 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5243 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5244 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5245 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5246 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5247 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5248 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5249 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5250 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5251 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5252 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5253 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5254 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5255 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5256 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5257 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5258 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5259 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5263 static struct alc_config_preset alc260_presets[] = {
5265 .mixers = { alc260_base_output_mixer,
5267 alc260_pc_beep_mixer,
5268 alc260_capture_mixer },
5269 .init_verbs = { alc260_init_verbs },
5270 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5271 .dac_nids = alc260_dac_nids,
5272 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5273 .adc_nids = alc260_adc_nids,
5274 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5275 .channel_mode = alc260_modes,
5276 .input_mux = &alc260_capture_source,
5279 .mixers = { alc260_hp_output_mixer,
5281 alc260_capture_alt_mixer },
5282 .init_verbs = { alc260_init_verbs,
5283 alc260_hp_unsol_verbs },
5284 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5285 .dac_nids = alc260_dac_nids,
5286 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5287 .adc_nids = alc260_hp_adc_nids,
5288 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5289 .channel_mode = alc260_modes,
5290 .input_mux = &alc260_capture_source,
5291 .unsol_event = alc260_hp_unsol_event,
5292 .init_hook = alc260_hp_automute,
5294 [ALC260_HP_DC7600] = {
5295 .mixers = { alc260_hp_dc7600_mixer,
5297 alc260_capture_alt_mixer },
5298 .init_verbs = { alc260_init_verbs,
5299 alc260_hp_dc7600_verbs },
5300 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5301 .dac_nids = alc260_dac_nids,
5302 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5303 .adc_nids = alc260_hp_adc_nids,
5304 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5305 .channel_mode = alc260_modes,
5306 .input_mux = &alc260_capture_source,
5307 .unsol_event = alc260_hp_3012_unsol_event,
5308 .init_hook = alc260_hp_3012_automute,
5310 [ALC260_HP_3013] = {
5311 .mixers = { alc260_hp_3013_mixer,
5313 alc260_capture_alt_mixer },
5314 .init_verbs = { alc260_hp_3013_init_verbs,
5315 alc260_hp_3013_unsol_verbs },
5316 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5317 .dac_nids = alc260_dac_nids,
5318 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5319 .adc_nids = alc260_hp_adc_nids,
5320 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5321 .channel_mode = alc260_modes,
5322 .input_mux = &alc260_capture_source,
5323 .unsol_event = alc260_hp_3013_unsol_event,
5324 .init_hook = alc260_hp_3013_automute,
5326 [ALC260_FUJITSU_S702X] = {
5327 .mixers = { alc260_fujitsu_mixer,
5328 alc260_capture_mixer },
5329 .init_verbs = { alc260_fujitsu_init_verbs },
5330 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5331 .dac_nids = alc260_dac_nids,
5332 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5333 .adc_nids = alc260_dual_adc_nids,
5334 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5335 .channel_mode = alc260_modes,
5336 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5337 .input_mux = alc260_fujitsu_capture_sources,
5340 .mixers = { alc260_acer_mixer,
5341 alc260_capture_mixer },
5342 .init_verbs = { alc260_acer_init_verbs },
5343 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5344 .dac_nids = alc260_dac_nids,
5345 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5346 .adc_nids = alc260_dual_adc_nids,
5347 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5348 .channel_mode = alc260_modes,
5349 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5350 .input_mux = alc260_acer_capture_sources,
5353 .mixers = { alc260_will_mixer,
5354 alc260_capture_mixer },
5355 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5356 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5357 .dac_nids = alc260_dac_nids,
5358 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5359 .adc_nids = alc260_adc_nids,
5360 .dig_out_nid = ALC260_DIGOUT_NID,
5361 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5362 .channel_mode = alc260_modes,
5363 .input_mux = &alc260_capture_source,
5365 [ALC260_REPLACER_672V] = {
5366 .mixers = { alc260_replacer_672v_mixer,
5367 alc260_capture_mixer },
5368 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5369 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5370 .dac_nids = alc260_dac_nids,
5371 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5372 .adc_nids = alc260_adc_nids,
5373 .dig_out_nid = ALC260_DIGOUT_NID,
5374 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5375 .channel_mode = alc260_modes,
5376 .input_mux = &alc260_capture_source,
5377 .unsol_event = alc260_replacer_672v_unsol_event,
5378 .init_hook = alc260_replacer_672v_automute,
5380 #ifdef CONFIG_SND_DEBUG
5382 .mixers = { alc260_test_mixer,
5383 alc260_capture_mixer },
5384 .init_verbs = { alc260_test_init_verbs },
5385 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5386 .dac_nids = alc260_test_dac_nids,
5387 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5388 .adc_nids = alc260_test_adc_nids,
5389 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5390 .channel_mode = alc260_modes,
5391 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5392 .input_mux = alc260_test_capture_sources,
5397 static int patch_alc260(struct hda_codec *codec)
5399 struct alc_spec *spec;
5400 int err, board_config;
5402 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5408 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5411 if (board_config < 0) {
5412 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5413 "trying auto-probe from BIOS...\n");
5414 board_config = ALC260_AUTO;
5417 if (board_config == ALC260_AUTO) {
5418 /* automatic parse from the BIOS config */
5419 err = alc260_parse_auto_config(codec);
5425 "hda_codec: Cannot set up configuration "
5426 "from BIOS. Using base mode...\n");
5427 board_config = ALC260_BASIC;
5431 if (board_config != ALC260_AUTO)
5432 setup_preset(spec, &alc260_presets[board_config]);
5434 spec->stream_name_analog = "ALC260 Analog";
5435 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5436 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5438 spec->stream_name_digital = "ALC260 Digital";
5439 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5440 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5442 spec->vmaster_nid = 0x08;
5444 codec->patch_ops = alc_patch_ops;
5445 if (board_config == ALC260_AUTO)
5446 spec->init_hook = alc260_auto_init;
5447 #ifdef CONFIG_SND_HDA_POWER_SAVE
5448 if (!spec->loopback.amplist)
5449 spec->loopback.amplist = alc260_loopbacks;
5459 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5460 * configuration. Each pin widget can choose any input DACs and a mixer.
5461 * Each ADC is connected from a mixer of all inputs. This makes possible
5462 * 6-channel independent captures.
5464 * In addition, an independent DAC for the multi-playback (not used in this
5467 #define ALC882_DIGOUT_NID 0x06
5468 #define ALC882_DIGIN_NID 0x0a
5470 static struct hda_channel_mode alc882_ch_modes[1] = {
5474 static hda_nid_t alc882_dac_nids[4] = {
5475 /* front, rear, clfe, rear_surr */
5476 0x02, 0x03, 0x04, 0x05
5479 /* identical with ALC880 */
5480 #define alc882_adc_nids alc880_adc_nids
5481 #define alc882_adc_nids_alt alc880_adc_nids_alt
5483 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5484 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5487 /* FIXME: should be a matrix-type input source selection */
5489 static struct hda_input_mux alc882_capture_source = {
5493 { "Front Mic", 0x1 },
5498 #define alc882_mux_enum_info alc_mux_enum_info
5499 #define alc882_mux_enum_get alc_mux_enum_get
5501 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5502 struct snd_ctl_elem_value *ucontrol)
5504 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5505 struct alc_spec *spec = codec->spec;
5506 const struct hda_input_mux *imux = spec->input_mux;
5507 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5508 hda_nid_t nid = spec->capsrc_nids ?
5509 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5510 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5511 unsigned int i, idx;
5513 idx = ucontrol->value.enumerated.item[0];
5514 if (idx >= imux->num_items)
5515 idx = imux->num_items - 1;
5516 if (*cur_val == idx)
5518 for (i = 0; i < imux->num_items; i++) {
5519 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5520 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5521 imux->items[i].index,
5531 static struct hda_verb alc882_3ST_ch2_init[] = {
5532 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5533 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5534 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5535 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5542 static struct hda_verb alc882_3ST_ch6_init[] = {
5543 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5544 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5545 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5546 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5547 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5548 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5552 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5553 { 2, alc882_3ST_ch2_init },
5554 { 6, alc882_3ST_ch6_init },
5560 static struct hda_verb alc882_sixstack_ch6_init[] = {
5561 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5562 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5563 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5564 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5571 static struct hda_verb alc882_sixstack_ch8_init[] = {
5572 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5573 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5574 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5575 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5579 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5580 { 6, alc882_sixstack_ch6_init },
5581 { 8, alc882_sixstack_ch8_init },
5585 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5591 static struct hda_verb alc885_mbp_ch2_init[] = {
5592 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5593 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5594 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5601 static struct hda_verb alc885_mbp_ch6_init[] = {
5602 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5603 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5604 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5605 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5606 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5610 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5611 { 2, alc885_mbp_ch2_init },
5612 { 6, alc885_mbp_ch6_init },
5616 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5617 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5619 static struct snd_kcontrol_new alc882_base_mixer[] = {
5620 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5621 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5622 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5623 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5624 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5625 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5626 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5627 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5628 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5629 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5630 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5631 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5632 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5633 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5634 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5635 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5636 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5638 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5639 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5640 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5641 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5642 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5646 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5648 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5649 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5650 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5651 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5652 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5653 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5654 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5655 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5656 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5659 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5660 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5661 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5662 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5663 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5664 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5665 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5669 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5670 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5674 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5675 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5676 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5677 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5678 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5679 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5680 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5681 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5682 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5683 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5684 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5685 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5686 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5687 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5691 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5692 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5694 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5696 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5697 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5698 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5699 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5700 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5701 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5702 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5703 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5704 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5707 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5711 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5712 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5713 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5715 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5716 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5717 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5718 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5720 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5722 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5723 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5727 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5730 .name = "Channel Mode",
5731 .info = alc_ch_mode_info,
5732 .get = alc_ch_mode_get,
5733 .put = alc_ch_mode_put,
5738 static struct hda_verb alc882_init_verbs[] = {
5739 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5742 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5744 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5750 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5752 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5753 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5754 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5756 /* Front Pin: output 0 (0x0c) */
5757 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5759 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5760 /* Rear Pin: output 1 (0x0d) */
5761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5763 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5764 /* CLFE Pin: output 2 (0x0e) */
5765 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5766 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5767 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5768 /* Side Pin: output 3 (0x0f) */
5769 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5770 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5771 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5772 /* Mic (rear) pin: input vref at 80% */
5773 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5774 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5775 /* Front Mic pin: input vref at 80% */
5776 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5777 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5778 /* Line In pin: input */
5779 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5780 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5781 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5782 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5783 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5784 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5785 /* CD pin widget for input */
5786 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5788 /* FIXME: use matrix-type input source selection */
5789 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5790 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5791 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5792 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5793 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5794 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5796 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5797 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5798 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5799 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5801 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5802 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5803 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5804 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5805 /* ADC1: mute amp left and right */
5806 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5807 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5808 /* ADC2: mute amp left and right */
5809 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5810 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5811 /* ADC3: mute amp left and right */
5812 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5813 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5818 static struct hda_verb alc882_eapd_verbs[] = {
5819 /* change to EAPD mode */
5820 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5821 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5826 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5829 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5830 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5831 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5832 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5833 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5837 static struct hda_verb alc882_macpro_init_verbs[] = {
5838 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5840 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5842 /* Front Pin: output 0 (0x0c) */
5843 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5844 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5845 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5846 /* Front Mic pin: input vref at 80% */
5847 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5848 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5849 /* Speaker: output */
5850 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5851 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5852 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5853 /* Headphone output (output 0 - 0x0c) */
5854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5855 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5856 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5858 /* FIXME: use matrix-type input source selection */
5859 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5860 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5861 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5862 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5863 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5864 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5866 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5867 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5868 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5869 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5871 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5875 /* ADC1: mute amp left and right */
5876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5877 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5878 /* ADC2: mute amp left and right */
5879 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5880 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5881 /* ADC3: mute amp left and right */
5882 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5883 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5888 /* Macbook Pro rev3 */
5889 static struct hda_verb alc885_mbp3_init_verbs[] = {
5890 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5893 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5895 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5896 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5897 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5898 /* Front Pin: output 0 (0x0c) */
5899 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5900 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5901 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5902 /* HP Pin: output 0 (0x0d) */
5903 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5904 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5905 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5906 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5907 /* Mic (rear) pin: input vref at 80% */
5908 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5909 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5910 /* Front Mic pin: input vref at 80% */
5911 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5912 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5913 /* Line In pin: use output 1 when in LineOut mode */
5914 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5915 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5916 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5918 /* FIXME: use matrix-type input source selection */
5919 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5920 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5922 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5923 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5924 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5927 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5929 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5932 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5933 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5934 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5935 /* ADC1: mute amp left and right */
5936 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5937 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5938 /* ADC2: mute amp left and right */
5939 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5940 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5941 /* ADC3: mute amp left and right */
5942 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5943 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5948 /* iMac 24 mixer. */
5949 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5950 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5951 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5955 /* iMac 24 init verbs. */
5956 static struct hda_verb alc885_imac24_init_verbs[] = {
5957 /* Internal speakers: output 0 (0x0c) */
5958 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5959 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5960 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5961 /* Internal speakers: output 0 (0x0c) */
5962 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5963 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5964 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5965 /* Headphone: output 0 (0x0c) */
5966 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5967 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5968 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5969 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5970 /* Front Mic: input vref at 80% */
5971 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5972 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5976 /* Toggle speaker-output according to the hp-jack state */
5977 static void alc885_imac24_automute(struct hda_codec *codec)
5979 unsigned int present;
5981 present = snd_hda_codec_read(codec, 0x14, 0,
5982 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5983 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5984 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5985 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5986 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5989 /* Processes unsolicited events. */
5990 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5993 /* Headphone insertion or removal. */
5994 if ((res >> 26) == ALC880_HP_EVENT)
5995 alc885_imac24_automute(codec);
5998 static void alc885_mbp3_automute(struct hda_codec *codec)
6000 unsigned int present;
6002 present = snd_hda_codec_read(codec, 0x15, 0,
6003 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6004 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6005 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6006 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6007 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6010 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6013 /* Headphone insertion or removal. */
6014 if ((res >> 26) == ALC880_HP_EVENT)
6015 alc885_mbp3_automute(codec);
6019 static struct hda_verb alc882_targa_verbs[] = {
6020 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6021 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6023 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6024 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6026 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6027 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6028 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6030 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6031 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6032 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6033 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6037 /* toggle speaker-output according to the hp-jack state */
6038 static void alc882_targa_automute(struct hda_codec *codec)
6040 unsigned int present;
6042 present = snd_hda_codec_read(codec, 0x14, 0,
6043 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6044 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6045 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6046 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6050 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6052 /* Looks like the unsol event is incompatible with the standard
6053 * definition. 4bit tag is placed at 26 bit!
6055 if (((res >> 26) == ALC880_HP_EVENT)) {
6056 alc882_targa_automute(codec);
6060 static struct hda_verb alc882_asus_a7j_verbs[] = {
6061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6066 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6068 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6069 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6070 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6072 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6073 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6074 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6078 static struct hda_verb alc882_asus_a7m_verbs[] = {
6079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6082 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6084 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6086 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6087 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6088 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6090 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6091 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6092 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6096 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6098 unsigned int gpiostate, gpiomask, gpiodir;
6100 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6101 AC_VERB_GET_GPIO_DATA, 0);
6104 gpiostate |= (1 << pin);
6106 gpiostate &= ~(1 << pin);
6108 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6109 AC_VERB_GET_GPIO_MASK, 0);
6110 gpiomask |= (1 << pin);
6112 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6113 AC_VERB_GET_GPIO_DIRECTION, 0);
6114 gpiodir |= (1 << pin);
6117 snd_hda_codec_write(codec, codec->afg, 0,
6118 AC_VERB_SET_GPIO_MASK, gpiomask);
6119 snd_hda_codec_write(codec, codec->afg, 0,
6120 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6124 snd_hda_codec_write(codec, codec->afg, 0,
6125 AC_VERB_SET_GPIO_DATA, gpiostate);
6128 /* set up GPIO at initialization */
6129 static void alc885_macpro_init_hook(struct hda_codec *codec)
6131 alc882_gpio_mute(codec, 0, 0);
6132 alc882_gpio_mute(codec, 1, 0);
6135 /* set up GPIO and update auto-muting at initialization */
6136 static void alc885_imac24_init_hook(struct hda_codec *codec)
6138 alc885_macpro_init_hook(codec);
6139 alc885_imac24_automute(codec);
6143 * generic initialization of ADC, input mixers and output mixers
6145 static struct hda_verb alc882_auto_init_verbs[] = {
6147 * Unmute ADC0-2 and set the default input to mic-in
6149 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6151 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6152 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6153 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6154 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6156 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6158 * Note: PASD motherboards uses the Line In 2 as the input for
6159 * front panel mic (mic 2)
6161 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6162 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6163 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6164 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6165 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6166 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6169 * Set up output mixers (0x0c - 0x0f)
6171 /* set vol=0 to output mixers */
6172 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6173 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6174 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6175 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6176 /* set up input amps for analog loopback */
6177 /* Amp Indices: DAC = 0, mixer = 1 */
6178 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6180 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6181 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6182 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6183 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6184 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6185 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6186 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6187 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6189 /* FIXME: use matrix-type input source selection */
6190 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6191 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6192 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6194 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6195 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6199 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6200 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6202 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6204 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6205 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6210 /* capture mixer elements */
6211 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6212 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6213 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6214 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6215 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6217 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6218 /* The multiple "Capture Source" controls confuse alsamixer
6219 * So call somewhat different..
6221 /* .name = "Capture Source", */
6222 .name = "Input Source",
6224 .info = alc882_mux_enum_info,
6225 .get = alc882_mux_enum_get,
6226 .put = alc882_mux_enum_put,
6231 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6232 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6233 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6234 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6235 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6236 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6237 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6240 /* The multiple "Capture Source" controls confuse alsamixer
6241 * So call somewhat different..
6243 /* .name = "Capture Source", */
6244 .name = "Input Source",
6246 .info = alc882_mux_enum_info,
6247 .get = alc882_mux_enum_get,
6248 .put = alc882_mux_enum_put,
6253 #ifdef CONFIG_SND_HDA_POWER_SAVE
6254 #define alc882_loopbacks alc880_loopbacks
6257 /* pcm configuration: identiacal with ALC880 */
6258 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6259 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6260 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6261 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6264 * configuration and preset
6266 static const char *alc882_models[ALC882_MODEL_LAST] = {
6267 [ALC882_3ST_DIG] = "3stack-dig",
6268 [ALC882_6ST_DIG] = "6stack-dig",
6269 [ALC882_ARIMA] = "arima",
6270 [ALC882_W2JC] = "w2jc",
6271 [ALC882_TARGA] = "targa",
6272 [ALC882_ASUS_A7J] = "asus-a7j",
6273 [ALC882_ASUS_A7M] = "asus-a7m",
6274 [ALC885_MACPRO] = "macpro",
6275 [ALC885_MBP3] = "mbp3",
6276 [ALC885_IMAC24] = "imac24",
6277 [ALC882_AUTO] = "auto",
6280 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6281 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6282 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6283 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6284 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6285 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6286 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6287 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6288 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6289 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6290 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6291 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6292 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6296 static struct alc_config_preset alc882_presets[] = {
6297 [ALC882_3ST_DIG] = {
6298 .mixers = { alc882_base_mixer },
6299 .init_verbs = { alc882_init_verbs },
6300 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6301 .dac_nids = alc882_dac_nids,
6302 .dig_out_nid = ALC882_DIGOUT_NID,
6303 .dig_in_nid = ALC882_DIGIN_NID,
6304 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6305 .channel_mode = alc882_ch_modes,
6307 .input_mux = &alc882_capture_source,
6309 [ALC882_6ST_DIG] = {
6310 .mixers = { alc882_base_mixer, alc882_chmode_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_sixstack_modes),
6317 .channel_mode = alc882_sixstack_modes,
6318 .input_mux = &alc882_capture_source,
6321 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6322 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6323 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6324 .dac_nids = alc882_dac_nids,
6325 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6326 .channel_mode = alc882_sixstack_modes,
6327 .input_mux = &alc882_capture_source,
6330 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6331 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6332 alc880_gpio1_init_verbs },
6333 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6334 .dac_nids = alc882_dac_nids,
6335 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6336 .channel_mode = alc880_threestack_modes,
6338 .input_mux = &alc882_capture_source,
6339 .dig_out_nid = ALC882_DIGOUT_NID,
6342 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6343 .init_verbs = { alc885_mbp3_init_verbs,
6344 alc880_gpio1_init_verbs },
6345 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6346 .dac_nids = alc882_dac_nids,
6347 .channel_mode = alc885_mbp_6ch_modes,
6348 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6349 .input_mux = &alc882_capture_source,
6350 .dig_out_nid = ALC882_DIGOUT_NID,
6351 .dig_in_nid = ALC882_DIGIN_NID,
6352 .unsol_event = alc885_mbp3_unsol_event,
6353 .init_hook = alc885_mbp3_automute,
6356 .mixers = { alc882_macpro_mixer },
6357 .init_verbs = { alc882_macpro_init_verbs },
6358 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6359 .dac_nids = alc882_dac_nids,
6360 .dig_out_nid = ALC882_DIGOUT_NID,
6361 .dig_in_nid = ALC882_DIGIN_NID,
6362 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6363 .channel_mode = alc882_ch_modes,
6364 .input_mux = &alc882_capture_source,
6365 .init_hook = alc885_macpro_init_hook,
6368 .mixers = { alc885_imac24_mixer },
6369 .init_verbs = { alc885_imac24_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 .unsol_event = alc885_imac24_unsol_event,
6378 .init_hook = alc885_imac24_init_hook,
6381 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6382 alc882_capture_mixer },
6383 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6384 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6385 .dac_nids = alc882_dac_nids,
6386 .dig_out_nid = ALC882_DIGOUT_NID,
6387 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6388 .adc_nids = alc882_adc_nids,
6389 .capsrc_nids = alc882_capsrc_nids,
6390 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6391 .channel_mode = alc882_3ST_6ch_modes,
6393 .input_mux = &alc882_capture_source,
6394 .unsol_event = alc882_targa_unsol_event,
6395 .init_hook = alc882_targa_automute,
6397 [ALC882_ASUS_A7J] = {
6398 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6399 alc882_capture_mixer },
6400 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6401 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6402 .dac_nids = alc882_dac_nids,
6403 .dig_out_nid = ALC882_DIGOUT_NID,
6404 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6405 .adc_nids = alc882_adc_nids,
6406 .capsrc_nids = alc882_capsrc_nids,
6407 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6408 .channel_mode = alc882_3ST_6ch_modes,
6410 .input_mux = &alc882_capture_source,
6412 [ALC882_ASUS_A7M] = {
6413 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6414 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6415 alc880_gpio1_init_verbs,
6416 alc882_asus_a7m_verbs },
6417 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6418 .dac_nids = alc882_dac_nids,
6419 .dig_out_nid = ALC882_DIGOUT_NID,
6420 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6421 .channel_mode = alc880_threestack_modes,
6423 .input_mux = &alc882_capture_source,
6432 PINFIX_ABIT_AW9D_MAX
6435 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6436 { 0x15, 0x01080104 }, /* side */
6437 { 0x16, 0x01011012 }, /* rear */
6438 { 0x17, 0x01016011 }, /* clfe */
6442 static const struct alc_pincfg *alc882_pin_fixes[] = {
6443 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6446 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6447 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6452 * BIOS auto configuration
6454 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6455 hda_nid_t nid, int pin_type,
6459 struct alc_spec *spec = codec->spec;
6462 alc_set_pin_output(codec, nid, pin_type);
6463 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6466 idx = spec->multiout.dac_nids[dac_idx] - 2;
6467 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6471 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6473 struct alc_spec *spec = codec->spec;
6476 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6477 for (i = 0; i <= HDA_SIDE; i++) {
6478 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6479 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6481 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6486 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6488 struct alc_spec *spec = codec->spec;
6491 pin = spec->autocfg.hp_pins[0];
6492 if (pin) /* connect to front */
6494 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6495 pin = spec->autocfg.speaker_pins[0];
6497 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6500 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6501 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6503 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6505 struct alc_spec *spec = codec->spec;
6508 for (i = 0; i < AUTO_PIN_LAST; i++) {
6509 hda_nid_t nid = spec->autocfg.input_pins[i];
6514 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6515 unsigned int pincap;
6516 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6517 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6521 snd_hda_codec_write(codec, nid, 0,
6522 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6523 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6524 snd_hda_codec_write(codec, nid, 0,
6525 AC_VERB_SET_AMP_GAIN_MUTE,
6530 static void alc882_auto_init_input_src(struct hda_codec *codec)
6532 struct alc_spec *spec = codec->spec;
6533 const struct hda_input_mux *imux = spec->input_mux;
6536 for (c = 0; c < spec->num_adc_nids; c++) {
6537 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6538 hda_nid_t nid = spec->capsrc_nids[c];
6539 int conns, mute, idx, item;
6541 conns = snd_hda_get_connections(codec, nid, conn_list,
6542 ARRAY_SIZE(conn_list));
6545 for (idx = 0; idx < conns; idx++) {
6546 /* if the current connection is the selected one,
6547 * unmute it as default - otherwise mute it
6549 mute = AMP_IN_MUTE(idx);
6550 for (item = 0; item < imux->num_items; item++) {
6551 if (imux->items[item].index == idx) {
6552 if (spec->cur_mux[c] == item)
6553 mute = AMP_IN_UNMUTE(idx);
6557 snd_hda_codec_write(codec, nid, 0,
6558 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6563 /* add mic boosts if needed */
6564 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6566 struct alc_spec *spec = codec->spec;
6570 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6571 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6572 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6574 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6578 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6579 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6580 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6582 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6589 /* almost identical with ALC880 parser... */
6590 static int alc882_parse_auto_config(struct hda_codec *codec)
6592 struct alc_spec *spec = codec->spec;
6593 int err = alc880_parse_auto_config(codec);
6598 return 0; /* no config found */
6600 err = alc_auto_add_mic_boost(codec);
6604 /* hack - override the init verbs */
6605 spec->init_verbs[0] = alc882_auto_init_verbs;
6607 return 1; /* config found */
6610 /* additional initialization for auto-configuration model */
6611 static void alc882_auto_init(struct hda_codec *codec)
6613 struct alc_spec *spec = codec->spec;
6614 alc882_auto_init_multi_out(codec);
6615 alc882_auto_init_hp_out(codec);
6616 alc882_auto_init_analog_input(codec);
6617 alc882_auto_init_input_src(codec);
6618 if (spec->unsol_event)
6619 alc_sku_automute(codec);
6622 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6624 static int patch_alc882(struct hda_codec *codec)
6626 struct alc_spec *spec;
6627 int err, board_config;
6629 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6635 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6639 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6640 /* Pick up systems that don't supply PCI SSID */
6641 switch (codec->subsystem_id) {
6642 case 0x106b0c00: /* Mac Pro */
6643 board_config = ALC885_MACPRO;
6645 case 0x106b1000: /* iMac 24 */
6646 board_config = ALC885_IMAC24;
6648 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6649 case 0x106b2c00: /* Macbook Pro rev3 */
6650 case 0x106b3600: /* Macbook 3.1 */
6651 board_config = ALC885_MBP3;
6654 /* ALC889A is handled better as ALC888-compatible */
6655 if (codec->revision_id == 0x100103) {
6657 return patch_alc883(codec);
6659 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6660 "trying auto-probe from BIOS...\n");
6661 board_config = ALC882_AUTO;
6665 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6667 if (board_config == ALC882_AUTO) {
6668 /* automatic parse from the BIOS config */
6669 err = alc882_parse_auto_config(codec);
6675 "hda_codec: Cannot set up configuration "
6676 "from BIOS. Using base mode...\n");
6677 board_config = ALC882_3ST_DIG;
6681 if (board_config != ALC882_AUTO)
6682 setup_preset(spec, &alc882_presets[board_config]);
6684 if (codec->vendor_id == 0x10ec0885) {
6685 spec->stream_name_analog = "ALC885 Analog";
6686 spec->stream_name_digital = "ALC885 Digital";
6688 spec->stream_name_analog = "ALC882 Analog";
6689 spec->stream_name_digital = "ALC882 Digital";
6692 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6693 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6694 /* FIXME: setup DAC5 */
6695 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6696 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6698 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6699 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6701 if (!spec->adc_nids && spec->input_mux) {
6702 /* check whether NID 0x07 is valid */
6703 unsigned int wcap = get_wcaps(codec, 0x07);
6705 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6706 if (wcap != AC_WID_AUD_IN) {
6707 spec->adc_nids = alc882_adc_nids_alt;
6708 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6709 spec->capsrc_nids = alc882_capsrc_nids_alt;
6710 spec->mixers[spec->num_mixers] =
6711 alc882_capture_alt_mixer;
6714 spec->adc_nids = alc882_adc_nids;
6715 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6716 spec->capsrc_nids = alc882_capsrc_nids;
6717 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6722 spec->vmaster_nid = 0x0c;
6724 codec->patch_ops = alc_patch_ops;
6725 if (board_config == ALC882_AUTO)
6726 spec->init_hook = alc882_auto_init;
6727 #ifdef CONFIG_SND_HDA_POWER_SAVE
6728 if (!spec->loopback.amplist)
6729 spec->loopback.amplist = alc882_loopbacks;
6738 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6739 * configuration. Each pin widget can choose any input DACs and a mixer.
6740 * Each ADC is connected from a mixer of all inputs. This makes possible
6741 * 6-channel independent captures.
6743 * In addition, an independent DAC for the multi-playback (not used in this
6746 #define ALC883_DIGOUT_NID 0x06
6747 #define ALC883_DIGIN_NID 0x0a
6749 static hda_nid_t alc883_dac_nids[4] = {
6750 /* front, rear, clfe, rear_surr */
6751 0x02, 0x03, 0x04, 0x05
6754 static hda_nid_t alc883_adc_nids[2] = {
6759 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6762 /* FIXME: should be a matrix-type input source selection */
6764 static struct hda_input_mux alc883_capture_source = {
6768 { "Front Mic", 0x1 },
6774 static struct hda_input_mux alc883_3stack_6ch_intel = {
6778 { "Front Mic", 0x0 },
6784 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6792 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6802 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6810 #define alc883_mux_enum_info alc_mux_enum_info
6811 #define alc883_mux_enum_get alc_mux_enum_get
6812 /* ALC883 has the ALC882-type input selection */
6813 #define alc883_mux_enum_put alc882_mux_enum_put
6818 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6825 static struct hda_verb alc883_3ST_ch2_init[] = {
6826 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6827 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6828 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6829 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6836 static struct hda_verb alc883_3ST_ch4_init[] = {
6837 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6838 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6841 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6848 static struct hda_verb alc883_3ST_ch6_init[] = {
6849 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6850 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6851 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6853 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6854 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6858 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6859 { 2, alc883_3ST_ch2_init },
6860 { 4, alc883_3ST_ch4_init },
6861 { 6, alc883_3ST_ch6_init },
6867 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6868 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6869 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6870 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6871 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6878 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6880 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
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 },
6890 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6891 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6892 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6893 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6894 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6895 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6896 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6900 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6901 { 2, alc883_3ST_ch2_intel_init },
6902 { 4, alc883_3ST_ch4_intel_init },
6903 { 6, alc883_3ST_ch6_intel_init },
6909 static struct hda_verb alc883_sixstack_ch6_init[] = {
6910 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6911 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6912 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6913 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6920 static struct hda_verb alc883_sixstack_ch8_init[] = {
6921 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6922 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6923 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6924 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6928 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6929 { 6, alc883_sixstack_ch6_init },
6930 { 8, alc883_sixstack_ch8_init },
6933 static struct hda_verb alc883_medion_eapd_verbs[] = {
6934 /* eanable EAPD on medion laptop */
6935 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6936 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6940 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6941 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6944 static struct snd_kcontrol_new alc883_base_mixer[] = {
6945 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6946 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6947 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6948 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6949 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6950 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6951 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6952 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6953 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6954 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6956 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6957 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6958 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6959 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6960 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6961 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6962 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6963 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6964 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6965 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6966 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6967 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6968 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6969 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6970 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6971 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6973 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6974 /* .name = "Capture Source", */
6975 .name = "Input Source",
6977 .info = alc883_mux_enum_info,
6978 .get = alc883_mux_enum_get,
6979 .put = alc883_mux_enum_put,
6984 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6985 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6986 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6987 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6993 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6995 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6996 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6997 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6998 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6999 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7000 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7001 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7004 /* .name = "Capture Source", */
7005 .name = "Input Source",
7007 .info = alc883_mux_enum_info,
7008 .get = alc883_mux_enum_get,
7009 .put = alc883_mux_enum_put,
7014 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7015 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7016 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7017 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7018 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7020 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7021 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7022 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7023 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7024 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7025 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7026 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7027 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7028 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7031 /* .name = "Capture Source", */
7032 .name = "Input Source",
7034 .info = alc883_mux_enum_info,
7035 .get = alc883_mux_enum_get,
7036 .put = alc883_mux_enum_put,
7041 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7042 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7043 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7044 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7045 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7047 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7049 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7050 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7051 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7052 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7053 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7054 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7055 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7057 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7058 /* .name = "Capture Source", */
7059 .name = "Input Source",
7061 .info = alc883_mux_enum_info,
7062 .get = alc883_mux_enum_get,
7063 .put = alc883_mux_enum_put,
7068 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7069 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7070 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7077 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7079 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7080 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7081 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7082 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7083 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7084 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7085 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7086 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7087 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7089 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7090 /* .name = "Capture Source", */
7091 .name = "Input Source",
7093 .info = alc883_mux_enum_info,
7094 .get = alc883_mux_enum_get,
7095 .put = alc883_mux_enum_put,
7100 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7102 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7103 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7104 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7105 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7106 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7107 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7108 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7110 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7111 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7112 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7113 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7115 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7117 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7118 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7119 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7120 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7121 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7122 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7123 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7124 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7125 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7127 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7128 /* .name = "Capture Source", */
7129 .name = "Input Source",
7131 .info = alc883_mux_enum_info,
7132 .get = alc883_mux_enum_get,
7133 .put = alc883_mux_enum_put,
7138 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7139 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7140 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7141 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7142 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7143 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7145 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7146 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7147 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7148 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7149 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7150 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7151 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7152 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7153 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7154 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7155 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7156 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7157 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7158 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7159 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7160 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7161 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7162 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7163 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7164 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7166 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7167 /* .name = "Capture Source", */
7168 .name = "Input Source",
7170 .info = alc883_mux_enum_info,
7171 .get = alc883_mux_enum_get,
7172 .put = alc883_mux_enum_put,
7177 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7178 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7179 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7180 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7181 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7182 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7183 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7184 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7185 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7186 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7187 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7188 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7189 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7190 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7192 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7193 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7195 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7196 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7197 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7198 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7199 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7200 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7204 /* .name = "Capture Source", */
7205 .name = "Input Source",
7207 .info = alc883_mux_enum_info,
7208 .get = alc883_mux_enum_get,
7209 .put = alc883_mux_enum_put,
7214 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7215 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7216 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7217 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7218 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7219 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7220 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7221 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7222 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7223 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7224 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7225 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7226 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7227 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7229 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7231 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7232 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7233 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7234 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7236 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7237 /* .name = "Capture Source", */
7238 .name = "Input Source",
7240 .info = alc883_mux_enum_info,
7241 .get = alc883_mux_enum_get,
7242 .put = alc883_mux_enum_put,
7247 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7248 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7249 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7250 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7254 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7256 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7257 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7258 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7259 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7260 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7261 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7262 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7264 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7265 /* .name = "Capture Source", */
7266 .name = "Input Source",
7268 .info = alc883_mux_enum_info,
7269 .get = alc883_mux_enum_get,
7270 .put = alc883_mux_enum_put,
7275 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7276 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7277 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7278 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7279 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7280 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7281 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7282 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7283 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7284 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7285 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7288 /* .name = "Capture Source", */
7289 .name = "Input Source",
7291 .info = alc883_mux_enum_info,
7292 .get = alc883_mux_enum_get,
7293 .put = alc883_mux_enum_put,
7298 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7299 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7300 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7302 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7303 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7305 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7306 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7307 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7308 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7309 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7310 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7311 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7314 /* .name = "Capture Source", */
7315 .name = "Input Source",
7317 .info = alc883_mux_enum_info,
7318 .get = alc883_mux_enum_get,
7319 .put = alc883_mux_enum_put,
7324 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7325 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7327 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7328 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7329 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7330 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7331 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7332 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7333 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7334 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7335 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7336 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7337 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7340 /* .name = "Capture Source", */
7341 .name = "Input Source",
7343 .info = alc883_mux_enum_info,
7344 .get = alc883_mux_enum_get,
7345 .put = alc883_mux_enum_put,
7350 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7351 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7352 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7353 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7354 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7355 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7357 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7358 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7359 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7360 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7361 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7362 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7364 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7365 /* .name = "Capture Source", */
7366 .name = "Input Source",
7368 .info = alc883_mux_enum_info,
7369 .get = alc883_mux_enum_get,
7370 .put = alc883_mux_enum_put,
7375 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7377 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7378 .name = "Channel Mode",
7379 .info = alc_ch_mode_info,
7380 .get = alc_ch_mode_get,
7381 .put = alc_ch_mode_put,
7386 static struct hda_verb alc883_init_verbs[] = {
7387 /* ADC1: mute amp left and right */
7388 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7389 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7390 /* ADC2: mute amp left and right */
7391 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7392 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7393 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7395 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7396 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7398 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7399 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7400 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7402 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7404 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7406 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7407 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7408 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7410 /* mute analog input loopbacks */
7411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7412 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7413 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7414 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7415 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7417 /* Front Pin: output 0 (0x0c) */
7418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7419 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7420 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7421 /* Rear Pin: output 1 (0x0d) */
7422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7424 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7425 /* CLFE Pin: output 2 (0x0e) */
7426 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7427 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7428 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7429 /* Side Pin: output 3 (0x0f) */
7430 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7431 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7432 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7433 /* Mic (rear) pin: input vref at 80% */
7434 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7435 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7436 /* Front Mic pin: input vref at 80% */
7437 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7438 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7439 /* Line In pin: input */
7440 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7441 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7442 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7443 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7444 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7445 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7446 /* CD pin widget for input */
7447 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7449 /* FIXME: use matrix-type input source selection */
7450 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7464 /* toggle speaker-output according to the hp-jack state */
7465 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7467 unsigned int present;
7469 present = snd_hda_codec_read(codec, 0x15, 0,
7470 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7471 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7472 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7473 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7474 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7477 /* auto-toggle front mic */
7479 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7481 unsigned int present;
7484 present = snd_hda_codec_read(codec, 0x18, 0,
7485 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7486 bits = present ? HDA_AMP_MUTE : 0;
7487 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7491 static void alc883_mitac_automute(struct hda_codec *codec)
7493 alc883_mitac_hp_automute(codec);
7494 /* alc883_mitac_mic_automute(codec); */
7497 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7500 switch (res >> 26) {
7501 case ALC880_HP_EVENT:
7502 alc883_mitac_hp_automute(codec);
7504 case ALC880_MIC_EVENT:
7505 /* alc883_mitac_mic_automute(codec); */
7510 static struct hda_verb alc883_mitac_verbs[] = {
7512 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7515 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7516 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7518 /* enable unsolicited event */
7519 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7520 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7525 static struct hda_verb alc883_clevo_m720_verbs[] = {
7527 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7528 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7530 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7533 /* enable unsolicited event */
7534 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7535 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7540 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7542 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7543 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7545 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7548 /* enable unsolicited event */
7549 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7554 static struct hda_verb alc883_tagra_verbs[] = {
7555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7559 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7561 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7562 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7563 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7565 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7566 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7567 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7568 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7573 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7574 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7575 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7576 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7580 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7581 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7582 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7583 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7584 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7588 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7592 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7593 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7597 static struct hda_verb alc883_haier_w66_verbs[] = {
7598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7599 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7603 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7604 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7605 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7606 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7610 static struct hda_verb alc888_3st_hp_verbs[] = {
7611 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7612 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7613 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7617 static struct hda_verb alc888_6st_dell_verbs[] = {
7618 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7622 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7623 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7624 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7625 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7626 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7630 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7631 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7632 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7633 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7634 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7638 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7639 { 2, alc888_3st_hp_2ch_init },
7640 { 6, alc888_3st_hp_6ch_init },
7643 /* toggle front-jack and RCA according to the hp-jack state */
7644 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7646 unsigned int present;
7648 present = snd_hda_codec_read(codec, 0x1b, 0,
7649 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7650 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7651 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7652 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7653 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7656 /* toggle RCA according to the front-jack state */
7657 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7659 unsigned int present;
7661 present = snd_hda_codec_read(codec, 0x14, 0,
7662 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7663 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7664 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7667 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7670 if ((res >> 26) == ALC880_HP_EVENT)
7671 alc888_lenovo_ms7195_front_automute(codec);
7672 if ((res >> 26) == ALC880_FRONT_EVENT)
7673 alc888_lenovo_ms7195_rca_automute(codec);
7676 static struct hda_verb alc883_medion_md2_verbs[] = {
7677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7680 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7682 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7686 /* toggle speaker-output according to the hp-jack state */
7687 static void alc883_medion_md2_automute(struct hda_codec *codec)
7689 unsigned int present;
7691 present = snd_hda_codec_read(codec, 0x14, 0,
7692 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7693 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7694 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7697 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7700 if ((res >> 26) == ALC880_HP_EVENT)
7701 alc883_medion_md2_automute(codec);
7704 /* toggle speaker-output according to the hp-jack state */
7705 static void alc883_tagra_automute(struct hda_codec *codec)
7707 unsigned int present;
7710 present = snd_hda_codec_read(codec, 0x14, 0,
7711 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7712 bits = present ? HDA_AMP_MUTE : 0;
7713 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7714 HDA_AMP_MUTE, bits);
7715 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7719 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7721 if ((res >> 26) == ALC880_HP_EVENT)
7722 alc883_tagra_automute(codec);
7725 /* toggle speaker-output according to the hp-jack state */
7726 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7728 unsigned int present;
7731 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7732 & AC_PINSENSE_PRESENCE;
7733 bits = present ? HDA_AMP_MUTE : 0;
7734 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7735 HDA_AMP_MUTE, bits);
7738 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7740 unsigned int present;
7742 present = snd_hda_codec_read(codec, 0x18, 0,
7743 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7744 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7745 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7748 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7750 alc883_clevo_m720_hp_automute(codec);
7751 alc883_clevo_m720_mic_automute(codec);
7754 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7757 switch (res >> 26) {
7758 case ALC880_HP_EVENT:
7759 alc883_clevo_m720_hp_automute(codec);
7761 case ALC880_MIC_EVENT:
7762 alc883_clevo_m720_mic_automute(codec);
7767 /* toggle speaker-output according to the hp-jack state */
7768 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7770 unsigned int present;
7773 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7774 & AC_PINSENSE_PRESENCE;
7775 bits = present ? HDA_AMP_MUTE : 0;
7776 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7777 HDA_AMP_MUTE, bits);
7780 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7783 if ((res >> 26) == ALC880_HP_EVENT)
7784 alc883_2ch_fujitsu_pi2515_automute(codec);
7787 static void alc883_haier_w66_automute(struct hda_codec *codec)
7789 unsigned int present;
7792 present = snd_hda_codec_read(codec, 0x1b, 0,
7793 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7794 bits = present ? 0x80 : 0;
7795 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7799 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7802 if ((res >> 26) == ALC880_HP_EVENT)
7803 alc883_haier_w66_automute(codec);
7806 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7808 unsigned int present;
7811 present = snd_hda_codec_read(codec, 0x14, 0,
7812 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7813 bits = present ? HDA_AMP_MUTE : 0;
7814 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7815 HDA_AMP_MUTE, bits);
7818 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7820 unsigned int present;
7823 present = snd_hda_codec_read(codec, 0x1b, 0,
7824 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7825 bits = present ? HDA_AMP_MUTE : 0;
7826 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7827 HDA_AMP_MUTE, bits);
7828 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7829 HDA_AMP_MUTE, bits);
7832 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7835 if ((res >> 26) == ALC880_HP_EVENT)
7836 alc883_lenovo_101e_all_automute(codec);
7837 if ((res >> 26) == ALC880_FRONT_EVENT)
7838 alc883_lenovo_101e_ispeaker_automute(codec);
7841 /* toggle speaker-output according to the hp-jack state */
7842 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7844 unsigned int present;
7846 present = snd_hda_codec_read(codec, 0x14, 0,
7847 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7848 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7849 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7850 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7851 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7854 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7857 if ((res >> 26) == ALC880_HP_EVENT)
7858 alc883_acer_aspire_automute(codec);
7861 static struct hda_verb alc883_acer_eapd_verbs[] = {
7862 /* HP Pin: output 0 (0x0c) */
7863 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7864 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7865 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7866 /* Front Pin: output 0 (0x0c) */
7867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7869 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7870 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7871 /* eanable EAPD on medion laptop */
7872 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7873 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7874 /* enable unsolicited event */
7875 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7879 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7881 unsigned int present;
7883 present = snd_hda_codec_read(codec, 0x1b, 0,
7884 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7885 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7886 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7887 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7888 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7889 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7890 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7891 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7892 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7895 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7898 switch (res >> 26) {
7899 case ALC880_HP_EVENT:
7900 printk("hp_event\n");
7901 alc888_6st_dell_front_automute(codec);
7907 * generic initialization of ADC, input mixers and output mixers
7909 static struct hda_verb alc883_auto_init_verbs[] = {
7911 * Unmute ADC0-2 and set the default input to mic-in
7913 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7914 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7915 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7916 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7918 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7920 * Note: PASD motherboards uses the Line In 2 as the input for
7921 * front panel mic (mic 2)
7923 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7931 * Set up output mixers (0x0c - 0x0f)
7933 /* set vol=0 to output mixers */
7934 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7935 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7937 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7938 /* set up input amps for analog loopback */
7939 /* Amp Indices: DAC = 0, mixer = 1 */
7940 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7941 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7942 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7943 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7944 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7945 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7946 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7947 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7948 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7949 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7951 /* FIXME: use matrix-type input source selection */
7952 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7954 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7955 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7957 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7960 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7963 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7969 /* capture mixer elements */
7970 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7971 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7972 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7973 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7974 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7976 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7977 /* The multiple "Capture Source" controls confuse alsamixer
7978 * So call somewhat different..
7980 /* .name = "Capture Source", */
7981 .name = "Input Source",
7983 .info = alc882_mux_enum_info,
7984 .get = alc882_mux_enum_get,
7985 .put = alc882_mux_enum_put,
7990 #ifdef CONFIG_SND_HDA_POWER_SAVE
7991 #define alc883_loopbacks alc880_loopbacks
7994 /* pcm configuration: identiacal with ALC880 */
7995 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
7996 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
7997 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
7998 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
7999 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8002 * configuration and preset
8004 static const char *alc883_models[ALC883_MODEL_LAST] = {
8005 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8006 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8007 [ALC883_3ST_6ch] = "3stack-6ch",
8008 [ALC883_6ST_DIG] = "6stack-dig",
8009 [ALC883_TARGA_DIG] = "targa-dig",
8010 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8011 [ALC883_ACER] = "acer",
8012 [ALC883_ACER_ASPIRE] = "acer-aspire",
8013 [ALC883_MEDION] = "medion",
8014 [ALC883_MEDION_MD2] = "medion-md2",
8015 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8016 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8017 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8018 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8019 [ALC883_HAIER_W66] = "haier-w66",
8020 [ALC888_3ST_HP] = "3stack-hp",
8021 [ALC888_6ST_DELL] = "6stack-dell",
8022 [ALC883_MITAC] = "mitac",
8023 [ALC883_CLEVO_M720] = "clevo-m720",
8024 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8025 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8026 [ALC883_AUTO] = "auto",
8029 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8030 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8031 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8032 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8033 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8034 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8035 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8036 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8037 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8038 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8039 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8040 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8041 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8042 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8043 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8044 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8045 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8046 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8047 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8048 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8049 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8050 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8051 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8052 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8053 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8054 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8055 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8056 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8057 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8058 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8059 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8060 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8061 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8062 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8063 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8064 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8065 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8066 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8067 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8068 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8069 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8070 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8071 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8072 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8073 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8074 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8075 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8076 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8077 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8078 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8079 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8080 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8081 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8082 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8083 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8084 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8085 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8086 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8090 static struct alc_config_preset alc883_presets[] = {
8091 [ALC883_3ST_2ch_DIG] = {
8092 .mixers = { alc883_3ST_2ch_mixer },
8093 .init_verbs = { alc883_init_verbs },
8094 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8095 .dac_nids = alc883_dac_nids,
8096 .dig_out_nid = ALC883_DIGOUT_NID,
8097 .dig_in_nid = ALC883_DIGIN_NID,
8098 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8099 .channel_mode = alc883_3ST_2ch_modes,
8100 .input_mux = &alc883_capture_source,
8102 [ALC883_3ST_6ch_DIG] = {
8103 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8104 .init_verbs = { alc883_init_verbs },
8105 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8106 .dac_nids = alc883_dac_nids,
8107 .dig_out_nid = ALC883_DIGOUT_NID,
8108 .dig_in_nid = ALC883_DIGIN_NID,
8109 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8110 .channel_mode = alc883_3ST_6ch_modes,
8112 .input_mux = &alc883_capture_source,
8114 [ALC883_3ST_6ch] = {
8115 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8116 .init_verbs = { alc883_init_verbs },
8117 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8118 .dac_nids = alc883_dac_nids,
8119 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8120 .channel_mode = alc883_3ST_6ch_modes,
8122 .input_mux = &alc883_capture_source,
8124 [ALC883_3ST_6ch_INTEL] = {
8125 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8126 .init_verbs = { alc883_init_verbs },
8127 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8128 .dac_nids = alc883_dac_nids,
8129 .dig_out_nid = ALC883_DIGOUT_NID,
8130 .dig_in_nid = ALC883_DIGIN_NID,
8131 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8132 .channel_mode = alc883_3ST_6ch_intel_modes,
8134 .input_mux = &alc883_3stack_6ch_intel,
8136 [ALC883_6ST_DIG] = {
8137 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8138 .init_verbs = { alc883_init_verbs },
8139 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8140 .dac_nids = alc883_dac_nids,
8141 .dig_out_nid = ALC883_DIGOUT_NID,
8142 .dig_in_nid = ALC883_DIGIN_NID,
8143 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8144 .channel_mode = alc883_sixstack_modes,
8145 .input_mux = &alc883_capture_source,
8147 [ALC883_TARGA_DIG] = {
8148 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8149 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8150 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8151 .dac_nids = alc883_dac_nids,
8152 .dig_out_nid = ALC883_DIGOUT_NID,
8153 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8154 .channel_mode = alc883_3ST_6ch_modes,
8156 .input_mux = &alc883_capture_source,
8157 .unsol_event = alc883_tagra_unsol_event,
8158 .init_hook = alc883_tagra_automute,
8160 [ALC883_TARGA_2ch_DIG] = {
8161 .mixers = { alc883_tagra_2ch_mixer},
8162 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8163 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8164 .dac_nids = alc883_dac_nids,
8165 .dig_out_nid = ALC883_DIGOUT_NID,
8166 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8167 .channel_mode = alc883_3ST_2ch_modes,
8168 .input_mux = &alc883_capture_source,
8169 .unsol_event = alc883_tagra_unsol_event,
8170 .init_hook = alc883_tagra_automute,
8173 .mixers = { alc883_base_mixer },
8174 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8175 * and the headphone jack. Turn this on and rely on the
8176 * standard mute methods whenever the user wants to turn
8177 * these outputs off.
8179 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8180 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8181 .dac_nids = alc883_dac_nids,
8182 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8183 .channel_mode = alc883_3ST_2ch_modes,
8184 .input_mux = &alc883_capture_source,
8186 [ALC883_ACER_ASPIRE] = {
8187 .mixers = { alc883_acer_aspire_mixer },
8188 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8189 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8190 .dac_nids = alc883_dac_nids,
8191 .dig_out_nid = ALC883_DIGOUT_NID,
8192 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8193 .channel_mode = alc883_3ST_2ch_modes,
8194 .input_mux = &alc883_capture_source,
8195 .unsol_event = alc883_acer_aspire_unsol_event,
8196 .init_hook = alc883_acer_aspire_automute,
8199 .mixers = { alc883_fivestack_mixer,
8200 alc883_chmode_mixer },
8201 .init_verbs = { alc883_init_verbs,
8202 alc883_medion_eapd_verbs },
8203 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8204 .dac_nids = alc883_dac_nids,
8205 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8206 .channel_mode = alc883_sixstack_modes,
8207 .input_mux = &alc883_capture_source,
8209 [ALC883_MEDION_MD2] = {
8210 .mixers = { alc883_medion_md2_mixer},
8211 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8212 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8213 .dac_nids = alc883_dac_nids,
8214 .dig_out_nid = ALC883_DIGOUT_NID,
8215 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8216 .channel_mode = alc883_3ST_2ch_modes,
8217 .input_mux = &alc883_capture_source,
8218 .unsol_event = alc883_medion_md2_unsol_event,
8219 .init_hook = alc883_medion_md2_automute,
8221 [ALC883_LAPTOP_EAPD] = {
8222 .mixers = { alc883_base_mixer },
8223 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8224 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8225 .dac_nids = alc883_dac_nids,
8226 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8227 .channel_mode = alc883_3ST_2ch_modes,
8228 .input_mux = &alc883_capture_source,
8230 [ALC883_CLEVO_M720] = {
8231 .mixers = { alc883_clevo_m720_mixer },
8232 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8233 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8234 .dac_nids = alc883_dac_nids,
8235 .dig_out_nid = ALC883_DIGOUT_NID,
8236 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8237 .channel_mode = alc883_3ST_2ch_modes,
8238 .input_mux = &alc883_capture_source,
8239 .unsol_event = alc883_clevo_m720_unsol_event,
8240 .init_hook = alc883_clevo_m720_automute,
8242 [ALC883_LENOVO_101E_2ch] = {
8243 .mixers = { alc883_lenovo_101e_2ch_mixer},
8244 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8245 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8246 .dac_nids = alc883_dac_nids,
8247 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8248 .channel_mode = alc883_3ST_2ch_modes,
8249 .input_mux = &alc883_lenovo_101e_capture_source,
8250 .unsol_event = alc883_lenovo_101e_unsol_event,
8251 .init_hook = alc883_lenovo_101e_all_automute,
8253 [ALC883_LENOVO_NB0763] = {
8254 .mixers = { alc883_lenovo_nb0763_mixer },
8255 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8256 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8257 .dac_nids = alc883_dac_nids,
8258 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8259 .channel_mode = alc883_3ST_2ch_modes,
8261 .input_mux = &alc883_lenovo_nb0763_capture_source,
8262 .unsol_event = alc883_medion_md2_unsol_event,
8263 .init_hook = alc883_medion_md2_automute,
8265 [ALC888_LENOVO_MS7195_DIG] = {
8266 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8267 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8268 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8269 .dac_nids = alc883_dac_nids,
8270 .dig_out_nid = ALC883_DIGOUT_NID,
8271 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8272 .channel_mode = alc883_3ST_6ch_modes,
8274 .input_mux = &alc883_capture_source,
8275 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8276 .init_hook = alc888_lenovo_ms7195_front_automute,
8278 [ALC883_HAIER_W66] = {
8279 .mixers = { alc883_tagra_2ch_mixer},
8280 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8281 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8282 .dac_nids = alc883_dac_nids,
8283 .dig_out_nid = ALC883_DIGOUT_NID,
8284 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8285 .channel_mode = alc883_3ST_2ch_modes,
8286 .input_mux = &alc883_capture_source,
8287 .unsol_event = alc883_haier_w66_unsol_event,
8288 .init_hook = alc883_haier_w66_automute,
8291 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8292 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8293 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8294 .dac_nids = alc883_dac_nids,
8295 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8296 .channel_mode = alc888_3st_hp_modes,
8298 .input_mux = &alc883_capture_source,
8300 [ALC888_6ST_DELL] = {
8301 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8302 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8303 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8304 .dac_nids = alc883_dac_nids,
8305 .dig_out_nid = ALC883_DIGOUT_NID,
8306 .dig_in_nid = ALC883_DIGIN_NID,
8307 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8308 .channel_mode = alc883_sixstack_modes,
8309 .input_mux = &alc883_capture_source,
8310 .unsol_event = alc888_6st_dell_unsol_event,
8311 .init_hook = alc888_6st_dell_front_automute,
8314 .mixers = { alc883_mitac_mixer },
8315 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8316 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8317 .dac_nids = alc883_dac_nids,
8318 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8319 .channel_mode = alc883_3ST_2ch_modes,
8320 .input_mux = &alc883_capture_source,
8321 .unsol_event = alc883_mitac_unsol_event,
8322 .init_hook = alc883_mitac_automute,
8324 [ALC883_FUJITSU_PI2515] = {
8325 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8326 .init_verbs = { alc883_init_verbs,
8327 alc883_2ch_fujitsu_pi2515_verbs},
8328 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8329 .dac_nids = alc883_dac_nids,
8330 .dig_out_nid = ALC883_DIGOUT_NID,
8331 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8332 .channel_mode = alc883_3ST_2ch_modes,
8333 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8334 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8335 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8341 * BIOS auto configuration
8343 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8344 hda_nid_t nid, int pin_type,
8348 struct alc_spec *spec = codec->spec;
8351 alc_set_pin_output(codec, nid, pin_type);
8352 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8355 idx = spec->multiout.dac_nids[dac_idx] - 2;
8356 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8360 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8362 struct alc_spec *spec = codec->spec;
8365 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8366 for (i = 0; i <= HDA_SIDE; i++) {
8367 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8368 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8370 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8375 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8377 struct alc_spec *spec = codec->spec;
8380 pin = spec->autocfg.hp_pins[0];
8381 if (pin) /* connect to front */
8383 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8384 pin = spec->autocfg.speaker_pins[0];
8386 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8389 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8390 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8392 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8394 struct alc_spec *spec = codec->spec;
8397 for (i = 0; i < AUTO_PIN_LAST; i++) {
8398 hda_nid_t nid = spec->autocfg.input_pins[i];
8399 if (alc883_is_input_pin(nid)) {
8400 snd_hda_codec_write(codec, nid, 0,
8401 AC_VERB_SET_PIN_WIDGET_CONTROL,
8402 (i <= AUTO_PIN_FRONT_MIC ?
8403 PIN_VREF80 : PIN_IN));
8404 if (nid != ALC883_PIN_CD_NID)
8405 snd_hda_codec_write(codec, nid, 0,
8406 AC_VERB_SET_AMP_GAIN_MUTE,
8412 #define alc883_auto_init_input_src alc882_auto_init_input_src
8414 /* almost identical with ALC880 parser... */
8415 static int alc883_parse_auto_config(struct hda_codec *codec)
8417 struct alc_spec *spec = codec->spec;
8418 int err = alc880_parse_auto_config(codec);
8423 return 0; /* no config found */
8425 err = alc_auto_add_mic_boost(codec);
8429 /* hack - override the init verbs */
8430 spec->init_verbs[0] = alc883_auto_init_verbs;
8431 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8434 return 1; /* config found */
8437 /* additional initialization for auto-configuration model */
8438 static void alc883_auto_init(struct hda_codec *codec)
8440 struct alc_spec *spec = codec->spec;
8441 alc883_auto_init_multi_out(codec);
8442 alc883_auto_init_hp_out(codec);
8443 alc883_auto_init_analog_input(codec);
8444 alc883_auto_init_input_src(codec);
8445 if (spec->unsol_event)
8446 alc_sku_automute(codec);
8449 static int patch_alc883(struct hda_codec *codec)
8451 struct alc_spec *spec;
8452 int err, board_config;
8454 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8460 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8462 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8465 if (board_config < 0) {
8466 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8467 "trying auto-probe from BIOS...\n");
8468 board_config = ALC883_AUTO;
8471 if (board_config == ALC883_AUTO) {
8472 /* automatic parse from the BIOS config */
8473 err = alc883_parse_auto_config(codec);
8479 "hda_codec: Cannot set up configuration "
8480 "from BIOS. Using base mode...\n");
8481 board_config = ALC883_3ST_2ch_DIG;
8485 if (board_config != ALC883_AUTO)
8486 setup_preset(spec, &alc883_presets[board_config]);
8488 switch (codec->vendor_id) {
8490 spec->stream_name_analog = "ALC888 Analog";
8491 spec->stream_name_digital = "ALC888 Digital";
8494 spec->stream_name_analog = "ALC889 Analog";
8495 spec->stream_name_digital = "ALC889 Digital";
8498 spec->stream_name_analog = "ALC883 Analog";
8499 spec->stream_name_digital = "ALC883 Digital";
8503 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8504 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8505 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8507 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8508 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8510 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8511 spec->adc_nids = alc883_adc_nids;
8512 spec->capsrc_nids = alc883_capsrc_nids;
8514 spec->vmaster_nid = 0x0c;
8516 codec->patch_ops = alc_patch_ops;
8517 if (board_config == ALC883_AUTO)
8518 spec->init_hook = alc883_auto_init;
8520 #ifdef CONFIG_SND_HDA_POWER_SAVE
8521 if (!spec->loopback.amplist)
8522 spec->loopback.amplist = alc883_loopbacks;
8532 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8533 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8535 #define alc262_dac_nids alc260_dac_nids
8536 #define alc262_adc_nids alc882_adc_nids
8537 #define alc262_adc_nids_alt alc882_adc_nids_alt
8538 #define alc262_capsrc_nids alc882_capsrc_nids
8539 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8541 #define alc262_modes alc260_modes
8542 #define alc262_capture_source alc882_capture_source
8544 static hda_nid_t alc262_dmic_adc_nids[1] = {
8549 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8551 static struct snd_kcontrol_new alc262_base_mixer[] = {
8552 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8553 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8554 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8555 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8556 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8557 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8558 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8559 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8560 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8561 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8562 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8563 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8564 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8565 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8567 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8568 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8569 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8573 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8574 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8575 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8576 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8577 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8578 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8579 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8581 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8582 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8583 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8584 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8585 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8586 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8587 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8588 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8589 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8593 /* update HP, line and mono-out pins according to the master switch */
8594 static void alc262_hp_master_update(struct hda_codec *codec)
8596 struct alc_spec *spec = codec->spec;
8597 int val = spec->master_sw;
8600 snd_hda_codec_write_cache(codec, 0x1b, 0,
8601 AC_VERB_SET_PIN_WIDGET_CONTROL,
8603 snd_hda_codec_write_cache(codec, 0x15, 0,
8604 AC_VERB_SET_PIN_WIDGET_CONTROL,
8606 /* mono (speaker) depending on the HP jack sense */
8607 val = val && !spec->jack_present;
8608 snd_hda_codec_write_cache(codec, 0x16, 0,
8609 AC_VERB_SET_PIN_WIDGET_CONTROL,
8613 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8615 struct alc_spec *spec = codec->spec;
8616 unsigned int presence;
8617 presence = snd_hda_codec_read(codec, 0x1b, 0,
8618 AC_VERB_GET_PIN_SENSE, 0);
8619 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8620 alc262_hp_master_update(codec);
8623 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8625 if ((res >> 26) != ALC880_HP_EVENT)
8627 alc262_hp_bpc_automute(codec);
8630 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8632 struct alc_spec *spec = codec->spec;
8633 unsigned int presence;
8634 presence = snd_hda_codec_read(codec, 0x15, 0,
8635 AC_VERB_GET_PIN_SENSE, 0);
8636 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8637 alc262_hp_master_update(codec);
8640 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8643 if ((res >> 26) != ALC880_HP_EVENT)
8645 alc262_hp_wildwest_automute(codec);
8648 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8649 struct snd_ctl_elem_value *ucontrol)
8651 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8652 struct alc_spec *spec = codec->spec;
8653 *ucontrol->value.integer.value = spec->master_sw;
8657 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8658 struct snd_ctl_elem_value *ucontrol)
8660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8661 struct alc_spec *spec = codec->spec;
8662 int val = !!*ucontrol->value.integer.value;
8664 if (val == spec->master_sw)
8666 spec->master_sw = val;
8667 alc262_hp_master_update(codec);
8671 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8674 .name = "Master Playback Switch",
8675 .info = snd_ctl_boolean_mono_info,
8676 .get = alc262_hp_master_sw_get,
8677 .put = alc262_hp_master_sw_put,
8679 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8680 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8681 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8682 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8684 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8686 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8688 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8689 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8690 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8691 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8692 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8693 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8694 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8695 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8696 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8697 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8698 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8699 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8703 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8706 .name = "Master Playback Switch",
8707 .info = snd_ctl_boolean_mono_info,
8708 .get = alc262_hp_master_sw_get,
8709 .put = alc262_hp_master_sw_put,
8711 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8712 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8713 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8715 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8717 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8719 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8720 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8721 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8722 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8723 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8724 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8725 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8726 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8727 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8731 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8732 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8733 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8734 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8738 /* mute/unmute internal speaker according to the hp jack and mute state */
8739 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8741 struct alc_spec *spec = codec->spec;
8743 if (force || !spec->sense_updated) {
8744 unsigned int present;
8745 present = snd_hda_codec_read(codec, 0x15, 0,
8746 AC_VERB_GET_PIN_SENSE, 0);
8747 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8748 spec->sense_updated = 1;
8750 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8751 spec->jack_present ? HDA_AMP_MUTE : 0);
8754 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8757 if ((res >> 26) != ALC880_HP_EVENT)
8759 alc262_hp_t5735_automute(codec, 1);
8762 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8764 alc262_hp_t5735_automute(codec, 1);
8767 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8768 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8769 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8770 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8771 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8773 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8774 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8778 static struct hda_verb alc262_hp_t5735_verbs[] = {
8779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8782 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8786 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8787 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8788 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8789 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8790 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8791 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8792 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8796 static struct hda_verb alc262_hp_rp5700_verbs[] = {
8797 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8798 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8799 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8800 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8801 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8802 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8803 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8804 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8805 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8810 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8817 /* bind hp and internal speaker mute (with plug check) */
8818 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8819 struct snd_ctl_elem_value *ucontrol)
8821 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8822 long *valp = ucontrol->value.integer.value;
8825 /* change hp mute */
8826 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8828 valp[0] ? 0 : HDA_AMP_MUTE);
8829 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8831 valp[1] ? 0 : HDA_AMP_MUTE);
8833 /* change speaker according to HP jack state */
8834 struct alc_spec *spec = codec->spec;
8836 if (spec->jack_present)
8837 mute = HDA_AMP_MUTE;
8839 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8841 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8842 HDA_AMP_MUTE, mute);
8847 static struct snd_kcontrol_new alc262_sony_mixer[] = {
8848 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8851 .name = "Master Playback Switch",
8852 .info = snd_hda_mixer_amp_switch_info,
8853 .get = snd_hda_mixer_amp_switch_get,
8854 .put = alc262_sony_master_sw_put,
8855 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8859 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8860 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8864 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8865 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8866 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8867 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8869 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8870 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8871 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8875 #define alc262_capture_mixer alc882_capture_mixer
8876 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
8879 * generic initialization of ADC, input mixers and output mixers
8881 static struct hda_verb alc262_init_verbs[] = {
8883 * Unmute ADC0-2 and set the default input to mic-in
8885 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8886 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8887 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8889 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8890 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8892 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8894 * Note: PASD motherboards uses the Line In 2 as the input for
8895 * front panel mic (mic 2)
8897 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8898 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8899 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8900 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8901 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8902 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8905 * Set up output mixers (0x0c - 0x0e)
8907 /* set vol=0 to output mixers */
8908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8909 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8910 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8911 /* set up input amps for analog loopback */
8912 /* Amp Indices: DAC = 0, mixer = 1 */
8913 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8914 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8915 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8916 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8917 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8918 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8921 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8922 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8923 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8924 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8925 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8927 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8929 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8930 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8931 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8933 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8934 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8936 /* FIXME: use matrix-type input source selection */
8937 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8938 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8939 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8940 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8941 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8942 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8944 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8945 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8949 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8950 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8957 static struct hda_verb alc262_eapd_verbs[] = {
8958 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8959 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8963 static struct hda_verb alc262_hippo_unsol_verbs[] = {
8964 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8965 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8969 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8970 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8971 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8972 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8974 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8975 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8979 static struct hda_verb alc262_sony_unsol_verbs[] = {
8980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8982 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8984 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8989 static struct hda_input_mux alc262_dmic_capture_source = {
8992 { "Int DMic", 0x9 },
8997 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
8998 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8999 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9003 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9004 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9006 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9007 /* The multiple "Capture Source" controls confuse alsamixer
9008 * So call somewhat different..
9010 /* .name = "Capture Source", */
9011 .name = "Input Source",
9013 .info = alc_mux_enum_info,
9014 .get = alc_mux_enum_get,
9015 .put = alc_mux_enum_put,
9020 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9021 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9023 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9024 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9025 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9026 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9027 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9028 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9032 static void alc262_dmic_automute(struct hda_codec *codec)
9034 unsigned int present;
9036 present = snd_hda_codec_read(codec, 0x18, 0,
9037 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9038 snd_hda_codec_write(codec, 0x22, 0,
9039 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9042 /* toggle speaker-output according to the hp-jack state */
9043 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9045 unsigned int present;
9048 present = snd_hda_codec_read(codec, 0x15, 0,
9049 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9050 bits = present ? 0 : PIN_OUT;
9051 snd_hda_codec_write(codec, 0x14, 0,
9052 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9057 /* unsolicited event for HP jack sensing */
9058 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9061 if ((res >> 26) == ALC880_HP_EVENT)
9062 alc262_toshiba_s06_speaker_automute(codec);
9063 if ((res >> 26) == ALC880_MIC_EVENT)
9064 alc262_dmic_automute(codec);
9068 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9070 alc262_toshiba_s06_speaker_automute(codec);
9071 alc262_dmic_automute(codec);
9074 /* mute/unmute internal speaker according to the hp jack and mute state */
9075 static void alc262_hippo_automute(struct hda_codec *codec)
9077 struct alc_spec *spec = codec->spec;
9079 unsigned int present;
9081 /* need to execute and sync at first */
9082 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9083 present = snd_hda_codec_read(codec, 0x15, 0,
9084 AC_VERB_GET_PIN_SENSE, 0);
9085 spec->jack_present = (present & 0x80000000) != 0;
9086 if (spec->jack_present) {
9087 /* mute internal speaker */
9088 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9089 HDA_AMP_MUTE, HDA_AMP_MUTE);
9091 /* unmute internal speaker if necessary */
9092 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9093 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9094 HDA_AMP_MUTE, mute);
9098 /* unsolicited event for HP jack sensing */
9099 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9102 if ((res >> 26) != ALC880_HP_EVENT)
9104 alc262_hippo_automute(codec);
9107 static void alc262_hippo1_automute(struct hda_codec *codec)
9110 unsigned int present;
9112 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9113 present = snd_hda_codec_read(codec, 0x1b, 0,
9114 AC_VERB_GET_PIN_SENSE, 0);
9115 present = (present & 0x80000000) != 0;
9117 /* mute internal speaker */
9118 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9119 HDA_AMP_MUTE, HDA_AMP_MUTE);
9121 /* unmute internal speaker if necessary */
9122 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9123 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9124 HDA_AMP_MUTE, mute);
9128 /* unsolicited event for HP jack sensing */
9129 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9132 if ((res >> 26) != ALC880_HP_EVENT)
9134 alc262_hippo1_automute(codec);
9140 * 0x16 = internal speaker
9141 * 0x18 = external mic
9144 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9145 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9146 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9150 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9157 static struct hda_verb alc262_nec_verbs[] = {
9158 /* Unmute Speaker */
9159 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9162 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9165 /* External mic to headphone */
9166 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9167 /* External mic to speaker */
9168 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9174 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9175 * 0x1b = port replicator headphone out
9178 #define ALC_HP_EVENT 0x37
9180 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9181 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9182 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9183 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9184 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9188 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9189 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9190 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9194 static struct hda_input_mux alc262_fujitsu_capture_source = {
9203 static struct hda_input_mux alc262_HP_capture_source = {
9207 { "Front Mic", 0x1 },
9214 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9218 { "Front Mic", 0x2 },
9224 /* mute/unmute internal speaker according to the hp jacks and mute state */
9225 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9227 struct alc_spec *spec = codec->spec;
9230 if (force || !spec->sense_updated) {
9231 unsigned int present;
9232 /* need to execute and sync at first */
9233 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9234 /* check laptop HP jack */
9235 present = snd_hda_codec_read(codec, 0x14, 0,
9236 AC_VERB_GET_PIN_SENSE, 0);
9237 /* need to execute and sync at first */
9238 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9239 /* check docking HP jack */
9240 present |= snd_hda_codec_read(codec, 0x1b, 0,
9241 AC_VERB_GET_PIN_SENSE, 0);
9242 if (present & AC_PINSENSE_PRESENCE)
9243 spec->jack_present = 1;
9245 spec->jack_present = 0;
9246 spec->sense_updated = 1;
9248 /* unmute internal speaker only if both HPs are unplugged and
9249 * master switch is on
9251 if (spec->jack_present)
9252 mute = HDA_AMP_MUTE;
9254 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9255 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9256 HDA_AMP_MUTE, mute);
9259 /* unsolicited event for HP jack sensing */
9260 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9263 if ((res >> 26) != ALC_HP_EVENT)
9265 alc262_fujitsu_automute(codec, 1);
9268 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9270 alc262_fujitsu_automute(codec, 1);
9273 /* bind volumes of both NID 0x0c and 0x0d */
9274 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9275 .ops = &snd_hda_bind_vol,
9277 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9278 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9283 /* mute/unmute internal speaker according to the hp jack and mute state */
9284 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9286 struct alc_spec *spec = codec->spec;
9289 if (force || !spec->sense_updated) {
9290 unsigned int present_int_hp;
9291 /* need to execute and sync at first */
9292 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9293 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9294 AC_VERB_GET_PIN_SENSE, 0);
9295 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9296 spec->sense_updated = 1;
9298 if (spec->jack_present) {
9299 /* mute internal speaker */
9300 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9301 HDA_AMP_MUTE, HDA_AMP_MUTE);
9302 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9303 HDA_AMP_MUTE, HDA_AMP_MUTE);
9305 /* unmute internal speaker if necessary */
9306 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9307 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9308 HDA_AMP_MUTE, mute);
9309 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9310 HDA_AMP_MUTE, mute);
9314 /* unsolicited event for HP jack sensing */
9315 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9318 if ((res >> 26) != ALC_HP_EVENT)
9320 alc262_lenovo_3000_automute(codec, 1);
9323 /* bind hp and internal speaker mute (with plug check) */
9324 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9325 struct snd_ctl_elem_value *ucontrol)
9327 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9328 long *valp = ucontrol->value.integer.value;
9331 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9333 valp ? 0 : HDA_AMP_MUTE);
9334 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9336 valp ? 0 : HDA_AMP_MUTE);
9339 alc262_fujitsu_automute(codec, 0);
9343 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9344 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9347 .name = "Master Playback Switch",
9348 .info = snd_hda_mixer_amp_switch_info,
9349 .get = snd_hda_mixer_amp_switch_get,
9350 .put = alc262_fujitsu_master_sw_put,
9351 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9353 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9354 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9355 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9356 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9357 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9358 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9359 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9360 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9361 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9362 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9366 /* bind hp and internal speaker mute (with plug check) */
9367 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9368 struct snd_ctl_elem_value *ucontrol)
9370 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9371 long *valp = ucontrol->value.integer.value;
9374 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9376 valp ? 0 : HDA_AMP_MUTE);
9379 alc262_lenovo_3000_automute(codec, 0);
9383 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9384 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9386 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9387 .name = "Master Playback Switch",
9388 .info = snd_hda_mixer_amp_switch_info,
9389 .get = snd_hda_mixer_amp_switch_get,
9390 .put = alc262_lenovo_3000_master_sw_put,
9391 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9393 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9394 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9395 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9396 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9397 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9398 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9399 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9400 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9404 /* additional init verbs for Benq laptops */
9405 static struct hda_verb alc262_EAPD_verbs[] = {
9406 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9407 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9411 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9412 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9413 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9415 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9416 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9420 /* Samsung Q1 Ultra Vista model setup */
9421 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9422 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9423 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9426 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9427 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9431 static struct hda_verb alc262_ultra_verbs[] = {
9433 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9437 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9438 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9440 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9443 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9445 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9446 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9448 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9449 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9450 /* ADC, choose mic */
9451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9464 /* mute/unmute internal speaker according to the hp jack and mute state */
9465 static void alc262_ultra_automute(struct hda_codec *codec)
9467 struct alc_spec *spec = codec->spec;
9471 /* auto-mute only when HP is used as HP */
9472 if (!spec->cur_mux[0]) {
9473 unsigned int present;
9474 /* need to execute and sync at first */
9475 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9476 present = snd_hda_codec_read(codec, 0x15, 0,
9477 AC_VERB_GET_PIN_SENSE, 0);
9478 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9479 if (spec->jack_present)
9480 mute = HDA_AMP_MUTE;
9482 /* mute/unmute internal speaker */
9483 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9484 HDA_AMP_MUTE, mute);
9485 /* mute/unmute HP */
9486 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9487 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9490 /* unsolicited event for HP jack sensing */
9491 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9494 if ((res >> 26) != ALC880_HP_EVENT)
9496 alc262_ultra_automute(codec);
9499 static struct hda_input_mux alc262_ultra_capture_source = {
9503 { "Headphone", 0x7 },
9507 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9508 struct snd_ctl_elem_value *ucontrol)
9510 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9511 struct alc_spec *spec = codec->spec;
9514 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9517 /* reprogram the HP pin as mic or HP according to the input source */
9518 snd_hda_codec_write_cache(codec, 0x15, 0,
9519 AC_VERB_SET_PIN_WIDGET_CONTROL,
9520 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9521 alc262_ultra_automute(codec); /* mute/unmute HP */
9525 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9526 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9527 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9530 .name = "Capture Source",
9531 .info = alc882_mux_enum_info,
9532 .get = alc882_mux_enum_get,
9533 .put = alc262_ultra_mux_enum_put,
9538 /* add playback controls from the parsed DAC table */
9539 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9540 const struct auto_pin_cfg *cfg)
9545 spec->multiout.num_dacs = 1; /* only use one dac */
9546 spec->multiout.dac_nids = spec->private_dac_nids;
9547 spec->multiout.dac_nids[0] = 2;
9549 nid = cfg->line_out_pins[0];
9551 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9552 "Front Playback Volume",
9553 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9556 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9557 "Front Playback Switch",
9558 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9563 nid = cfg->speaker_pins[0];
9566 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9567 "Speaker Playback Volume",
9568 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9572 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9573 "Speaker Playback Switch",
9574 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9579 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9580 "Speaker Playback Switch",
9581 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9587 nid = cfg->hp_pins[0];
9589 /* spec->multiout.hp_nid = 2; */
9591 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9592 "Headphone Playback Volume",
9593 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9597 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9598 "Headphone Playback Switch",
9599 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9604 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9605 "Headphone Playback Switch",
9606 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9615 /* identical with ALC880 */
9616 #define alc262_auto_create_analog_input_ctls \
9617 alc880_auto_create_analog_input_ctls
9620 * generic initialization of ADC, input mixers and output mixers
9622 static struct hda_verb alc262_volume_init_verbs[] = {
9624 * Unmute ADC0-2 and set the default input to mic-in
9626 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9627 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9628 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9630 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9631 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9633 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9635 * Note: PASD motherboards uses the Line In 2 as the input for
9636 * front panel mic (mic 2)
9638 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9640 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9646 * Set up output mixers (0x0c - 0x0f)
9648 /* set vol=0 to output mixers */
9649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9653 /* set up input amps for analog loopback */
9654 /* Amp Indices: DAC = 0, mixer = 1 */
9655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9657 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9658 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9659 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9660 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9662 /* FIXME: use matrix-type input source selection */
9663 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9664 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9665 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9667 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9668 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9670 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9672 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9673 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9683 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9685 * Unmute ADC0-2 and set the default input to mic-in
9687 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9689 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9690 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9691 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9692 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9694 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9696 * Note: PASD motherboards uses the Line In 2 as the input for
9697 * front panel mic (mic 2)
9699 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9700 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9701 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9702 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9703 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9704 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9705 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9706 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9709 * Set up output mixers (0x0c - 0x0e)
9711 /* set vol=0 to output mixers */
9712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9713 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9716 /* set up input amps for analog loopback */
9717 /* Amp Indices: DAC = 0, mixer = 1 */
9718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9725 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9727 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9729 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9732 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9733 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9735 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9736 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9737 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9738 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9739 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9744 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9745 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9746 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9749 /* FIXME: use matrix-type input source selection */
9750 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9751 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9752 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9753 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9754 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9757 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9758 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9759 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9760 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9763 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9764 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9767 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9772 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9774 * Unmute ADC0-2 and set the default input to mic-in
9776 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9778 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9779 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9780 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9781 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9783 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9785 * Note: PASD motherboards uses the Line In 2 as the input for front
9788 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9789 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9790 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9791 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9792 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9793 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9794 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9798 * Set up output mixers (0x0c - 0x0e)
9800 /* set vol=0 to output mixers */
9801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9802 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9803 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9805 /* set up input amps for analog loopback */
9806 /* Amp Indices: DAC = 0, mixer = 1 */
9807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9810 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9811 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9812 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9815 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9816 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9817 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9818 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9819 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9820 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9821 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9823 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9826 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9827 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9829 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9832 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9833 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9834 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9836 /* FIXME: use matrix-type input source selection */
9837 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9838 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9840 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9841 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9842 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9843 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9844 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9845 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9847 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9848 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9849 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9850 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9851 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9852 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9853 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9855 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9856 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9860 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9863 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9868 #ifdef CONFIG_SND_HDA_POWER_SAVE
9869 #define alc262_loopbacks alc880_loopbacks
9872 /* pcm configuration: identiacal with ALC880 */
9873 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
9874 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
9875 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
9876 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
9879 * BIOS auto configuration
9881 static int alc262_parse_auto_config(struct hda_codec *codec)
9883 struct alc_spec *spec = codec->spec;
9885 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9887 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9891 if (!spec->autocfg.line_outs)
9892 return 0; /* can't find valid BIOS pin config */
9893 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9896 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9900 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9902 if (spec->autocfg.dig_out_pin)
9903 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9904 if (spec->autocfg.dig_in_pin)
9905 spec->dig_in_nid = ALC262_DIGIN_NID;
9907 if (spec->kctl_alloc)
9908 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9910 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
9911 spec->num_mux_defs = 1;
9912 spec->input_mux = &spec->private_imux;
9914 err = alc_auto_add_mic_boost(codec);
9921 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
9922 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
9923 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
9924 #define alc262_auto_init_input_src alc882_auto_init_input_src
9927 /* init callback for auto-configuration model -- overriding the default init */
9928 static void alc262_auto_init(struct hda_codec *codec)
9930 struct alc_spec *spec = codec->spec;
9931 alc262_auto_init_multi_out(codec);
9932 alc262_auto_init_hp_out(codec);
9933 alc262_auto_init_analog_input(codec);
9934 alc262_auto_init_input_src(codec);
9935 if (spec->unsol_event)
9936 alc_sku_automute(codec);
9940 * configuration and preset
9942 static const char *alc262_models[ALC262_MODEL_LAST] = {
9943 [ALC262_BASIC] = "basic",
9944 [ALC262_HIPPO] = "hippo",
9945 [ALC262_HIPPO_1] = "hippo_1",
9946 [ALC262_FUJITSU] = "fujitsu",
9947 [ALC262_HP_BPC] = "hp-bpc",
9948 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
9949 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
9950 [ALC262_HP_RP5700] = "hp-rp5700",
9951 [ALC262_BENQ_ED8] = "benq",
9952 [ALC262_BENQ_T31] = "benq-t31",
9953 [ALC262_SONY_ASSAMD] = "sony-assamd",
9954 [ALC262_ULTRA] = "ultra",
9955 [ALC262_LENOVO_3000] = "lenovo-3000",
9956 [ALC262_NEC] = "nec",
9957 [ALC262_AUTO] = "auto",
9960 static struct snd_pci_quirk alc262_cfg_tbl[] = {
9961 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9962 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
9963 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
9964 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
9965 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9966 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
9967 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
9968 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
9969 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
9970 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
9971 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
9972 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
9973 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
9974 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
9975 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
9976 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
9977 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
9978 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
9979 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9980 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9981 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
9982 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9983 ALC262_HP_TC_T5735),
9984 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
9985 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9986 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
9987 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9988 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9989 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9990 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9991 ALC262_SONY_ASSAMD),
9992 SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
9993 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9994 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9995 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
9996 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
9997 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
9998 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9999 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10000 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10004 static struct alc_config_preset alc262_presets[] = {
10006 .mixers = { alc262_base_mixer },
10007 .init_verbs = { alc262_init_verbs },
10008 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10009 .dac_nids = alc262_dac_nids,
10011 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10012 .channel_mode = alc262_modes,
10013 .input_mux = &alc262_capture_source,
10016 .mixers = { alc262_base_mixer },
10017 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10018 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10019 .dac_nids = alc262_dac_nids,
10021 .dig_out_nid = ALC262_DIGOUT_NID,
10022 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10023 .channel_mode = alc262_modes,
10024 .input_mux = &alc262_capture_source,
10025 .unsol_event = alc262_hippo_unsol_event,
10026 .init_hook = alc262_hippo_automute,
10028 [ALC262_HIPPO_1] = {
10029 .mixers = { alc262_hippo1_mixer },
10030 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10031 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10032 .dac_nids = alc262_dac_nids,
10034 .dig_out_nid = ALC262_DIGOUT_NID,
10035 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10036 .channel_mode = alc262_modes,
10037 .input_mux = &alc262_capture_source,
10038 .unsol_event = alc262_hippo1_unsol_event,
10039 .init_hook = alc262_hippo1_automute,
10041 [ALC262_FUJITSU] = {
10042 .mixers = { alc262_fujitsu_mixer },
10043 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10044 alc262_fujitsu_unsol_verbs },
10045 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10046 .dac_nids = alc262_dac_nids,
10048 .dig_out_nid = ALC262_DIGOUT_NID,
10049 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10050 .channel_mode = alc262_modes,
10051 .input_mux = &alc262_fujitsu_capture_source,
10052 .unsol_event = alc262_fujitsu_unsol_event,
10053 .init_hook = alc262_fujitsu_init_hook,
10055 [ALC262_HP_BPC] = {
10056 .mixers = { alc262_HP_BPC_mixer },
10057 .init_verbs = { alc262_HP_BPC_init_verbs },
10058 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10059 .dac_nids = alc262_dac_nids,
10061 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10062 .channel_mode = alc262_modes,
10063 .input_mux = &alc262_HP_capture_source,
10064 .unsol_event = alc262_hp_bpc_unsol_event,
10065 .init_hook = alc262_hp_bpc_automute,
10067 [ALC262_HP_BPC_D7000_WF] = {
10068 .mixers = { alc262_HP_BPC_WildWest_mixer },
10069 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10070 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10071 .dac_nids = alc262_dac_nids,
10073 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10074 .channel_mode = alc262_modes,
10075 .input_mux = &alc262_HP_D7000_capture_source,
10076 .unsol_event = alc262_hp_wildwest_unsol_event,
10077 .init_hook = alc262_hp_wildwest_automute,
10079 [ALC262_HP_BPC_D7000_WL] = {
10080 .mixers = { alc262_HP_BPC_WildWest_mixer,
10081 alc262_HP_BPC_WildWest_option_mixer },
10082 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10083 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10084 .dac_nids = alc262_dac_nids,
10086 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10087 .channel_mode = alc262_modes,
10088 .input_mux = &alc262_HP_D7000_capture_source,
10089 .unsol_event = alc262_hp_wildwest_unsol_event,
10090 .init_hook = alc262_hp_wildwest_automute,
10092 [ALC262_HP_TC_T5735] = {
10093 .mixers = { alc262_hp_t5735_mixer },
10094 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10095 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10096 .dac_nids = alc262_dac_nids,
10098 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10099 .channel_mode = alc262_modes,
10100 .input_mux = &alc262_capture_source,
10101 .unsol_event = alc262_hp_t5735_unsol_event,
10102 .init_hook = alc262_hp_t5735_init_hook,
10104 [ALC262_HP_RP5700] = {
10105 .mixers = { alc262_hp_rp5700_mixer },
10106 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10107 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10108 .dac_nids = alc262_dac_nids,
10109 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10110 .channel_mode = alc262_modes,
10111 .input_mux = &alc262_hp_rp5700_capture_source,
10113 [ALC262_BENQ_ED8] = {
10114 .mixers = { alc262_base_mixer },
10115 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10116 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10117 .dac_nids = alc262_dac_nids,
10119 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10120 .channel_mode = alc262_modes,
10121 .input_mux = &alc262_capture_source,
10123 [ALC262_SONY_ASSAMD] = {
10124 .mixers = { alc262_sony_mixer },
10125 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10126 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10127 .dac_nids = alc262_dac_nids,
10129 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10130 .channel_mode = alc262_modes,
10131 .input_mux = &alc262_capture_source,
10132 .unsol_event = alc262_hippo_unsol_event,
10133 .init_hook = alc262_hippo_automute,
10135 [ALC262_BENQ_T31] = {
10136 .mixers = { alc262_benq_t31_mixer },
10137 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10138 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10139 .dac_nids = alc262_dac_nids,
10141 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10142 .channel_mode = alc262_modes,
10143 .input_mux = &alc262_capture_source,
10144 .unsol_event = alc262_hippo_unsol_event,
10145 .init_hook = alc262_hippo_automute,
10148 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10149 .init_verbs = { alc262_ultra_verbs },
10150 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10151 .dac_nids = alc262_dac_nids,
10152 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10153 .channel_mode = alc262_modes,
10154 .input_mux = &alc262_ultra_capture_source,
10155 .adc_nids = alc262_adc_nids, /* ADC0 */
10156 .capsrc_nids = alc262_capsrc_nids,
10157 .num_adc_nids = 1, /* single ADC */
10158 .unsol_event = alc262_ultra_unsol_event,
10159 .init_hook = alc262_ultra_automute,
10161 [ALC262_LENOVO_3000] = {
10162 .mixers = { alc262_lenovo_3000_mixer },
10163 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10164 alc262_lenovo_3000_unsol_verbs },
10165 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10166 .dac_nids = alc262_dac_nids,
10168 .dig_out_nid = ALC262_DIGOUT_NID,
10169 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10170 .channel_mode = alc262_modes,
10171 .input_mux = &alc262_fujitsu_capture_source,
10172 .unsol_event = alc262_lenovo_3000_unsol_event,
10175 .mixers = { alc262_nec_mixer },
10176 .init_verbs = { alc262_nec_verbs },
10177 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10178 .dac_nids = alc262_dac_nids,
10180 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10181 .channel_mode = alc262_modes,
10182 .input_mux = &alc262_capture_source,
10184 [ALC262_TOSHIBA_S06] = {
10185 .mixers = { alc262_toshiba_s06_mixer },
10186 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10187 alc262_eapd_verbs },
10188 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10189 .capsrc_nids = alc262_dmic_capsrc_nids,
10190 .dac_nids = alc262_dac_nids,
10191 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10192 .dig_out_nid = ALC262_DIGOUT_NID,
10193 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10194 .channel_mode = alc262_modes,
10195 .input_mux = &alc262_dmic_capture_source,
10196 .unsol_event = alc262_toshiba_s06_unsol_event,
10197 .init_hook = alc262_toshiba_s06_init_hook,
10201 static int patch_alc262(struct hda_codec *codec)
10203 struct alc_spec *spec;
10207 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10211 codec->spec = spec;
10213 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10218 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10219 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10220 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10221 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10225 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10227 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10231 if (board_config < 0) {
10232 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10233 "trying auto-probe from BIOS...\n");
10234 board_config = ALC262_AUTO;
10237 if (board_config == ALC262_AUTO) {
10238 /* automatic parse from the BIOS config */
10239 err = alc262_parse_auto_config(codec);
10245 "hda_codec: Cannot set up configuration "
10246 "from BIOS. Using base mode...\n");
10247 board_config = ALC262_BASIC;
10251 if (board_config != ALC262_AUTO)
10252 setup_preset(spec, &alc262_presets[board_config]);
10254 spec->stream_name_analog = "ALC262 Analog";
10255 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10256 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10258 spec->stream_name_digital = "ALC262 Digital";
10259 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10260 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10262 if (!spec->adc_nids && spec->input_mux) {
10263 /* check whether NID 0x07 is valid */
10264 unsigned int wcap = get_wcaps(codec, 0x07);
10267 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10268 if (wcap != AC_WID_AUD_IN) {
10269 spec->adc_nids = alc262_adc_nids_alt;
10270 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10271 spec->capsrc_nids = alc262_capsrc_nids_alt;
10272 spec->mixers[spec->num_mixers] =
10273 alc262_capture_alt_mixer;
10274 spec->num_mixers++;
10276 spec->adc_nids = alc262_adc_nids;
10277 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10278 spec->capsrc_nids = alc262_capsrc_nids;
10279 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10280 spec->num_mixers++;
10284 spec->vmaster_nid = 0x0c;
10286 codec->patch_ops = alc_patch_ops;
10287 if (board_config == ALC262_AUTO)
10288 spec->init_hook = alc262_auto_init;
10289 #ifdef CONFIG_SND_HDA_POWER_SAVE
10290 if (!spec->loopback.amplist)
10291 spec->loopback.amplist = alc262_loopbacks;
10298 * ALC268 channel source setting (2 channel)
10300 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10301 #define alc268_modes alc260_modes
10303 static hda_nid_t alc268_dac_nids[2] = {
10308 static hda_nid_t alc268_adc_nids[2] = {
10313 static hda_nid_t alc268_adc_nids_alt[1] = {
10318 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10320 static struct snd_kcontrol_new alc268_base_mixer[] = {
10321 /* output mixer control */
10322 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10323 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10326 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10327 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10328 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10332 /* bind Beep switches of both NID 0x0f and 0x10 */
10333 static struct hda_bind_ctls alc268_bind_beep_sw = {
10334 .ops = &snd_hda_bind_sw,
10336 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10337 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10342 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10343 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10344 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10348 static struct hda_verb alc268_eapd_verbs[] = {
10349 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10350 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10354 /* Toshiba specific */
10355 #define alc268_toshiba_automute alc262_hippo_automute
10357 static struct hda_verb alc268_toshiba_verbs[] = {
10358 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10362 static struct hda_input_mux alc268_acer_lc_capture_source = {
10370 /* Acer specific */
10371 /* bind volumes of both NID 0x02 and 0x03 */
10372 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10373 .ops = &snd_hda_bind_vol,
10375 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10376 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10381 /* mute/unmute internal speaker according to the hp jack and mute state */
10382 static void alc268_acer_automute(struct hda_codec *codec, int force)
10384 struct alc_spec *spec = codec->spec;
10387 if (force || !spec->sense_updated) {
10388 unsigned int present;
10389 present = snd_hda_codec_read(codec, 0x14, 0,
10390 AC_VERB_GET_PIN_SENSE, 0);
10391 spec->jack_present = (present & 0x80000000) != 0;
10392 spec->sense_updated = 1;
10394 if (spec->jack_present)
10395 mute = HDA_AMP_MUTE; /* mute internal speaker */
10396 else /* unmute internal speaker if necessary */
10397 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10398 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10399 HDA_AMP_MUTE, mute);
10403 /* bind hp and internal speaker mute (with plug check) */
10404 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10405 struct snd_ctl_elem_value *ucontrol)
10407 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10408 long *valp = ucontrol->value.integer.value;
10411 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10413 valp[0] ? 0 : HDA_AMP_MUTE);
10414 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10416 valp[1] ? 0 : HDA_AMP_MUTE);
10418 alc268_acer_automute(codec, 0);
10422 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10423 /* output mixer control */
10424 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10427 .name = "Master Playback Switch",
10428 .info = snd_hda_mixer_amp_switch_info,
10429 .get = snd_hda_mixer_amp_switch_get,
10430 .put = alc268_acer_master_sw_put,
10431 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10433 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10437 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10438 /* output mixer control */
10439 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10442 .name = "Master Playback Switch",
10443 .info = snd_hda_mixer_amp_switch_info,
10444 .get = snd_hda_mixer_amp_switch_get,
10445 .put = alc268_acer_master_sw_put,
10446 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10448 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10449 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10450 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10454 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10455 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10457 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10458 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10459 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10464 static struct hda_verb alc268_acer_verbs[] = {
10465 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10466 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10467 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10468 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10469 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10470 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10471 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10475 /* unsolicited event for HP jack sensing */
10476 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10479 if ((res >> 26) != ALC880_HP_EVENT)
10481 alc268_toshiba_automute(codec);
10484 static void alc268_acer_unsol_event(struct hda_codec *codec,
10487 if ((res >> 26) != ALC880_HP_EVENT)
10489 alc268_acer_automute(codec, 1);
10492 static void alc268_acer_init_hook(struct hda_codec *codec)
10494 alc268_acer_automute(codec, 1);
10497 /* toggle speaker-output according to the hp-jack state */
10498 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10500 unsigned int present;
10501 unsigned char bits;
10503 present = snd_hda_codec_read(codec, 0x15, 0,
10504 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10505 bits = present ? AMP_IN_MUTE(0) : 0;
10506 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10507 AMP_IN_MUTE(0), bits);
10508 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10509 AMP_IN_MUTE(0), bits);
10513 static void alc268_acer_mic_automute(struct hda_codec *codec)
10515 unsigned int present;
10517 present = snd_hda_codec_read(codec, 0x18, 0,
10518 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10519 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10520 present ? 0x0 : 0x6);
10523 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10526 if ((res >> 26) == ALC880_HP_EVENT)
10527 alc268_aspire_one_speaker_automute(codec);
10528 if ((res >> 26) == ALC880_MIC_EVENT)
10529 alc268_acer_mic_automute(codec);
10532 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10534 alc268_aspire_one_speaker_automute(codec);
10535 alc268_acer_mic_automute(codec);
10538 static struct snd_kcontrol_new alc268_dell_mixer[] = {
10539 /* output mixer control */
10540 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10541 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10544 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10545 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10549 static struct hda_verb alc268_dell_verbs[] = {
10550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10551 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10552 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10556 /* mute/unmute internal speaker according to the hp jack and mute state */
10557 static void alc268_dell_automute(struct hda_codec *codec)
10559 unsigned int present;
10562 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10563 if (present & 0x80000000)
10564 mute = HDA_AMP_MUTE;
10566 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10567 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10568 HDA_AMP_MUTE, mute);
10571 static void alc268_dell_unsol_event(struct hda_codec *codec,
10574 if ((res >> 26) != ALC880_HP_EVENT)
10576 alc268_dell_automute(codec);
10579 #define alc268_dell_init_hook alc268_dell_automute
10581 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10582 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10583 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10584 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10585 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10586 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10587 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10588 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10589 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10593 static struct hda_verb alc267_quanta_il1_verbs[] = {
10594 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10595 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10599 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10601 unsigned int present;
10603 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10604 & AC_PINSENSE_PRESENCE;
10605 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10606 present ? 0 : PIN_OUT);
10609 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10611 unsigned int present;
10613 present = snd_hda_codec_read(codec, 0x18, 0,
10614 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10615 snd_hda_codec_write(codec, 0x23, 0,
10616 AC_VERB_SET_CONNECT_SEL,
10617 present ? 0x00 : 0x01);
10620 static void alc267_quanta_il1_automute(struct hda_codec *codec)
10622 alc267_quanta_il1_hp_automute(codec);
10623 alc267_quanta_il1_mic_automute(codec);
10626 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10629 switch (res >> 26) {
10630 case ALC880_HP_EVENT:
10631 alc267_quanta_il1_hp_automute(codec);
10633 case ALC880_MIC_EVENT:
10634 alc267_quanta_il1_mic_automute(codec);
10640 * generic initialization of ADC, input mixers and output mixers
10642 static struct hda_verb alc268_base_init_verbs[] = {
10643 /* Unmute DAC0-1 and set vol = 0 */
10644 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10645 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10646 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10647 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10648 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10649 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10652 * Set up output mixers (0x0c - 0x0e)
10654 /* set vol=0 to output mixers */
10655 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10656 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10657 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10658 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10660 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10661 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10663 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10664 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10665 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10666 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10668 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10669 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10670 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10672 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10673 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10674 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10675 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10676 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10677 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10678 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10680 /* set PCBEEP vol = 0, mute connections */
10681 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10682 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10683 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10685 /* Unmute Selector 23h,24h and set the default input to mic-in */
10687 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10688 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10689 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10696 * generic initialization of ADC, input mixers and output mixers
10698 static struct hda_verb alc268_volume_init_verbs[] = {
10699 /* set output DAC */
10700 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10701 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10702 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10703 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10705 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10706 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10707 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10708 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10709 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10714 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10715 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10717 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10718 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10719 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10720 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10722 /* set PCBEEP vol = 0, mute connections */
10723 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10724 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10725 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10730 #define alc268_mux_enum_info alc_mux_enum_info
10731 #define alc268_mux_enum_get alc_mux_enum_get
10732 #define alc268_mux_enum_put alc_mux_enum_put
10734 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
10735 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10736 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10739 /* The multiple "Capture Source" controls confuse alsamixer
10740 * So call somewhat different..
10742 /* .name = "Capture Source", */
10743 .name = "Input Source",
10745 .info = alc268_mux_enum_info,
10746 .get = alc268_mux_enum_get,
10747 .put = alc268_mux_enum_put,
10752 static struct snd_kcontrol_new alc268_capture_mixer[] = {
10753 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10754 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10755 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
10756 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
10758 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10759 /* The multiple "Capture Source" controls confuse alsamixer
10760 * So call somewhat different..
10762 /* .name = "Capture Source", */
10763 .name = "Input Source",
10765 .info = alc268_mux_enum_info,
10766 .get = alc268_mux_enum_get,
10767 .put = alc268_mux_enum_put,
10772 static struct hda_input_mux alc268_capture_source = {
10776 { "Front Mic", 0x1 },
10782 static struct hda_input_mux alc268_acer_capture_source = {
10786 { "Internal Mic", 0x6 },
10791 #ifdef CONFIG_SND_DEBUG
10792 static struct snd_kcontrol_new alc268_test_mixer[] = {
10793 /* Volume widgets */
10794 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10795 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10796 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10797 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
10798 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
10799 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
10800 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
10801 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
10802 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
10803 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
10804 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
10805 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
10806 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
10807 /* The below appears problematic on some hardwares */
10808 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
10809 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10810 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
10811 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
10812 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
10814 /* Modes for retasking pin widgets */
10815 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
10816 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
10817 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
10818 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
10820 /* Controls for GPIO pins, assuming they are configured as outputs */
10821 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
10822 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
10823 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
10824 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
10826 /* Switches to allow the digital SPDIF output pin to be enabled.
10827 * The ALC268 does not have an SPDIF input.
10829 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
10831 /* A switch allowing EAPD to be enabled. Some laptops seem to use
10832 * this output to turn on an external amplifier.
10834 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
10835 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
10841 /* create input playback/capture controls for the given pin */
10842 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
10843 const char *ctlname, int idx)
10848 sprintf(name, "%s Playback Volume", ctlname);
10850 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10851 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
10855 } else if (nid == 0x15) {
10856 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10857 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
10863 sprintf(name, "%s Playback Switch", ctlname);
10864 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10865 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
10871 /* add playback controls from the parsed DAC table */
10872 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
10873 const struct auto_pin_cfg *cfg)
10878 spec->multiout.num_dacs = 2; /* only use one dac */
10879 spec->multiout.dac_nids = spec->private_dac_nids;
10880 spec->multiout.dac_nids[0] = 2;
10881 spec->multiout.dac_nids[1] = 3;
10883 nid = cfg->line_out_pins[0];
10885 alc268_new_analog_output(spec, nid, "Front", 0);
10887 nid = cfg->speaker_pins[0];
10889 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10890 "Speaker Playback Volume",
10891 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10895 nid = cfg->hp_pins[0];
10897 alc268_new_analog_output(spec, nid, "Headphone", 0);
10899 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
10901 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10902 "Mono Playback Switch",
10903 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
10910 /* create playback/capture controls for input pins */
10911 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10912 const struct auto_pin_cfg *cfg)
10914 struct hda_input_mux *imux = &spec->private_imux;
10917 for (i = 0; i < AUTO_PIN_LAST; i++) {
10918 switch(cfg->input_pins[i]) {
10920 idx1 = 0; /* Mic 1 */
10923 idx1 = 1; /* Mic 2 */
10926 idx1 = 2; /* Line In */
10933 idx1 = 6; /* digital mics */
10938 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10939 imux->items[imux->num_items].index = idx1;
10945 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
10947 struct alc_spec *spec = codec->spec;
10948 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10949 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10950 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10951 unsigned int dac_vol1, dac_vol2;
10954 snd_hda_codec_write(codec, speaker_nid, 0,
10955 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10956 snd_hda_codec_write(codec, 0x0f, 0,
10957 AC_VERB_SET_AMP_GAIN_MUTE,
10959 snd_hda_codec_write(codec, 0x10, 0,
10960 AC_VERB_SET_AMP_GAIN_MUTE,
10963 snd_hda_codec_write(codec, 0x0f, 0,
10964 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10965 snd_hda_codec_write(codec, 0x10, 0,
10966 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10969 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
10970 if (line_nid == 0x14)
10971 dac_vol2 = AMP_OUT_ZERO;
10972 else if (line_nid == 0x15)
10973 dac_vol1 = AMP_OUT_ZERO;
10974 if (hp_nid == 0x14)
10975 dac_vol2 = AMP_OUT_ZERO;
10976 else if (hp_nid == 0x15)
10977 dac_vol1 = AMP_OUT_ZERO;
10978 if (line_nid != 0x16 || hp_nid != 0x16 ||
10979 spec->autocfg.line_out_pins[1] != 0x16 ||
10980 spec->autocfg.line_out_pins[2] != 0x16)
10981 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10983 snd_hda_codec_write(codec, 0x02, 0,
10984 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10985 snd_hda_codec_write(codec, 0x03, 0,
10986 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10989 /* pcm configuration: identiacal with ALC880 */
10990 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
10991 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
10992 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
10993 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
10996 * BIOS auto configuration
10998 static int alc268_parse_auto_config(struct hda_codec *codec)
11000 struct alc_spec *spec = codec->spec;
11002 static hda_nid_t alc268_ignore[] = { 0 };
11004 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11008 if (!spec->autocfg.line_outs)
11009 return 0; /* can't find valid BIOS pin config */
11011 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11014 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11018 spec->multiout.max_channels = 2;
11020 /* digital only support output */
11021 if (spec->autocfg.dig_out_pin)
11022 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11024 if (spec->kctl_alloc)
11025 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11027 if (spec->autocfg.speaker_pins[0] != 0x1d)
11028 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11030 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11031 spec->num_mux_defs = 1;
11032 spec->input_mux = &spec->private_imux;
11034 err = alc_auto_add_mic_boost(codec);
11041 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11042 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11043 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11045 /* init callback for auto-configuration model -- overriding the default init */
11046 static void alc268_auto_init(struct hda_codec *codec)
11048 struct alc_spec *spec = codec->spec;
11049 alc268_auto_init_multi_out(codec);
11050 alc268_auto_init_hp_out(codec);
11051 alc268_auto_init_mono_speaker_out(codec);
11052 alc268_auto_init_analog_input(codec);
11053 if (spec->unsol_event)
11054 alc_sku_automute(codec);
11058 * configuration and preset
11060 static const char *alc268_models[ALC268_MODEL_LAST] = {
11061 [ALC267_QUANTA_IL1] = "quanta-il1",
11062 [ALC268_3ST] = "3stack",
11063 [ALC268_TOSHIBA] = "toshiba",
11064 [ALC268_ACER] = "acer",
11065 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11066 [ALC268_DELL] = "dell",
11067 [ALC268_ZEPTO] = "zepto",
11068 #ifdef CONFIG_SND_DEBUG
11069 [ALC268_TEST] = "test",
11071 [ALC268_AUTO] = "auto",
11074 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11075 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11076 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11077 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11078 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11079 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11080 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11081 ALC268_ACER_ASPIRE_ONE),
11082 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11083 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11084 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11085 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11086 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11087 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11088 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11089 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11090 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11094 static struct alc_config_preset alc268_presets[] = {
11095 [ALC267_QUANTA_IL1] = {
11096 .mixers = { alc267_quanta_il1_mixer },
11097 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11098 alc267_quanta_il1_verbs },
11099 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11100 .dac_nids = alc268_dac_nids,
11101 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11102 .adc_nids = alc268_adc_nids_alt,
11104 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11105 .channel_mode = alc268_modes,
11106 .input_mux = &alc268_capture_source,
11107 .unsol_event = alc267_quanta_il1_unsol_event,
11108 .init_hook = alc267_quanta_il1_automute,
11111 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11112 alc268_beep_mixer },
11113 .init_verbs = { alc268_base_init_verbs },
11114 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11115 .dac_nids = alc268_dac_nids,
11116 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11117 .adc_nids = alc268_adc_nids_alt,
11118 .capsrc_nids = alc268_capsrc_nids,
11120 .dig_out_nid = ALC268_DIGOUT_NID,
11121 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11122 .channel_mode = alc268_modes,
11123 .input_mux = &alc268_capture_source,
11125 [ALC268_TOSHIBA] = {
11126 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11127 alc268_beep_mixer },
11128 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11129 alc268_toshiba_verbs },
11130 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11131 .dac_nids = alc268_dac_nids,
11132 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11133 .adc_nids = alc268_adc_nids_alt,
11134 .capsrc_nids = alc268_capsrc_nids,
11136 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11137 .channel_mode = alc268_modes,
11138 .input_mux = &alc268_capture_source,
11139 .unsol_event = alc268_toshiba_unsol_event,
11140 .init_hook = alc268_toshiba_automute,
11143 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11144 alc268_beep_mixer },
11145 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11146 alc268_acer_verbs },
11147 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11148 .dac_nids = alc268_dac_nids,
11149 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11150 .adc_nids = alc268_adc_nids_alt,
11151 .capsrc_nids = alc268_capsrc_nids,
11153 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11154 .channel_mode = alc268_modes,
11155 .input_mux = &alc268_acer_capture_source,
11156 .unsol_event = alc268_acer_unsol_event,
11157 .init_hook = alc268_acer_init_hook,
11159 [ALC268_ACER_ASPIRE_ONE] = {
11160 .mixers = { alc268_acer_aspire_one_mixer,
11161 alc268_capture_alt_mixer },
11162 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11163 alc268_acer_aspire_one_verbs },
11164 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11165 .dac_nids = alc268_dac_nids,
11166 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11167 .adc_nids = alc268_adc_nids_alt,
11168 .capsrc_nids = alc268_capsrc_nids,
11170 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11171 .channel_mode = alc268_modes,
11172 .input_mux = &alc268_acer_lc_capture_source,
11173 .unsol_event = alc268_acer_lc_unsol_event,
11174 .init_hook = alc268_acer_lc_init_hook,
11177 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11178 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11179 alc268_dell_verbs },
11180 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11181 .dac_nids = alc268_dac_nids,
11183 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11184 .channel_mode = alc268_modes,
11185 .unsol_event = alc268_dell_unsol_event,
11186 .init_hook = alc268_dell_init_hook,
11187 .input_mux = &alc268_capture_source,
11190 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11191 alc268_beep_mixer },
11192 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11193 alc268_toshiba_verbs },
11194 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11195 .dac_nids = alc268_dac_nids,
11196 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11197 .adc_nids = alc268_adc_nids_alt,
11198 .capsrc_nids = alc268_capsrc_nids,
11200 .dig_out_nid = ALC268_DIGOUT_NID,
11201 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11202 .channel_mode = alc268_modes,
11203 .input_mux = &alc268_capture_source,
11204 .unsol_event = alc268_toshiba_unsol_event,
11205 .init_hook = alc268_toshiba_automute
11207 #ifdef CONFIG_SND_DEBUG
11209 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11210 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11211 alc268_volume_init_verbs },
11212 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11213 .dac_nids = alc268_dac_nids,
11214 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11215 .adc_nids = alc268_adc_nids_alt,
11216 .capsrc_nids = alc268_capsrc_nids,
11218 .dig_out_nid = ALC268_DIGOUT_NID,
11219 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11220 .channel_mode = alc268_modes,
11221 .input_mux = &alc268_capture_source,
11226 static int patch_alc268(struct hda_codec *codec)
11228 struct alc_spec *spec;
11232 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11236 codec->spec = spec;
11238 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11242 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11243 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11244 "trying auto-probe from BIOS...\n");
11245 board_config = ALC268_AUTO;
11248 if (board_config == ALC268_AUTO) {
11249 /* automatic parse from the BIOS config */
11250 err = alc268_parse_auto_config(codec);
11256 "hda_codec: Cannot set up configuration "
11257 "from BIOS. Using base mode...\n");
11258 board_config = ALC268_3ST;
11262 if (board_config != ALC268_AUTO)
11263 setup_preset(spec, &alc268_presets[board_config]);
11265 if (codec->vendor_id == 0x10ec0267) {
11266 spec->stream_name_analog = "ALC267 Analog";
11267 spec->stream_name_digital = "ALC267 Digital";
11269 spec->stream_name_analog = "ALC268 Analog";
11270 spec->stream_name_digital = "ALC268 Digital";
11273 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11274 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11275 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11277 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11279 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11280 /* override the amp caps for beep generator */
11281 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11282 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11283 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11284 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11285 (0 << AC_AMPCAP_MUTE_SHIFT));
11287 if (!spec->adc_nids && spec->input_mux) {
11288 /* check whether NID 0x07 is valid */
11289 unsigned int wcap = get_wcaps(codec, 0x07);
11293 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11294 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11295 spec->adc_nids = alc268_adc_nids_alt;
11296 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11297 spec->mixers[spec->num_mixers] =
11298 alc268_capture_alt_mixer;
11299 spec->num_mixers++;
11301 spec->adc_nids = alc268_adc_nids;
11302 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11303 spec->mixers[spec->num_mixers] =
11304 alc268_capture_mixer;
11305 spec->num_mixers++;
11307 spec->capsrc_nids = alc268_capsrc_nids;
11308 /* set default input source */
11309 for (i = 0; i < spec->num_adc_nids; i++)
11310 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11311 0, AC_VERB_SET_CONNECT_SEL,
11312 spec->input_mux->items[0].index);
11315 spec->vmaster_nid = 0x02;
11317 codec->patch_ops = alc_patch_ops;
11318 if (board_config == ALC268_AUTO)
11319 spec->init_hook = alc268_auto_init;
11325 * ALC269 channel source setting (2 channel)
11327 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11329 #define alc269_dac_nids alc260_dac_nids
11331 static hda_nid_t alc269_adc_nids[1] = {
11336 static hda_nid_t alc269_capsrc_nids[1] = {
11340 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11344 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11352 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11360 #define alc269_modes alc260_modes
11361 #define alc269_capture_source alc880_lg_lw_capture_source
11363 static struct snd_kcontrol_new alc269_base_mixer[] = {
11364 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11365 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11366 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11367 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11369 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11370 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11371 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11373 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11374 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11375 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11376 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11377 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11381 /* bind volumes of both NID 0x0c and 0x0d */
11382 static struct hda_bind_ctls alc269_epc_bind_vol = {
11383 .ops = &snd_hda_bind_vol,
11385 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11386 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11391 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11392 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11393 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11394 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11398 /* capture mixer elements */
11399 static struct snd_kcontrol_new alc269_capture_mixer[] = {
11400 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11401 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11403 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11404 /* The multiple "Capture Source" controls confuse alsamixer
11405 * So call somewhat different..
11407 /* .name = "Capture Source", */
11408 .name = "Input Source",
11410 .info = alc_mux_enum_info,
11411 .get = alc_mux_enum_get,
11412 .put = alc_mux_enum_put,
11417 /* capture mixer elements */
11418 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11419 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11420 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11425 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11426 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11427 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11432 * generic initialization of ADC, input mixers and output mixers
11434 static struct hda_verb alc269_init_verbs[] = {
11436 * Unmute ADC0 and set the default input to mic-in
11438 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11440 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11441 * analog-loopback mixer widget
11442 * Note: PASD motherboards uses the Line In 2 as the input for
11443 * front panel mic (mic 2)
11445 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11446 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11447 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11448 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11449 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11450 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11453 * Set up output mixers (0x0c - 0x0e)
11455 /* set vol=0 to output mixers */
11456 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11457 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11459 /* set up input amps for analog loopback */
11460 /* Amp Indices: DAC = 0, mixer = 1 */
11461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11466 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11470 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11471 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11472 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11473 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11474 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11476 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11477 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11478 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11479 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11480 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11481 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11482 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11484 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11485 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11487 /* FIXME: use matrix-type input source selection */
11488 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11489 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11490 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11491 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11492 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11496 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11497 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11501 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11502 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11503 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11504 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11506 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11507 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11508 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11512 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11513 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11514 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11515 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11517 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11518 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11522 /* toggle speaker-output according to the hp-jack state */
11523 static void alc269_speaker_automute(struct hda_codec *codec)
11525 unsigned int present;
11528 present = snd_hda_codec_read(codec, 0x15, 0,
11529 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11530 bits = present ? AMP_IN_MUTE(0) : 0;
11531 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11532 AMP_IN_MUTE(0), bits);
11533 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11534 AMP_IN_MUTE(0), bits);
11537 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11539 unsigned int present;
11541 present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0)
11542 & AC_PINSENSE_PRESENCE;
11543 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11547 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11549 unsigned int present;
11551 present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0)
11552 & AC_PINSENSE_PRESENCE;
11553 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11554 present ? AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0));
11555 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11556 present ? AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1));
11559 /* unsolicited event for HP jack sensing */
11560 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11563 if ((res >> 26) == ALC880_HP_EVENT)
11564 alc269_speaker_automute(codec);
11566 if ((res >> 26) == ALC880_MIC_EVENT)
11567 alc269_eeepc_dmic_automute(codec);
11570 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11572 alc269_speaker_automute(codec);
11573 alc269_eeepc_dmic_automute(codec);
11576 /* unsolicited event for HP jack sensing */
11577 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11580 if ((res >> 26) == ALC880_HP_EVENT)
11581 alc269_speaker_automute(codec);
11583 if ((res >> 26) == ALC880_MIC_EVENT)
11584 alc269_eeepc_amic_automute(codec);
11587 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11589 alc269_speaker_automute(codec);
11590 alc269_eeepc_amic_automute(codec);
11593 /* add playback controls from the parsed DAC table */
11594 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11595 const struct auto_pin_cfg *cfg)
11600 spec->multiout.num_dacs = 1; /* only use one dac */
11601 spec->multiout.dac_nids = spec->private_dac_nids;
11602 spec->multiout.dac_nids[0] = 2;
11604 nid = cfg->line_out_pins[0];
11606 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11607 "Front Playback Volume",
11608 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
11611 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11612 "Front Playback Switch",
11613 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11618 nid = cfg->speaker_pins[0];
11620 if (!cfg->line_out_pins[0]) {
11621 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11622 "Speaker Playback Volume",
11623 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11629 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11630 "Speaker Playback Switch",
11631 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11636 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11637 "Speaker Playback Switch",
11638 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11644 nid = cfg->hp_pins[0];
11646 /* spec->multiout.hp_nid = 2; */
11647 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
11648 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11649 "Headphone Playback Volume",
11650 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11656 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11657 "Headphone Playback Switch",
11658 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11663 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11664 "Headphone Playback Switch",
11665 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11674 #define alc269_auto_create_analog_input_ctls \
11675 alc880_auto_create_analog_input_ctls
11677 #ifdef CONFIG_SND_HDA_POWER_SAVE
11678 #define alc269_loopbacks alc880_loopbacks
11681 /* pcm configuration: identiacal with ALC880 */
11682 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
11683 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
11684 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
11685 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
11688 * BIOS auto configuration
11690 static int alc269_parse_auto_config(struct hda_codec *codec)
11692 struct alc_spec *spec = codec->spec;
11694 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
11696 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11701 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
11704 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
11708 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11710 if (spec->autocfg.dig_out_pin)
11711 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
11713 if (spec->kctl_alloc)
11714 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11716 /* create a beep mixer control if the pin 0x1d isn't assigned */
11717 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
11718 if (spec->autocfg.input_pins[i] == 0x1d)
11720 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
11721 spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
11723 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
11724 spec->num_mux_defs = 1;
11725 spec->input_mux = &spec->private_imux;
11726 /* set default input source */
11727 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
11728 0, AC_VERB_SET_CONNECT_SEL,
11729 spec->input_mux->items[0].index);
11731 err = alc_auto_add_mic_boost(codec);
11735 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
11736 spec->num_mixers++;
11741 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
11742 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
11743 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
11746 /* init callback for auto-configuration model -- overriding the default init */
11747 static void alc269_auto_init(struct hda_codec *codec)
11749 struct alc_spec *spec = codec->spec;
11750 alc269_auto_init_multi_out(codec);
11751 alc269_auto_init_hp_out(codec);
11752 alc269_auto_init_analog_input(codec);
11753 if (spec->unsol_event)
11754 alc_sku_automute(codec);
11758 * configuration and preset
11760 static const char *alc269_models[ALC269_MODEL_LAST] = {
11761 [ALC269_BASIC] = "basic",
11764 static struct snd_pci_quirk alc269_cfg_tbl[] = {
11765 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
11766 ALC269_ASUS_EEEPC_P703),
11767 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
11768 ALC269_ASUS_EEEPC_P901),
11772 static struct alc_config_preset alc269_presets[] = {
11774 .mixers = { alc269_base_mixer, alc269_capture_mixer },
11775 .init_verbs = { alc269_init_verbs },
11776 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
11777 .dac_nids = alc269_dac_nids,
11779 .num_channel_mode = ARRAY_SIZE(alc269_modes),
11780 .channel_mode = alc269_modes,
11781 .input_mux = &alc269_capture_source,
11783 [ALC269_ASUS_EEEPC_P703] = {
11784 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
11785 .init_verbs = { alc269_init_verbs,
11786 alc269_eeepc_amic_init_verbs },
11787 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
11788 .dac_nids = alc269_dac_nids,
11790 .num_channel_mode = ARRAY_SIZE(alc269_modes),
11791 .channel_mode = alc269_modes,
11792 .input_mux = &alc269_eeepc_amic_capture_source,
11793 .unsol_event = alc269_eeepc_amic_unsol_event,
11794 .init_hook = alc269_eeepc_amic_inithook,
11796 [ALC269_ASUS_EEEPC_P901] = {
11797 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
11798 .init_verbs = { alc269_init_verbs,
11799 alc269_eeepc_dmic_init_verbs },
11800 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
11801 .dac_nids = alc269_dac_nids,
11803 .num_channel_mode = ARRAY_SIZE(alc269_modes),
11804 .channel_mode = alc269_modes,
11805 .input_mux = &alc269_eeepc_dmic_capture_source,
11806 .unsol_event = alc269_eeepc_dmic_unsol_event,
11807 .init_hook = alc269_eeepc_dmic_inithook,
11811 static int patch_alc269(struct hda_codec *codec)
11813 struct alc_spec *spec;
11817 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11821 codec->spec = spec;
11823 alc_fix_pll_init(codec, 0x20, 0x04, 15);
11825 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
11829 if (board_config < 0) {
11830 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
11831 "trying auto-probe from BIOS...\n");
11832 board_config = ALC269_AUTO;
11835 if (board_config == ALC269_AUTO) {
11836 /* automatic parse from the BIOS config */
11837 err = alc269_parse_auto_config(codec);
11843 "hda_codec: Cannot set up configuration "
11844 "from BIOS. Using base mode...\n");
11845 board_config = ALC269_BASIC;
11849 if (board_config != ALC269_AUTO)
11850 setup_preset(spec, &alc269_presets[board_config]);
11852 spec->stream_name_analog = "ALC269 Analog";
11853 spec->stream_analog_playback = &alc269_pcm_analog_playback;
11854 spec->stream_analog_capture = &alc269_pcm_analog_capture;
11856 spec->stream_name_digital = "ALC269 Digital";
11857 spec->stream_digital_playback = &alc269_pcm_digital_playback;
11858 spec->stream_digital_capture = &alc269_pcm_digital_capture;
11860 spec->adc_nids = alc269_adc_nids;
11861 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
11862 spec->capsrc_nids = alc269_capsrc_nids;
11864 codec->patch_ops = alc_patch_ops;
11865 if (board_config == ALC269_AUTO)
11866 spec->init_hook = alc269_auto_init;
11867 #ifdef CONFIG_SND_HDA_POWER_SAVE
11868 if (!spec->loopback.amplist)
11869 spec->loopback.amplist = alc269_loopbacks;
11876 * ALC861 channel source setting (2/6 channel selection for 3-stack)
11880 * set the path ways for 2 channel output
11881 * need to set the codec line out and mic 1 pin widgets to inputs
11883 static struct hda_verb alc861_threestack_ch2_init[] = {
11884 /* set pin widget 1Ah (line in) for input */
11885 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11886 /* set pin widget 18h (mic1/2) for input, for mic also enable
11889 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11891 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11893 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11894 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11900 * need to set the codec line out and mic 1 pin widgets to outputs
11902 static struct hda_verb alc861_threestack_ch6_init[] = {
11903 /* set pin widget 1Ah (line in) for output (Back Surround)*/
11904 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11905 /* set pin widget 18h (mic1) for output (CLFE)*/
11906 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11908 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11909 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11911 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11913 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11914 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11919 static struct hda_channel_mode alc861_threestack_modes[2] = {
11920 { 2, alc861_threestack_ch2_init },
11921 { 6, alc861_threestack_ch6_init },
11923 /* Set mic1 as input and unmute the mixer */
11924 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
11925 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11926 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11929 /* Set mic1 as output and mute mixer */
11930 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
11931 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11932 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11936 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
11937 { 2, alc861_uniwill_m31_ch2_init },
11938 { 4, alc861_uniwill_m31_ch4_init },
11941 /* Set mic1 and line-in as input and unmute the mixer */
11942 static struct hda_verb alc861_asus_ch2_init[] = {
11943 /* set pin widget 1Ah (line in) for input */
11944 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11945 /* set pin widget 18h (mic1/2) for input, for mic also enable
11948 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11950 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11952 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11953 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11957 /* Set mic1 nad line-in as output and mute mixer */
11958 static struct hda_verb alc861_asus_ch6_init[] = {
11959 /* set pin widget 1Ah (line in) for output (Back Surround)*/
11960 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11961 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11962 /* set pin widget 18h (mic1) for output (CLFE)*/
11963 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11964 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11965 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11966 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11968 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11970 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11971 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11976 static struct hda_channel_mode alc861_asus_modes[2] = {
11977 { 2, alc861_asus_ch2_init },
11978 { 6, alc861_asus_ch6_init },
11983 static struct snd_kcontrol_new alc861_base_mixer[] = {
11984 /* output mixer control */
11985 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11986 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11987 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11988 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11989 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11991 /*Input mixer control */
11992 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11993 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11994 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11995 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11996 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11997 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11998 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11999 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12001 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12003 /* Capture mixer control */
12004 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12005 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12008 .name = "Capture Source",
12010 .info = alc_mux_enum_info,
12011 .get = alc_mux_enum_get,
12012 .put = alc_mux_enum_put,
12017 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12018 /* output mixer control */
12019 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12020 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12021 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12022 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12023 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12025 /* Input mixer control */
12026 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12027 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12028 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12029 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12030 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12031 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12033 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12034 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12037 /* Capture mixer control */
12038 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12039 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12042 .name = "Capture Source",
12044 .info = alc_mux_enum_info,
12045 .get = alc_mux_enum_get,
12046 .put = alc_mux_enum_put,
12049 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12050 .name = "Channel Mode",
12051 .info = alc_ch_mode_info,
12052 .get = alc_ch_mode_get,
12053 .put = alc_ch_mode_put,
12054 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12059 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12060 /* output mixer control */
12061 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12063 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12065 /*Capture mixer control */
12066 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12067 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12070 .name = "Capture Source",
12072 .info = alc_mux_enum_info,
12073 .get = alc_mux_enum_get,
12074 .put = alc_mux_enum_put,
12080 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12081 /* output mixer control */
12082 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12083 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12084 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12085 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12086 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12088 /* Input mixer control */
12089 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12090 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12091 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12092 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12093 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12094 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12095 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12096 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12097 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12100 /* Capture mixer control */
12101 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12102 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12105 .name = "Capture Source",
12107 .info = alc_mux_enum_info,
12108 .get = alc_mux_enum_get,
12109 .put = alc_mux_enum_put,
12112 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12113 .name = "Channel Mode",
12114 .info = alc_ch_mode_info,
12115 .get = alc_ch_mode_get,
12116 .put = alc_ch_mode_put,
12117 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12122 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12123 /* output mixer control */
12124 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12125 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12126 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12127 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12128 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12130 /* Input mixer control */
12131 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12132 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12133 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12134 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12135 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12136 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12138 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12139 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12142 /* Capture mixer control */
12143 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12144 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12147 .name = "Capture Source",
12149 .info = alc_mux_enum_info,
12150 .get = alc_mux_enum_get,
12151 .put = alc_mux_enum_put,
12154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12155 .name = "Channel Mode",
12156 .info = alc_ch_mode_info,
12157 .get = alc_ch_mode_get,
12158 .put = alc_ch_mode_put,
12159 .private_value = ARRAY_SIZE(alc861_asus_modes),
12164 /* additional mixer */
12165 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12166 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12167 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12168 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12169 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12174 * generic initialization of ADC, input mixers and output mixers
12176 static struct hda_verb alc861_base_init_verbs[] = {
12178 * Unmute ADC0 and set the default input to mic-in
12180 /* port-A for surround (rear panel) */
12181 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12182 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12183 /* port-B for mic-in (rear panel) with vref */
12184 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12185 /* port-C for line-in (rear panel) */
12186 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12187 /* port-D for Front */
12188 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12189 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12190 /* port-E for HP out (front panel) */
12191 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12192 /* route front PCM to HP */
12193 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12194 /* port-F for mic-in (front panel) with vref */
12195 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12196 /* port-G for CLFE (rear panel) */
12197 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12198 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12199 /* port-H for side (rear panel) */
12200 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12201 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12203 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12204 /* route front mic to ADC1*/
12205 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12206 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12208 /* Unmute DAC0~3 & spdif out*/
12209 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12210 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12211 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12212 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12215 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12216 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12217 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12218 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12219 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12221 /* Unmute Stereo Mixer 15 */
12222 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12223 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12227 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12228 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12229 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12230 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12231 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12232 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12233 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12235 /* hp used DAC 3 (Front) */
12236 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12242 static struct hda_verb alc861_threestack_init_verbs[] = {
12244 * Unmute ADC0 and set the default input to mic-in
12246 /* port-A for surround (rear panel) */
12247 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12248 /* port-B for mic-in (rear panel) with vref */
12249 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12250 /* port-C for line-in (rear panel) */
12251 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12252 /* port-D for Front */
12253 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12254 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12255 /* port-E for HP out (front panel) */
12256 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12257 /* route front PCM to HP */
12258 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12259 /* port-F for mic-in (front panel) with vref */
12260 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12261 /* port-G for CLFE (rear panel) */
12262 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12263 /* port-H for side (rear panel) */
12264 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12266 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12267 /* route front mic to ADC1*/
12268 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12270 /* Unmute DAC0~3 & spdif out*/
12271 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12272 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12273 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12274 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12277 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12278 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12279 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12280 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12281 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12283 /* Unmute Stereo Mixer 15 */
12284 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12285 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12286 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12287 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12289 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12290 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12291 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12292 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12293 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12294 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12295 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12296 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12297 /* hp used DAC 3 (Front) */
12298 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12299 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12303 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12305 * Unmute ADC0 and set the default input to mic-in
12307 /* port-A for surround (rear panel) */
12308 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12309 /* port-B for mic-in (rear panel) with vref */
12310 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12311 /* port-C for line-in (rear panel) */
12312 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12313 /* port-D for Front */
12314 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12315 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12316 /* port-E for HP out (front panel) */
12317 /* this has to be set to VREF80 */
12318 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12319 /* route front PCM to HP */
12320 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12321 /* port-F for mic-in (front panel) with vref */
12322 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12323 /* port-G for CLFE (rear panel) */
12324 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12325 /* port-H for side (rear panel) */
12326 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12328 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12329 /* route front mic to ADC1*/
12330 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12331 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12332 /* Unmute DAC0~3 & spdif out*/
12333 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12334 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12335 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12336 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12337 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12339 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12340 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12341 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12342 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12343 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12345 /* Unmute Stereo Mixer 15 */
12346 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12347 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12348 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12349 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12351 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12352 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12353 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12354 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12355 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12356 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12357 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12358 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12359 /* hp used DAC 3 (Front) */
12360 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12361 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12365 static struct hda_verb alc861_asus_init_verbs[] = {
12367 * Unmute ADC0 and set the default input to mic-in
12369 /* port-A for surround (rear panel)
12370 * according to codec#0 this is the HP jack
12372 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12373 /* route front PCM to HP */
12374 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12375 /* port-B for mic-in (rear panel) with vref */
12376 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12377 /* port-C for line-in (rear panel) */
12378 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12379 /* port-D for Front */
12380 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12381 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12382 /* port-E for HP out (front panel) */
12383 /* this has to be set to VREF80 */
12384 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12385 /* route front PCM to HP */
12386 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12387 /* port-F for mic-in (front panel) with vref */
12388 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12389 /* port-G for CLFE (rear panel) */
12390 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12391 /* port-H for side (rear panel) */
12392 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12394 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12395 /* route front mic to ADC1*/
12396 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12397 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12398 /* Unmute DAC0~3 & spdif out*/
12399 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12400 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12401 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12402 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12404 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12405 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12406 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12407 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12408 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12410 /* Unmute Stereo Mixer 15 */
12411 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12412 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12413 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12414 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12416 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12417 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12418 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12419 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12420 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12421 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12422 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12423 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12424 /* hp used DAC 3 (Front) */
12425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12426 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12430 /* additional init verbs for ASUS laptops */
12431 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12432 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12433 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12438 * generic initialization of ADC, input mixers and output mixers
12440 static struct hda_verb alc861_auto_init_verbs[] = {
12442 * Unmute ADC0 and set the default input to mic-in
12444 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12447 /* Unmute DAC0~3 & spdif out*/
12448 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12449 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12450 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12451 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12454 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12455 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12456 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12457 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12458 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12460 /* Unmute Stereo Mixer 15 */
12461 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12462 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12463 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12464 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12466 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12467 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12468 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12469 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12470 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12471 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12473 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12475 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12476 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12477 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12478 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12479 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12480 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12481 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12482 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12484 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
12489 static struct hda_verb alc861_toshiba_init_verbs[] = {
12490 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12495 /* toggle speaker-output according to the hp-jack state */
12496 static void alc861_toshiba_automute(struct hda_codec *codec)
12498 unsigned int present;
12500 present = snd_hda_codec_read(codec, 0x0f, 0,
12501 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12502 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12503 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12504 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12505 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12508 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12511 if ((res >> 26) == ALC880_HP_EVENT)
12512 alc861_toshiba_automute(codec);
12515 /* pcm configuration: identiacal with ALC880 */
12516 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
12517 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
12518 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
12519 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
12522 #define ALC861_DIGOUT_NID 0x07
12524 static struct hda_channel_mode alc861_8ch_modes[1] = {
12528 static hda_nid_t alc861_dac_nids[4] = {
12529 /* front, surround, clfe, side */
12530 0x03, 0x06, 0x05, 0x04
12533 static hda_nid_t alc660_dac_nids[3] = {
12534 /* front, clfe, surround */
12538 static hda_nid_t alc861_adc_nids[1] = {
12543 static struct hda_input_mux alc861_capture_source = {
12547 { "Front Mic", 0x3 },
12554 /* fill in the dac_nids table from the parsed pin configuration */
12555 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12556 const struct auto_pin_cfg *cfg)
12561 spec->multiout.dac_nids = spec->private_dac_nids;
12562 for (i = 0; i < cfg->line_outs; i++) {
12563 nid = cfg->line_out_pins[i];
12565 if (i >= ARRAY_SIZE(alc861_dac_nids))
12567 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12570 spec->multiout.num_dacs = cfg->line_outs;
12574 /* add playback controls from the parsed DAC table */
12575 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12576 const struct auto_pin_cfg *cfg)
12579 static const char *chname[4] = {
12580 "Front", "Surround", NULL /*CLFE*/, "Side"
12585 for (i = 0; i < cfg->line_outs; i++) {
12586 nid = spec->multiout.dac_nids[i];
12591 err = add_control(spec, ALC_CTL_BIND_MUTE,
12592 "Center Playback Switch",
12593 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12597 err = add_control(spec, ALC_CTL_BIND_MUTE,
12598 "LFE Playback Switch",
12599 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12604 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
12606 if (nid == alc861_dac_nids[idx])
12608 sprintf(name, "%s Playback Switch", chname[idx]);
12609 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12610 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12619 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
12627 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
12629 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12630 "Headphone Playback Switch",
12631 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12634 spec->multiout.hp_nid = nid;
12639 /* create playback/capture controls for input pins */
12640 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
12641 const struct auto_pin_cfg *cfg)
12643 struct hda_input_mux *imux = &spec->private_imux;
12644 int i, err, idx, idx1;
12646 for (i = 0; i < AUTO_PIN_LAST; i++) {
12647 switch (cfg->input_pins[i]) {
12650 idx = 2; /* Line In */
12654 idx = 2; /* Line In */
12658 idx = 1; /* Mic In */
12662 idx = 1; /* Mic In */
12672 err = new_analog_input(spec, cfg->input_pins[i],
12673 auto_pin_cfg_labels[i], idx, 0x15);
12677 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12678 imux->items[imux->num_items].index = idx1;
12684 static struct snd_kcontrol_new alc861_capture_mixer[] = {
12685 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12686 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12690 /* The multiple "Capture Source" controls confuse alsamixer
12691 * So call somewhat different..
12693 /* .name = "Capture Source", */
12694 .name = "Input Source",
12696 .info = alc_mux_enum_info,
12697 .get = alc_mux_enum_get,
12698 .put = alc_mux_enum_put,
12703 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
12705 int pin_type, int dac_idx)
12707 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
12709 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12713 static void alc861_auto_init_multi_out(struct hda_codec *codec)
12715 struct alc_spec *spec = codec->spec;
12718 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
12719 for (i = 0; i < spec->autocfg.line_outs; i++) {
12720 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12721 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12723 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
12724 spec->multiout.dac_nids[i]);
12728 static void alc861_auto_init_hp_out(struct hda_codec *codec)
12730 struct alc_spec *spec = codec->spec;
12733 pin = spec->autocfg.hp_pins[0];
12734 if (pin) /* connect to front */
12735 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
12736 spec->multiout.dac_nids[0]);
12737 pin = spec->autocfg.speaker_pins[0];
12739 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
12742 static void alc861_auto_init_analog_input(struct hda_codec *codec)
12744 struct alc_spec *spec = codec->spec;
12747 for (i = 0; i < AUTO_PIN_LAST; i++) {
12748 hda_nid_t nid = spec->autocfg.input_pins[i];
12749 if (nid >= 0x0c && nid <= 0x11) {
12750 snd_hda_codec_write(codec, nid, 0,
12751 AC_VERB_SET_PIN_WIDGET_CONTROL,
12752 i <= AUTO_PIN_FRONT_MIC ?
12753 PIN_VREF80 : PIN_IN);
12758 /* parse the BIOS configuration and set up the alc_spec */
12759 /* return 1 if successful, 0 if the proper config is not found,
12760 * or a negative error code
12762 static int alc861_parse_auto_config(struct hda_codec *codec)
12764 struct alc_spec *spec = codec->spec;
12766 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
12768 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12772 if (!spec->autocfg.line_outs)
12773 return 0; /* can't find valid BIOS pin config */
12775 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
12778 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
12781 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
12784 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
12788 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12790 if (spec->autocfg.dig_out_pin)
12791 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
12793 if (spec->kctl_alloc)
12794 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12796 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
12798 spec->num_mux_defs = 1;
12799 spec->input_mux = &spec->private_imux;
12801 spec->adc_nids = alc861_adc_nids;
12802 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
12803 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
12804 spec->num_mixers++;
12809 /* additional initialization for auto-configuration model */
12810 static void alc861_auto_init(struct hda_codec *codec)
12812 struct alc_spec *spec = codec->spec;
12813 alc861_auto_init_multi_out(codec);
12814 alc861_auto_init_hp_out(codec);
12815 alc861_auto_init_analog_input(codec);
12816 if (spec->unsol_event)
12817 alc_sku_automute(codec);
12820 #ifdef CONFIG_SND_HDA_POWER_SAVE
12821 static struct hda_amp_list alc861_loopbacks[] = {
12822 { 0x15, HDA_INPUT, 0 },
12823 { 0x15, HDA_INPUT, 1 },
12824 { 0x15, HDA_INPUT, 2 },
12825 { 0x15, HDA_INPUT, 3 },
12832 * configuration and preset
12834 static const char *alc861_models[ALC861_MODEL_LAST] = {
12835 [ALC861_3ST] = "3stack",
12836 [ALC660_3ST] = "3stack-660",
12837 [ALC861_3ST_DIG] = "3stack-dig",
12838 [ALC861_6ST_DIG] = "6stack-dig",
12839 [ALC861_UNIWILL_M31] = "uniwill-m31",
12840 [ALC861_TOSHIBA] = "toshiba",
12841 [ALC861_ASUS] = "asus",
12842 [ALC861_ASUS_LAPTOP] = "asus-laptop",
12843 [ALC861_AUTO] = "auto",
12846 static struct snd_pci_quirk alc861_cfg_tbl[] = {
12847 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
12848 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12849 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12850 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
12851 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
12852 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
12853 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
12854 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
12855 * Any other models that need this preset?
12857 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
12858 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
12859 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
12860 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
12861 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
12862 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
12863 /* FIXME: the below seems conflict */
12864 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
12865 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
12866 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
12870 static struct alc_config_preset alc861_presets[] = {
12872 .mixers = { alc861_3ST_mixer },
12873 .init_verbs = { alc861_threestack_init_verbs },
12874 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12875 .dac_nids = alc861_dac_nids,
12876 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12877 .channel_mode = alc861_threestack_modes,
12879 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12880 .adc_nids = alc861_adc_nids,
12881 .input_mux = &alc861_capture_source,
12883 [ALC861_3ST_DIG] = {
12884 .mixers = { alc861_base_mixer },
12885 .init_verbs = { alc861_threestack_init_verbs },
12886 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12887 .dac_nids = alc861_dac_nids,
12888 .dig_out_nid = ALC861_DIGOUT_NID,
12889 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12890 .channel_mode = alc861_threestack_modes,
12892 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12893 .adc_nids = alc861_adc_nids,
12894 .input_mux = &alc861_capture_source,
12896 [ALC861_6ST_DIG] = {
12897 .mixers = { alc861_base_mixer },
12898 .init_verbs = { alc861_base_init_verbs },
12899 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12900 .dac_nids = alc861_dac_nids,
12901 .dig_out_nid = ALC861_DIGOUT_NID,
12902 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
12903 .channel_mode = alc861_8ch_modes,
12904 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12905 .adc_nids = alc861_adc_nids,
12906 .input_mux = &alc861_capture_source,
12909 .mixers = { alc861_3ST_mixer },
12910 .init_verbs = { alc861_threestack_init_verbs },
12911 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
12912 .dac_nids = alc660_dac_nids,
12913 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12914 .channel_mode = alc861_threestack_modes,
12916 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12917 .adc_nids = alc861_adc_nids,
12918 .input_mux = &alc861_capture_source,
12920 [ALC861_UNIWILL_M31] = {
12921 .mixers = { alc861_uniwill_m31_mixer },
12922 .init_verbs = { alc861_uniwill_m31_init_verbs },
12923 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12924 .dac_nids = alc861_dac_nids,
12925 .dig_out_nid = ALC861_DIGOUT_NID,
12926 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
12927 .channel_mode = alc861_uniwill_m31_modes,
12929 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12930 .adc_nids = alc861_adc_nids,
12931 .input_mux = &alc861_capture_source,
12933 [ALC861_TOSHIBA] = {
12934 .mixers = { alc861_toshiba_mixer },
12935 .init_verbs = { alc861_base_init_verbs,
12936 alc861_toshiba_init_verbs },
12937 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12938 .dac_nids = alc861_dac_nids,
12939 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12940 .channel_mode = alc883_3ST_2ch_modes,
12941 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12942 .adc_nids = alc861_adc_nids,
12943 .input_mux = &alc861_capture_source,
12944 .unsol_event = alc861_toshiba_unsol_event,
12945 .init_hook = alc861_toshiba_automute,
12948 .mixers = { alc861_asus_mixer },
12949 .init_verbs = { alc861_asus_init_verbs },
12950 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12951 .dac_nids = alc861_dac_nids,
12952 .dig_out_nid = ALC861_DIGOUT_NID,
12953 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
12954 .channel_mode = alc861_asus_modes,
12957 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12958 .adc_nids = alc861_adc_nids,
12959 .input_mux = &alc861_capture_source,
12961 [ALC861_ASUS_LAPTOP] = {
12962 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
12963 .init_verbs = { alc861_asus_init_verbs,
12964 alc861_asus_laptop_init_verbs },
12965 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12966 .dac_nids = alc861_dac_nids,
12967 .dig_out_nid = ALC861_DIGOUT_NID,
12968 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12969 .channel_mode = alc883_3ST_2ch_modes,
12971 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12972 .adc_nids = alc861_adc_nids,
12973 .input_mux = &alc861_capture_source,
12978 static int patch_alc861(struct hda_codec *codec)
12980 struct alc_spec *spec;
12984 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12988 codec->spec = spec;
12990 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
12994 if (board_config < 0) {
12995 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
12996 "trying auto-probe from BIOS...\n");
12997 board_config = ALC861_AUTO;
13000 if (board_config == ALC861_AUTO) {
13001 /* automatic parse from the BIOS config */
13002 err = alc861_parse_auto_config(codec);
13008 "hda_codec: Cannot set up configuration "
13009 "from BIOS. Using base mode...\n");
13010 board_config = ALC861_3ST_DIG;
13014 if (board_config != ALC861_AUTO)
13015 setup_preset(spec, &alc861_presets[board_config]);
13017 spec->stream_name_analog = "ALC861 Analog";
13018 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13019 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13021 spec->stream_name_digital = "ALC861 Digital";
13022 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13023 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13025 spec->vmaster_nid = 0x03;
13027 codec->patch_ops = alc_patch_ops;
13028 if (board_config == ALC861_AUTO)
13029 spec->init_hook = alc861_auto_init;
13030 #ifdef CONFIG_SND_HDA_POWER_SAVE
13031 if (!spec->loopback.amplist)
13032 spec->loopback.amplist = alc861_loopbacks;
13039 * ALC861-VD support
13043 * In addition, an independent DAC
13045 #define ALC861VD_DIGOUT_NID 0x06
13047 static hda_nid_t alc861vd_dac_nids[4] = {
13048 /* front, surr, clfe, side surr */
13049 0x02, 0x03, 0x04, 0x05
13052 /* dac_nids for ALC660vd are in a different order - according to
13053 * Realtek's driver.
13054 * This should probably tesult in a different mixer for 6stack models
13055 * of ALC660vd codecs, but for now there is only 3stack mixer
13056 * - and it is the same as in 861vd.
13057 * adc_nids in ALC660vd are (is) the same as in 861vd
13059 static hda_nid_t alc660vd_dac_nids[3] = {
13060 /* front, rear, clfe, rear_surr */
13064 static hda_nid_t alc861vd_adc_nids[1] = {
13069 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13072 /* FIXME: should be a matrix-type input source selection */
13073 static struct hda_input_mux alc861vd_capture_source = {
13077 { "Front Mic", 0x1 },
13083 static struct hda_input_mux alc861vd_dallas_capture_source = {
13086 { "Ext Mic", 0x0 },
13087 { "Int Mic", 0x1 },
13091 static struct hda_input_mux alc861vd_hp_capture_source = {
13094 { "Front Mic", 0x0 },
13095 { "ATAPI Mic", 0x1 },
13099 #define alc861vd_mux_enum_info alc_mux_enum_info
13100 #define alc861vd_mux_enum_get alc_mux_enum_get
13101 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13102 #define alc861vd_mux_enum_put alc882_mux_enum_put
13107 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13114 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13115 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13116 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13117 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13118 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13125 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13126 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13127 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13128 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13129 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13133 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13134 { 6, alc861vd_6stack_ch6_init },
13135 { 8, alc861vd_6stack_ch8_init },
13138 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13140 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13141 .name = "Channel Mode",
13142 .info = alc_ch_mode_info,
13143 .get = alc_ch_mode_get,
13144 .put = alc_ch_mode_put,
13149 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13150 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13151 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13155 /* The multiple "Capture Source" controls confuse alsamixer
13156 * So call somewhat different..
13158 /* .name = "Capture Source", */
13159 .name = "Input Source",
13161 .info = alc861vd_mux_enum_info,
13162 .get = alc861vd_mux_enum_get,
13163 .put = alc861vd_mux_enum_put,
13168 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13169 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13171 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13172 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13173 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13175 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13176 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13178 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13180 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13182 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13183 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13185 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13186 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13188 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13190 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13194 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13195 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13196 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13198 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13199 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13201 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13202 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13204 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13205 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13210 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13211 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13212 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13214 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13216 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13220 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13221 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13222 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13224 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13225 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13227 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13228 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13230 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13231 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13236 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13237 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13238 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13239 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13241 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13244 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13247 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13248 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13249 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13251 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13252 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13257 /* Pin assignment: Speaker=0x14, HP = 0x15,
13258 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13260 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13261 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13262 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13263 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13264 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13265 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13266 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13267 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13268 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13269 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13270 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13271 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13272 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13276 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13277 * Front Mic=0x18, ATAPI Mic = 0x19,
13279 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13280 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13281 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13282 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13283 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13284 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13285 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13286 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13287 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13293 * generic initialization of ADC, input mixers and output mixers
13295 static struct hda_verb alc861vd_volume_init_verbs[] = {
13297 * Unmute ADC0 and set the default input to mic-in
13299 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13300 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13302 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13303 * the analog-loopback mixer widget
13305 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13306 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13307 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13308 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13309 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13310 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13312 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13319 * Set up output mixers (0x02 - 0x05)
13321 /* set vol=0 to output mixers */
13322 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13323 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13324 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13325 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13327 /* set up input amps for analog loopback */
13328 /* Amp Indices: DAC = 0, mixer = 1 */
13329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13331 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13335 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13336 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13342 * 3-stack pin configuration:
13343 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13345 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13347 * Set pin mode and muting
13349 /* set front pin widgets 0x14 for output */
13350 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13351 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13352 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13354 /* Mic (rear) pin: input vref at 80% */
13355 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13356 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13357 /* Front Mic pin: input vref at 80% */
13358 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13359 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13360 /* Line In pin: input */
13361 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13362 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13363 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13364 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13365 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13366 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13367 /* CD pin widget for input */
13368 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13374 * 6-stack pin configuration:
13376 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13378 * Set pin mode and muting
13380 /* set front pin widgets 0x14 for output */
13381 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13382 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13383 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13385 /* Rear Pin: output 1 (0x0d) */
13386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13388 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13389 /* CLFE Pin: output 2 (0x0e) */
13390 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13391 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13392 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13393 /* Side Pin: output 3 (0x0f) */
13394 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13395 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13396 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13398 /* Mic (rear) pin: input vref at 80% */
13399 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13401 /* Front Mic pin: input vref at 80% */
13402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13403 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13404 /* Line In pin: input */
13405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13406 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13407 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13411 /* CD pin widget for input */
13412 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13417 static struct hda_verb alc861vd_eapd_verbs[] = {
13418 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13422 static struct hda_verb alc660vd_eapd_verbs[] = {
13423 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13424 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13428 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13430 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13431 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13432 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13433 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13437 /* toggle speaker-output according to the hp-jack state */
13438 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13440 unsigned int present;
13441 unsigned char bits;
13443 present = snd_hda_codec_read(codec, 0x1b, 0,
13444 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13445 bits = present ? HDA_AMP_MUTE : 0;
13446 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13447 HDA_AMP_MUTE, bits);
13450 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13452 unsigned int present;
13453 unsigned char bits;
13455 present = snd_hda_codec_read(codec, 0x18, 0,
13456 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13457 bits = present ? HDA_AMP_MUTE : 0;
13458 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13459 HDA_AMP_MUTE, bits);
13462 static void alc861vd_lenovo_automute(struct hda_codec *codec)
13464 alc861vd_lenovo_hp_automute(codec);
13465 alc861vd_lenovo_mic_automute(codec);
13468 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13471 switch (res >> 26) {
13472 case ALC880_HP_EVENT:
13473 alc861vd_lenovo_hp_automute(codec);
13475 case ALC880_MIC_EVENT:
13476 alc861vd_lenovo_mic_automute(codec);
13481 static struct hda_verb alc861vd_dallas_verbs[] = {
13482 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13483 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13484 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13485 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13493 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13494 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13496 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13497 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13498 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13500 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13501 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13502 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13503 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13505 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13506 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13507 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13508 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13509 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13510 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13511 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13512 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13514 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13515 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13516 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13517 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13519 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13520 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13521 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13526 /* toggle speaker-output according to the hp-jack state */
13527 static void alc861vd_dallas_automute(struct hda_codec *codec)
13529 unsigned int present;
13531 present = snd_hda_codec_read(codec, 0x15, 0,
13532 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13533 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13534 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13537 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13539 if ((res >> 26) == ALC880_HP_EVENT)
13540 alc861vd_dallas_automute(codec);
13543 #ifdef CONFIG_SND_HDA_POWER_SAVE
13544 #define alc861vd_loopbacks alc880_loopbacks
13547 /* pcm configuration: identiacal with ALC880 */
13548 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
13549 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
13550 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
13551 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
13554 * configuration and preset
13556 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13557 [ALC660VD_3ST] = "3stack-660",
13558 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13559 [ALC861VD_3ST] = "3stack",
13560 [ALC861VD_3ST_DIG] = "3stack-digout",
13561 [ALC861VD_6ST_DIG] = "6stack-digout",
13562 [ALC861VD_LENOVO] = "lenovo",
13563 [ALC861VD_DALLAS] = "dallas",
13564 [ALC861VD_HP] = "hp",
13565 [ALC861VD_AUTO] = "auto",
13568 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13569 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13570 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13571 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13572 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13573 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
13574 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13575 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13576 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13577 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13578 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13579 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13580 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13581 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13582 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13583 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13584 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13585 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
13589 static struct alc_config_preset alc861vd_presets[] = {
13591 .mixers = { alc861vd_3st_mixer },
13592 .init_verbs = { alc861vd_volume_init_verbs,
13593 alc861vd_3stack_init_verbs },
13594 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13595 .dac_nids = alc660vd_dac_nids,
13596 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13597 .channel_mode = alc861vd_3stack_2ch_modes,
13598 .input_mux = &alc861vd_capture_source,
13600 [ALC660VD_3ST_DIG] = {
13601 .mixers = { alc861vd_3st_mixer },
13602 .init_verbs = { alc861vd_volume_init_verbs,
13603 alc861vd_3stack_init_verbs },
13604 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13605 .dac_nids = alc660vd_dac_nids,
13606 .dig_out_nid = ALC861VD_DIGOUT_NID,
13607 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13608 .channel_mode = alc861vd_3stack_2ch_modes,
13609 .input_mux = &alc861vd_capture_source,
13612 .mixers = { alc861vd_3st_mixer },
13613 .init_verbs = { alc861vd_volume_init_verbs,
13614 alc861vd_3stack_init_verbs },
13615 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13616 .dac_nids = alc861vd_dac_nids,
13617 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13618 .channel_mode = alc861vd_3stack_2ch_modes,
13619 .input_mux = &alc861vd_capture_source,
13621 [ALC861VD_3ST_DIG] = {
13622 .mixers = { alc861vd_3st_mixer },
13623 .init_verbs = { alc861vd_volume_init_verbs,
13624 alc861vd_3stack_init_verbs },
13625 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13626 .dac_nids = alc861vd_dac_nids,
13627 .dig_out_nid = ALC861VD_DIGOUT_NID,
13628 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13629 .channel_mode = alc861vd_3stack_2ch_modes,
13630 .input_mux = &alc861vd_capture_source,
13632 [ALC861VD_6ST_DIG] = {
13633 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
13634 .init_verbs = { alc861vd_volume_init_verbs,
13635 alc861vd_6stack_init_verbs },
13636 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13637 .dac_nids = alc861vd_dac_nids,
13638 .dig_out_nid = ALC861VD_DIGOUT_NID,
13639 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
13640 .channel_mode = alc861vd_6stack_modes,
13641 .input_mux = &alc861vd_capture_source,
13643 [ALC861VD_LENOVO] = {
13644 .mixers = { alc861vd_lenovo_mixer },
13645 .init_verbs = { alc861vd_volume_init_verbs,
13646 alc861vd_3stack_init_verbs,
13647 alc861vd_eapd_verbs,
13648 alc861vd_lenovo_unsol_verbs },
13649 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13650 .dac_nids = alc660vd_dac_nids,
13651 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13652 .channel_mode = alc861vd_3stack_2ch_modes,
13653 .input_mux = &alc861vd_capture_source,
13654 .unsol_event = alc861vd_lenovo_unsol_event,
13655 .init_hook = alc861vd_lenovo_automute,
13657 [ALC861VD_DALLAS] = {
13658 .mixers = { alc861vd_dallas_mixer },
13659 .init_verbs = { alc861vd_dallas_verbs },
13660 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13661 .dac_nids = alc861vd_dac_nids,
13662 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13663 .channel_mode = alc861vd_3stack_2ch_modes,
13664 .input_mux = &alc861vd_dallas_capture_source,
13665 .unsol_event = alc861vd_dallas_unsol_event,
13666 .init_hook = alc861vd_dallas_automute,
13669 .mixers = { alc861vd_hp_mixer },
13670 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
13671 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13672 .dac_nids = alc861vd_dac_nids,
13673 .dig_out_nid = ALC861VD_DIGOUT_NID,
13674 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13675 .channel_mode = alc861vd_3stack_2ch_modes,
13676 .input_mux = &alc861vd_hp_capture_source,
13677 .unsol_event = alc861vd_dallas_unsol_event,
13678 .init_hook = alc861vd_dallas_automute,
13683 * BIOS auto configuration
13685 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
13686 hda_nid_t nid, int pin_type, int dac_idx)
13688 alc_set_pin_output(codec, nid, pin_type);
13691 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
13693 struct alc_spec *spec = codec->spec;
13696 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13697 for (i = 0; i <= HDA_SIDE; i++) {
13698 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13699 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13701 alc861vd_auto_set_output_and_unmute(codec, nid,
13707 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
13709 struct alc_spec *spec = codec->spec;
13712 pin = spec->autocfg.hp_pins[0];
13713 if (pin) /* connect to front and use dac 0 */
13714 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13715 pin = spec->autocfg.speaker_pins[0];
13717 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13720 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
13721 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
13723 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
13725 struct alc_spec *spec = codec->spec;
13728 for (i = 0; i < AUTO_PIN_LAST; i++) {
13729 hda_nid_t nid = spec->autocfg.input_pins[i];
13730 if (alc861vd_is_input_pin(nid)) {
13731 snd_hda_codec_write(codec, nid, 0,
13732 AC_VERB_SET_PIN_WIDGET_CONTROL,
13733 i <= AUTO_PIN_FRONT_MIC ?
13734 PIN_VREF80 : PIN_IN);
13735 if (nid != ALC861VD_PIN_CD_NID)
13736 snd_hda_codec_write(codec, nid, 0,
13737 AC_VERB_SET_AMP_GAIN_MUTE,
13743 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
13745 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
13746 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
13748 /* add playback controls from the parsed DAC table */
13749 /* Based on ALC880 version. But ALC861VD has separate,
13750 * different NIDs for mute/unmute switch and volume control */
13751 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
13752 const struct auto_pin_cfg *cfg)
13755 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
13756 hda_nid_t nid_v, nid_s;
13759 for (i = 0; i < cfg->line_outs; i++) {
13760 if (!spec->multiout.dac_nids[i])
13762 nid_v = alc861vd_idx_to_mixer_vol(
13764 spec->multiout.dac_nids[i]));
13765 nid_s = alc861vd_idx_to_mixer_switch(
13767 spec->multiout.dac_nids[i]));
13771 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13772 "Center Playback Volume",
13773 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
13777 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13778 "LFE Playback Volume",
13779 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
13783 err = add_control(spec, ALC_CTL_BIND_MUTE,
13784 "Center Playback Switch",
13785 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
13789 err = add_control(spec, ALC_CTL_BIND_MUTE,
13790 "LFE Playback Switch",
13791 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
13796 sprintf(name, "%s Playback Volume", chname[i]);
13797 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13798 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
13802 sprintf(name, "%s Playback Switch", chname[i]);
13803 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13804 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
13813 /* add playback controls for speaker and HP outputs */
13814 /* Based on ALC880 version. But ALC861VD has separate,
13815 * different NIDs for mute/unmute switch and volume control */
13816 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
13817 hda_nid_t pin, const char *pfx)
13819 hda_nid_t nid_v, nid_s;
13826 if (alc880_is_fixed_pin(pin)) {
13827 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13828 /* specify the DAC as the extra output */
13829 if (!spec->multiout.hp_nid)
13830 spec->multiout.hp_nid = nid_v;
13832 spec->multiout.extra_out_nid[0] = nid_v;
13833 /* control HP volume/switch on the output mixer amp */
13834 nid_v = alc861vd_idx_to_mixer_vol(
13835 alc880_fixed_pin_idx(pin));
13836 nid_s = alc861vd_idx_to_mixer_switch(
13837 alc880_fixed_pin_idx(pin));
13839 sprintf(name, "%s Playback Volume", pfx);
13840 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13841 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
13844 sprintf(name, "%s Playback Switch", pfx);
13845 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13846 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
13849 } else if (alc880_is_multi_pin(pin)) {
13850 /* set manual connection */
13851 /* we have only a switch on HP-out PIN */
13852 sprintf(name, "%s Playback Switch", pfx);
13853 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13854 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13861 /* parse the BIOS configuration and set up the alc_spec
13862 * return 1 if successful, 0 if the proper config is not found,
13863 * or a negative error code
13864 * Based on ALC880 version - had to change it to override
13865 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
13866 static int alc861vd_parse_auto_config(struct hda_codec *codec)
13868 struct alc_spec *spec = codec->spec;
13870 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
13872 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13876 if (!spec->autocfg.line_outs)
13877 return 0; /* can't find valid BIOS pin config */
13879 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13882 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
13885 err = alc861vd_auto_create_extra_out(spec,
13886 spec->autocfg.speaker_pins[0],
13890 err = alc861vd_auto_create_extra_out(spec,
13891 spec->autocfg.hp_pins[0],
13895 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
13899 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13901 if (spec->autocfg.dig_out_pin)
13902 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
13904 if (spec->kctl_alloc)
13905 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13907 spec->init_verbs[spec->num_init_verbs++]
13908 = alc861vd_volume_init_verbs;
13910 spec->num_mux_defs = 1;
13911 spec->input_mux = &spec->private_imux;
13913 err = alc_auto_add_mic_boost(codec);
13920 /* additional initialization for auto-configuration model */
13921 static void alc861vd_auto_init(struct hda_codec *codec)
13923 struct alc_spec *spec = codec->spec;
13924 alc861vd_auto_init_multi_out(codec);
13925 alc861vd_auto_init_hp_out(codec);
13926 alc861vd_auto_init_analog_input(codec);
13927 alc861vd_auto_init_input_src(codec);
13928 if (spec->unsol_event)
13929 alc_sku_automute(codec);
13932 static int patch_alc861vd(struct hda_codec *codec)
13934 struct alc_spec *spec;
13935 int err, board_config;
13937 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13941 codec->spec = spec;
13943 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
13947 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
13948 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
13949 "ALC861VD, trying auto-probe from BIOS...\n");
13950 board_config = ALC861VD_AUTO;
13953 if (board_config == ALC861VD_AUTO) {
13954 /* automatic parse from the BIOS config */
13955 err = alc861vd_parse_auto_config(codec);
13961 "hda_codec: Cannot set up configuration "
13962 "from BIOS. Using base mode...\n");
13963 board_config = ALC861VD_3ST;
13967 if (board_config != ALC861VD_AUTO)
13968 setup_preset(spec, &alc861vd_presets[board_config]);
13970 if (codec->vendor_id == 0x10ec0660) {
13971 spec->stream_name_analog = "ALC660-VD Analog";
13972 spec->stream_name_digital = "ALC660-VD Digital";
13973 /* always turn on EAPD */
13974 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
13976 spec->stream_name_analog = "ALC861VD Analog";
13977 spec->stream_name_digital = "ALC861VD Digital";
13980 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
13981 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
13983 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
13984 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
13986 spec->adc_nids = alc861vd_adc_nids;
13987 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
13988 spec->capsrc_nids = alc861vd_capsrc_nids;
13990 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
13991 spec->num_mixers++;
13993 spec->vmaster_nid = 0x02;
13995 codec->patch_ops = alc_patch_ops;
13997 if (board_config == ALC861VD_AUTO)
13998 spec->init_hook = alc861vd_auto_init;
13999 #ifdef CONFIG_SND_HDA_POWER_SAVE
14000 if (!spec->loopback.amplist)
14001 spec->loopback.amplist = alc861vd_loopbacks;
14010 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14011 * configuration. Each pin widget can choose any input DACs and a mixer.
14012 * Each ADC is connected from a mixer of all inputs. This makes possible
14013 * 6-channel independent captures.
14015 * In addition, an independent DAC for the multi-playback (not used in this
14018 #define ALC662_DIGOUT_NID 0x06
14019 #define ALC662_DIGIN_NID 0x0a
14021 static hda_nid_t alc662_dac_nids[4] = {
14022 /* front, rear, clfe, rear_surr */
14026 static hda_nid_t alc662_adc_nids[1] = {
14031 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14034 /* FIXME: should be a matrix-type input source selection */
14035 static struct hda_input_mux alc662_capture_source = {
14039 { "Front Mic", 0x1 },
14045 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14053 static struct hda_input_mux alc662_eeepc_capture_source = {
14061 static struct hda_input_mux alc663_capture_source = {
14065 { "Front Mic", 0x1 },
14070 static struct hda_input_mux alc663_m51va_capture_source = {
14073 { "Ext-Mic", 0x0 },
14078 #define alc662_mux_enum_info alc_mux_enum_info
14079 #define alc662_mux_enum_get alc_mux_enum_get
14080 #define alc662_mux_enum_put alc882_mux_enum_put
14085 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14092 static struct hda_verb alc662_3ST_ch2_init[] = {
14093 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14094 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14095 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14096 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14103 static struct hda_verb alc662_3ST_ch6_init[] = {
14104 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14105 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14106 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14107 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14108 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14109 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14113 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14114 { 2, alc662_3ST_ch2_init },
14115 { 6, alc662_3ST_ch6_init },
14121 static struct hda_verb alc662_sixstack_ch6_init[] = {
14122 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14123 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14124 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14131 static struct hda_verb alc662_sixstack_ch8_init[] = {
14132 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14133 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14134 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14138 static struct hda_channel_mode alc662_5stack_modes[2] = {
14139 { 2, alc662_sixstack_ch6_init },
14140 { 6, alc662_sixstack_ch8_init },
14143 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14144 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14147 static struct snd_kcontrol_new alc662_base_mixer[] = {
14148 /* output mixer control */
14149 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14150 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14151 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14152 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14153 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14154 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14155 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14156 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14159 /*Input mixer control */
14160 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14161 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14162 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14163 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14164 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14165 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14166 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14167 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14171 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14172 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14173 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14175 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14176 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14181 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14182 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14183 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14184 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14188 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14189 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14190 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14192 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14193 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14194 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14195 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14196 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14198 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14199 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14200 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14201 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14202 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14203 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14204 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14205 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14206 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14207 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14211 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14212 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14213 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14214 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14215 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14216 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14217 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14218 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14220 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14224 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14225 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14227 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14228 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14230 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14231 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14232 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14234 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14235 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14236 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14240 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14241 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14242 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14243 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14244 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14245 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14246 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14247 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14248 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14249 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14250 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14254 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14258 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14259 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14260 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14261 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14262 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14263 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14264 HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT),
14268 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14269 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14270 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14271 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14272 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14277 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14278 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14282 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14283 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14284 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14285 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14288 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14289 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14290 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14291 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14292 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14296 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14298 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14299 .name = "Channel Mode",
14300 .info = alc_ch_mode_info,
14301 .get = alc_ch_mode_get,
14302 .put = alc_ch_mode_put,
14307 static struct hda_verb alc662_init_verbs[] = {
14308 /* ADC: mute amp left and right */
14309 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14310 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14311 /* Front mixer: unmute input/output amp left and right (volume = 0) */
14313 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14314 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14315 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14316 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14317 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14319 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14321 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14322 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14323 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14324 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14326 /* Front Pin: output 0 (0x0c) */
14327 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14328 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14330 /* Rear Pin: output 1 (0x0d) */
14331 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14332 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14334 /* CLFE Pin: output 2 (0x0e) */
14335 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14336 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14338 /* Mic (rear) pin: input vref at 80% */
14339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14341 /* Front Mic pin: input vref at 80% */
14342 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14343 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14344 /* Line In pin: input */
14345 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14346 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14347 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14348 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14349 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14350 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14351 /* CD pin widget for input */
14352 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14354 /* FIXME: use matrix-type input source selection */
14355 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14357 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14358 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14360 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14367 /* always trun on EAPD */
14368 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14369 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14374 static struct hda_verb alc662_sue_init_verbs[] = {
14375 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14376 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14380 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14381 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14382 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14386 /* Set Unsolicited Event*/
14387 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14388 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14389 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14394 * generic initialization of ADC, input mixers and output mixers
14396 static struct hda_verb alc662_auto_init_verbs[] = {
14398 * Unmute ADC and set the default input to mic-in
14400 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14401 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14403 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14405 * Note: PASD motherboards uses the Line In 2 as the input for front
14406 * panel mic (mic 2)
14408 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14412 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14413 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14416 * Set up output mixers (0x0c - 0x0f)
14418 /* set vol=0 to output mixers */
14419 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14420 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14421 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14423 /* set up input amps for analog loopback */
14424 /* Amp Indices: DAC = 0, mixer = 1 */
14425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14427 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14428 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14429 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14430 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14433 /* FIXME: use matrix-type input source selection */
14434 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14437 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14441 /* additional verbs for ALC663 */
14442 static struct hda_verb alc663_auto_init_verbs[] = {
14443 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14444 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14448 static struct hda_verb alc663_m51va_init_verbs[] = {
14449 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14450 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14451 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14455 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14456 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14460 static struct hda_verb alc663_g71v_init_verbs[] = {
14461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14462 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
14463 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
14465 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14466 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14467 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14469 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14470 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
14471 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14475 static struct hda_verb alc663_g50v_init_verbs[] = {
14476 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14477 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14478 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14480 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14481 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14485 /* capture mixer elements */
14486 static struct snd_kcontrol_new alc662_capture_mixer[] = {
14487 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14488 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14491 /* The multiple "Capture Source" controls confuse alsamixer
14492 * So call somewhat different..
14494 /* .name = "Capture Source", */
14495 .name = "Input Source",
14497 .info = alc662_mux_enum_info,
14498 .get = alc662_mux_enum_get,
14499 .put = alc662_mux_enum_put,
14504 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
14506 unsigned int present;
14507 unsigned char bits;
14509 present = snd_hda_codec_read(codec, 0x14, 0,
14510 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14511 bits = present ? HDA_AMP_MUTE : 0;
14512 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14513 HDA_AMP_MUTE, bits);
14516 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
14518 unsigned int present;
14519 unsigned char bits;
14521 present = snd_hda_codec_read(codec, 0x1b, 0,
14522 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14523 bits = present ? HDA_AMP_MUTE : 0;
14524 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14525 HDA_AMP_MUTE, bits);
14526 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14527 HDA_AMP_MUTE, bits);
14530 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
14533 if ((res >> 26) == ALC880_HP_EVENT)
14534 alc662_lenovo_101e_all_automute(codec);
14535 if ((res >> 26) == ALC880_FRONT_EVENT)
14536 alc662_lenovo_101e_ispeaker_automute(codec);
14539 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
14541 unsigned int present;
14543 present = snd_hda_codec_read(codec, 0x18, 0,
14544 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14545 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14546 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14547 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14548 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14549 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14550 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14551 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14552 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14555 /* unsolicited event for HP jack sensing */
14556 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
14559 if ((res >> 26) == ALC880_HP_EVENT)
14560 alc262_hippo1_automute( codec );
14562 if ((res >> 26) == ALC880_MIC_EVENT)
14563 alc662_eeepc_mic_automute(codec);
14566 static void alc662_eeepc_inithook(struct hda_codec *codec)
14568 alc262_hippo1_automute( codec );
14569 alc662_eeepc_mic_automute(codec);
14572 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
14575 unsigned int present;
14577 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
14578 present = snd_hda_codec_read(codec, 0x14, 0,
14579 AC_VERB_GET_PIN_SENSE, 0);
14580 present = (present & 0x80000000) != 0;
14582 /* mute internal speaker */
14583 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14584 HDA_AMP_MUTE, HDA_AMP_MUTE);
14586 /* unmute internal speaker if necessary */
14587 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
14588 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14589 HDA_AMP_MUTE, mute);
14593 /* unsolicited event for HP jack sensing */
14594 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
14597 if ((res >> 26) == ALC880_HP_EVENT)
14598 alc662_eeepc_ep20_automute(codec);
14601 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
14603 alc662_eeepc_ep20_automute(codec);
14606 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
14608 unsigned int present;
14609 unsigned char bits;
14611 present = snd_hda_codec_read(codec, 0x21, 0,
14612 AC_VERB_GET_PIN_SENSE, 0)
14613 & AC_PINSENSE_PRESENCE;
14614 bits = present ? HDA_AMP_MUTE : 0;
14615 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14616 HDA_AMP_MUTE, bits);
14619 static void alc663_m51va_mic_automute(struct hda_codec *codec)
14621 unsigned int present;
14623 present = snd_hda_codec_read(codec, 0x18, 0,
14624 AC_VERB_GET_PIN_SENSE, 0)
14625 & AC_PINSENSE_PRESENCE;
14626 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14627 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14628 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14629 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14630 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14631 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14632 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14633 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14636 static void alc663_m51va_unsol_event(struct hda_codec *codec,
14639 switch (res >> 26) {
14640 case ALC880_HP_EVENT:
14641 alc663_m51va_speaker_automute(codec);
14643 case ALC880_MIC_EVENT:
14644 alc663_m51va_mic_automute(codec);
14649 static void alc663_m51va_inithook(struct hda_codec *codec)
14651 alc663_m51va_speaker_automute(codec);
14652 alc663_m51va_mic_automute(codec);
14655 static void alc663_g71v_hp_automute(struct hda_codec *codec)
14657 unsigned int present;
14658 unsigned char bits;
14660 present = snd_hda_codec_read(codec, 0x21, 0,
14661 AC_VERB_GET_PIN_SENSE, 0)
14662 & AC_PINSENSE_PRESENCE;
14663 bits = present ? HDA_AMP_MUTE : 0;
14664 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14665 HDA_AMP_MUTE, bits);
14666 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14667 HDA_AMP_MUTE, bits);
14670 static void alc663_g71v_front_automute(struct hda_codec *codec)
14672 unsigned int present;
14673 unsigned char bits;
14675 present = snd_hda_codec_read(codec, 0x15, 0,
14676 AC_VERB_GET_PIN_SENSE, 0)
14677 & AC_PINSENSE_PRESENCE;
14678 bits = present ? HDA_AMP_MUTE : 0;
14679 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14680 HDA_AMP_MUTE, bits);
14683 static void alc663_g71v_unsol_event(struct hda_codec *codec,
14686 switch (res >> 26) {
14687 case ALC880_HP_EVENT:
14688 alc663_g71v_hp_automute(codec);
14690 case ALC880_FRONT_EVENT:
14691 alc663_g71v_front_automute(codec);
14693 case ALC880_MIC_EVENT:
14694 alc662_eeepc_mic_automute(codec);
14699 static void alc663_g71v_inithook(struct hda_codec *codec)
14701 alc663_g71v_front_automute(codec);
14702 alc663_g71v_hp_automute(codec);
14703 alc662_eeepc_mic_automute(codec);
14706 static void alc663_g50v_unsol_event(struct hda_codec *codec,
14709 switch (res >> 26) {
14710 case ALC880_HP_EVENT:
14711 alc663_m51va_speaker_automute(codec);
14713 case ALC880_MIC_EVENT:
14714 alc662_eeepc_mic_automute(codec);
14719 static void alc663_g50v_inithook(struct hda_codec *codec)
14721 alc663_m51va_speaker_automute(codec);
14722 alc662_eeepc_mic_automute(codec);
14725 #ifdef CONFIG_SND_HDA_POWER_SAVE
14726 #define alc662_loopbacks alc880_loopbacks
14730 /* pcm configuration: identiacal with ALC880 */
14731 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
14732 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
14733 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
14734 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
14737 * configuration and preset
14739 static const char *alc662_models[ALC662_MODEL_LAST] = {
14740 [ALC662_3ST_2ch_DIG] = "3stack-dig",
14741 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
14742 [ALC662_3ST_6ch] = "3stack-6ch",
14743 [ALC662_5ST_DIG] = "6stack-dig",
14744 [ALC662_LENOVO_101E] = "lenovo-101e",
14745 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
14746 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
14747 [ALC663_ASUS_M51VA] = "m51va",
14748 [ALC663_ASUS_G71V] = "g71v",
14749 [ALC663_ASUS_H13] = "h13",
14750 [ALC663_ASUS_G50V] = "g50v",
14751 [ALC662_AUTO] = "auto",
14754 static struct snd_pci_quirk alc662_cfg_tbl[] = {
14755 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V),
14756 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
14757 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
14758 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
14759 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
14760 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
14761 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
14762 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
14763 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
14764 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
14768 static struct alc_config_preset alc662_presets[] = {
14769 [ALC662_3ST_2ch_DIG] = {
14770 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
14771 .init_verbs = { alc662_init_verbs },
14772 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14773 .dac_nids = alc662_dac_nids,
14774 .dig_out_nid = ALC662_DIGOUT_NID,
14775 .dig_in_nid = ALC662_DIGIN_NID,
14776 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14777 .channel_mode = alc662_3ST_2ch_modes,
14778 .input_mux = &alc662_capture_source,
14780 [ALC662_3ST_6ch_DIG] = {
14781 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
14782 alc662_capture_mixer },
14783 .init_verbs = { alc662_init_verbs },
14784 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14785 .dac_nids = alc662_dac_nids,
14786 .dig_out_nid = ALC662_DIGOUT_NID,
14787 .dig_in_nid = ALC662_DIGIN_NID,
14788 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14789 .channel_mode = alc662_3ST_6ch_modes,
14791 .input_mux = &alc662_capture_source,
14793 [ALC662_3ST_6ch] = {
14794 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
14795 alc662_capture_mixer },
14796 .init_verbs = { alc662_init_verbs },
14797 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14798 .dac_nids = alc662_dac_nids,
14799 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14800 .channel_mode = alc662_3ST_6ch_modes,
14802 .input_mux = &alc662_capture_source,
14804 [ALC662_5ST_DIG] = {
14805 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
14806 alc662_capture_mixer },
14807 .init_verbs = { alc662_init_verbs },
14808 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14809 .dac_nids = alc662_dac_nids,
14810 .dig_out_nid = ALC662_DIGOUT_NID,
14811 .dig_in_nid = ALC662_DIGIN_NID,
14812 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
14813 .channel_mode = alc662_5stack_modes,
14814 .input_mux = &alc662_capture_source,
14816 [ALC662_LENOVO_101E] = {
14817 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
14818 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
14819 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14820 .dac_nids = alc662_dac_nids,
14821 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14822 .channel_mode = alc662_3ST_2ch_modes,
14823 .input_mux = &alc662_lenovo_101e_capture_source,
14824 .unsol_event = alc662_lenovo_101e_unsol_event,
14825 .init_hook = alc662_lenovo_101e_all_automute,
14827 [ALC662_ASUS_EEEPC_P701] = {
14828 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
14829 .init_verbs = { alc662_init_verbs,
14830 alc662_eeepc_sue_init_verbs },
14831 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14832 .dac_nids = alc662_dac_nids,
14833 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14834 .channel_mode = alc662_3ST_2ch_modes,
14835 .input_mux = &alc662_eeepc_capture_source,
14836 .unsol_event = alc662_eeepc_unsol_event,
14837 .init_hook = alc662_eeepc_inithook,
14839 [ALC662_ASUS_EEEPC_EP20] = {
14840 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
14841 alc662_chmode_mixer },
14842 .init_verbs = { alc662_init_verbs,
14843 alc662_eeepc_ep20_sue_init_verbs },
14844 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14845 .dac_nids = alc662_dac_nids,
14846 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14847 .channel_mode = alc662_3ST_6ch_modes,
14848 .input_mux = &alc662_lenovo_101e_capture_source,
14849 .unsol_event = alc662_eeepc_ep20_unsol_event,
14850 .init_hook = alc662_eeepc_ep20_inithook,
14852 [ALC663_ASUS_M51VA] = {
14853 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14854 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14855 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14856 .dac_nids = alc662_dac_nids,
14857 .dig_out_nid = ALC662_DIGOUT_NID,
14858 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14859 .channel_mode = alc662_3ST_2ch_modes,
14860 .input_mux = &alc663_m51va_capture_source,
14861 .unsol_event = alc663_m51va_unsol_event,
14862 .init_hook = alc663_m51va_inithook,
14864 [ALC663_ASUS_G71V] = {
14865 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
14866 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
14867 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14868 .dac_nids = alc662_dac_nids,
14869 .dig_out_nid = ALC662_DIGOUT_NID,
14870 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14871 .channel_mode = alc662_3ST_2ch_modes,
14872 .input_mux = &alc662_eeepc_capture_source,
14873 .unsol_event = alc663_g71v_unsol_event,
14874 .init_hook = alc663_g71v_inithook,
14876 [ALC663_ASUS_H13] = {
14877 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14878 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14879 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14880 .dac_nids = alc662_dac_nids,
14881 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14882 .channel_mode = alc662_3ST_2ch_modes,
14883 .input_mux = &alc663_m51va_capture_source,
14884 .unsol_event = alc663_m51va_unsol_event,
14885 .init_hook = alc663_m51va_inithook,
14887 [ALC663_ASUS_G50V] = {
14888 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
14889 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
14890 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14891 .dac_nids = alc662_dac_nids,
14892 .dig_out_nid = ALC662_DIGOUT_NID,
14893 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14894 .channel_mode = alc662_3ST_6ch_modes,
14895 .input_mux = &alc663_capture_source,
14896 .unsol_event = alc663_g50v_unsol_event,
14897 .init_hook = alc663_g50v_inithook,
14903 * BIOS auto configuration
14906 /* add playback controls from the parsed DAC table */
14907 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
14908 const struct auto_pin_cfg *cfg)
14911 static const char *chname[4] = {
14912 "Front", "Surround", NULL /*CLFE*/, "Side"
14917 for (i = 0; i < cfg->line_outs; i++) {
14918 if (!spec->multiout.dac_nids[i])
14920 nid = alc880_idx_to_dac(i);
14923 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14924 "Center Playback Volume",
14925 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
14929 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14930 "LFE Playback Volume",
14931 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
14935 err = add_control(spec, ALC_CTL_BIND_MUTE,
14936 "Center Playback Switch",
14937 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
14941 err = add_control(spec, ALC_CTL_BIND_MUTE,
14942 "LFE Playback Switch",
14943 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
14948 sprintf(name, "%s Playback Volume", chname[i]);
14949 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14950 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
14954 sprintf(name, "%s Playback Switch", chname[i]);
14955 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14956 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
14965 /* add playback controls for speaker and HP outputs */
14966 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
14977 /* ALC663 has a mono output pin on 0x17 */
14978 sprintf(name, "%s Playback Switch", pfx);
14979 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14980 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
14984 if (alc880_is_fixed_pin(pin)) {
14985 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14986 /* printk("DAC nid=%x\n",nid); */
14987 /* specify the DAC as the extra output */
14988 if (!spec->multiout.hp_nid)
14989 spec->multiout.hp_nid = nid;
14991 spec->multiout.extra_out_nid[0] = nid;
14992 /* control HP volume/switch on the output mixer amp */
14993 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14994 sprintf(name, "%s Playback Volume", pfx);
14995 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14996 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
14999 sprintf(name, "%s Playback Switch", pfx);
15000 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15001 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
15004 } else if (alc880_is_multi_pin(pin)) {
15005 /* set manual connection */
15006 /* we have only a switch on HP-out PIN */
15007 sprintf(name, "%s Playback Switch", pfx);
15008 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15009 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15016 /* create playback/capture controls for input pins */
15017 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
15018 const struct auto_pin_cfg *cfg)
15020 struct hda_input_mux *imux = &spec->private_imux;
15023 for (i = 0; i < AUTO_PIN_LAST; i++) {
15024 if (alc880_is_input_pin(cfg->input_pins[i])) {
15025 idx = alc880_input_pin_idx(cfg->input_pins[i]);
15026 err = new_analog_input(spec, cfg->input_pins[i],
15027 auto_pin_cfg_labels[i],
15031 imux->items[imux->num_items].label =
15032 auto_pin_cfg_labels[i];
15033 imux->items[imux->num_items].index =
15034 alc880_input_pin_idx(cfg->input_pins[i]);
15041 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
15042 hda_nid_t nid, int pin_type,
15045 alc_set_pin_output(codec, nid, pin_type);
15046 /* need the manual connection? */
15047 if (alc880_is_multi_pin(nid)) {
15048 struct alc_spec *spec = codec->spec;
15049 int idx = alc880_multi_pin_idx(nid);
15050 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
15051 AC_VERB_SET_CONNECT_SEL,
15052 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
15056 static void alc662_auto_init_multi_out(struct hda_codec *codec)
15058 struct alc_spec *spec = codec->spec;
15061 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
15062 for (i = 0; i <= HDA_SIDE; i++) {
15063 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15064 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15066 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
15071 static void alc662_auto_init_hp_out(struct hda_codec *codec)
15073 struct alc_spec *spec = codec->spec;
15076 pin = spec->autocfg.hp_pins[0];
15077 if (pin) /* connect to front */
15079 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15080 pin = spec->autocfg.speaker_pins[0];
15082 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15085 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
15086 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
15088 static void alc662_auto_init_analog_input(struct hda_codec *codec)
15090 struct alc_spec *spec = codec->spec;
15093 for (i = 0; i < AUTO_PIN_LAST; i++) {
15094 hda_nid_t nid = spec->autocfg.input_pins[i];
15095 if (alc662_is_input_pin(nid)) {
15096 snd_hda_codec_write(codec, nid, 0,
15097 AC_VERB_SET_PIN_WIDGET_CONTROL,
15098 (i <= AUTO_PIN_FRONT_MIC ?
15099 PIN_VREF80 : PIN_IN));
15100 if (nid != ALC662_PIN_CD_NID)
15101 snd_hda_codec_write(codec, nid, 0,
15102 AC_VERB_SET_AMP_GAIN_MUTE,
15108 #define alc662_auto_init_input_src alc882_auto_init_input_src
15110 static int alc662_parse_auto_config(struct hda_codec *codec)
15112 struct alc_spec *spec = codec->spec;
15114 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
15116 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15120 if (!spec->autocfg.line_outs)
15121 return 0; /* can't find valid BIOS pin config */
15123 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15126 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
15129 err = alc662_auto_create_extra_out(spec,
15130 spec->autocfg.speaker_pins[0],
15134 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
15138 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
15142 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15144 if (spec->autocfg.dig_out_pin)
15145 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
15147 if (spec->kctl_alloc)
15148 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
15150 spec->num_mux_defs = 1;
15151 spec->input_mux = &spec->private_imux;
15153 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
15154 if (codec->vendor_id == 0x10ec0663)
15155 spec->init_verbs[spec->num_init_verbs++] =
15156 alc663_auto_init_verbs;
15158 err = alc_auto_add_mic_boost(codec);
15162 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
15163 spec->num_mixers++;
15167 /* additional initialization for auto-configuration model */
15168 static void alc662_auto_init(struct hda_codec *codec)
15170 struct alc_spec *spec = codec->spec;
15171 alc662_auto_init_multi_out(codec);
15172 alc662_auto_init_hp_out(codec);
15173 alc662_auto_init_analog_input(codec);
15174 alc662_auto_init_input_src(codec);
15175 if (spec->unsol_event)
15176 alc_sku_automute(codec);
15179 static int patch_alc662(struct hda_codec *codec)
15181 struct alc_spec *spec;
15182 int err, board_config;
15184 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15188 codec->spec = spec;
15190 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15192 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
15195 if (board_config < 0) {
15196 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
15197 "trying auto-probe from BIOS...\n");
15198 board_config = ALC662_AUTO;
15201 if (board_config == ALC662_AUTO) {
15202 /* automatic parse from the BIOS config */
15203 err = alc662_parse_auto_config(codec);
15209 "hda_codec: Cannot set up configuration "
15210 "from BIOS. Using base mode...\n");
15211 board_config = ALC662_3ST_2ch_DIG;
15215 if (board_config != ALC662_AUTO)
15216 setup_preset(spec, &alc662_presets[board_config]);
15218 if (codec->vendor_id == 0x10ec0663) {
15219 spec->stream_name_analog = "ALC663 Analog";
15220 spec->stream_name_digital = "ALC663 Digital";
15222 spec->stream_name_analog = "ALC662 Analog";
15223 spec->stream_name_digital = "ALC662 Digital";
15226 spec->stream_analog_playback = &alc662_pcm_analog_playback;
15227 spec->stream_analog_capture = &alc662_pcm_analog_capture;
15229 spec->stream_digital_playback = &alc662_pcm_digital_playback;
15230 spec->stream_digital_capture = &alc662_pcm_digital_capture;
15232 spec->adc_nids = alc662_adc_nids;
15233 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
15234 spec->capsrc_nids = alc662_capsrc_nids;
15236 spec->vmaster_nid = 0x02;
15238 codec->patch_ops = alc_patch_ops;
15239 if (board_config == ALC662_AUTO)
15240 spec->init_hook = alc662_auto_init;
15241 #ifdef CONFIG_SND_HDA_POWER_SAVE
15242 if (!spec->loopback.amplist)
15243 spec->loopback.amplist = alc662_loopbacks;
15252 struct hda_codec_preset snd_hda_preset_realtek[] = {
15253 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
15254 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
15255 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
15256 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
15257 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
15258 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
15259 .patch = patch_alc861 },
15260 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
15261 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
15262 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
15263 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
15264 .patch = patch_alc883 },
15265 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
15266 .patch = patch_alc662 },
15267 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
15268 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
15269 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
15270 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
15271 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
15272 .patch = patch_alc882 }, /* should be patch_alc883() in future */
15273 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
15274 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
15275 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
15276 {} /* terminator */